From 209357dc62e733be367f6f26c4d916309fae064c Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Tue, 23 Apr 2024 15:34:40 -0700 Subject: [PATCH] feat(openchallenges): filter challenges by input data types (EDAM Concept IDs) (#2647) --- .../.openapi-generator/FILES | 1 - .../challenge-service/requests.http | 4 +- .../service/api/ChallengeApiDelegate.java | 2 +- .../service/model/dto/ChallengeDto.java | 10 +- .../model/dto/ChallengeSearchQueryDto.java | 37 +++++++ .../service/model/dto/EdamDataDto.java | 104 ------------------ .../service/model/entity/ChallengeEntity.java | 4 +- .../entity/ChallengeInputDataTypeEntity.java | 2 +- .../model/entity/EdamConceptEntity.java | 1 + .../service/model/entity/EdamDataEntity.java | 37 ------- .../service/model/mapper/ChallengeMapper.java | 10 +- .../service/model/mapper/EdamDataMapper.java | 26 ----- .../CustomChallengeRepositoryImpl.java | 14 +++ .../src/main/resources/openapi.yaml | 53 ++++----- .../src/lib/.openapi-generator/FILES | 1 - .../src/lib/model/challenge.ts | 4 +- .../src/lib/model/challengeSearchQuery.ts | 4 + .../src/lib/model/edamData.ts | 21 ---- .../src/lib/model/models.ts | 1 - .../build/challenge.openapi.yaml | 44 +++----- .../api-description/build/openapi.yaml | 44 +++----- .../src/components/schemas/Challenge.yaml | 2 +- .../schemas/ChallengeSearchQuery.yaml | 5 + .../src/components/schemas/EdamData.yaml | 16 --- 24 files changed, 134 insertions(+), 313 deletions(-) delete mode 100644 apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamDataDto.java delete mode 100644 apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/EdamDataEntity.java delete mode 100644 apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/mapper/EdamDataMapper.java delete mode 100644 libs/openchallenges/api-client-angular/src/lib/model/edamData.ts delete mode 100644 libs/openchallenges/api-description/src/components/schemas/EdamData.yaml diff --git a/apps/openchallenges/challenge-service/.openapi-generator/FILES b/apps/openchallenges/challenge-service/.openapi-generator/FILES index 5229bdb9de..d6cff016a6 100644 --- a/apps/openchallenges/challenge-service/.openapi-generator/FILES +++ b/apps/openchallenges/challenge-service/.openapi-generator/FILES @@ -43,7 +43,6 @@ src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/Eda src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamConceptSearchQueryDto.java src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamConceptSortDto.java src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamConceptsPageDto.java -src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamDataDto.java src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamOperationDto.java src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamSectionDto.java src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/PageMetadataDto.java diff --git a/apps/openchallenges/challenge-service/requests.http b/apps/openchallenges/challenge-service/requests.http index 8f2e967d0f..f86f70eb94 100644 --- a/apps/openchallenges/challenge-service/requests.http +++ b/apps/openchallenges/challenge-service/requests.http @@ -44,9 +44,9 @@ GET {{basePath}}/challenges?searchTerms=mortality%20dream GET {{basePath}}/challenges?minStartDate=2017-01-01&maxStartDate=2017-12-31 -### List the challenges that include the input data type 'genomic'. +### Get the challenges whose input data types include the EDAM concept ID 2 or 18 -GET {{basePath}}/challenges?inputDataTypes=genomic +GET {{basePath}}/challenges?inputDataTypes=2,18 ### List the challenges by category: featured diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/api/ChallengeApiDelegate.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/api/ChallengeApiDelegate.java index 5087d30d47..e6c674a24f 100644 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/api/ChallengeApiDelegate.java +++ b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/api/ChallengeApiDelegate.java @@ -36,7 +36,7 @@ default ResponseEntity getChallenge(Long challengeId) { for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { String exampleString = - "{ \"avatarUrl\" : \"https://openchallenges.io\", \"endDate\" : \"2017-07-21T00:00:00.000+00:00\", \"description\" : \"This is an example description of the challenge.\", \"platform\" : { \"name\" : \"name\", \"id\" : 1, \"slug\" : \"example-challenge-platform\" }, \"starredCount\" : 100, \"createdAt\" : \"2022-07-04T22:19:11Z\", \"incentives\" : [ \"publication\", \"publication\" ], \"submissionTypes\" : [ \"container_image\", \"container_image\" ], \"websiteUrl\" : \"https://openchallenges.io\", \"name\" : \"name\", \"id\" : 1, \"categories\" : [ \"featured\", \"featured\" ], \"headline\" : \"Example challenge headline\", \"operation\" : { \"classId\" : \"http://edamontology.org/operation_0230\", \"preferredLabel\" : \"Sequence generation\" }, \"slug\" : \"awesome-challenge\", \"startDate\" : \"2017-07-21T00:00:00.000+00:00\", \"doi\" : \"https://doi.org/123/abc\", \"status\" : \"active\", \"inputDataTypes\" : [ { \"classId\" : \"http://edamontology.org/data_0850\", \"preferredLabel\" : \"Sequence set\" }, { \"classId\" : \"http://edamontology.org/data_0850\", \"preferredLabel\" : \"Sequence set\" } ], \"updatedAt\" : \"2022-07-04T22:19:11Z\" }"; + "{ \"avatarUrl\" : \"https://openchallenges.io\", \"endDate\" : \"2017-07-21T00:00:00.000+00:00\", \"description\" : \"This is an example description of the challenge.\", \"platform\" : { \"name\" : \"name\", \"id\" : 1, \"slug\" : \"example-challenge-platform\" }, \"starredCount\" : 100, \"createdAt\" : \"2022-07-04T22:19:11Z\", \"incentives\" : [ \"publication\", \"publication\" ], \"submissionTypes\" : [ \"container_image\", \"container_image\" ], \"websiteUrl\" : \"https://openchallenges.io\", \"name\" : \"name\", \"id\" : 1, \"categories\" : [ \"featured\", \"featured\" ], \"headline\" : \"Example challenge headline\", \"operation\" : { \"classId\" : \"http://edamontology.org/operation_0230\", \"preferredLabel\" : \"Sequence generation\" }, \"slug\" : \"awesome-challenge\", \"startDate\" : \"2017-07-21T00:00:00.000+00:00\", \"doi\" : \"https://doi.org/123/abc\", \"status\" : \"active\", \"inputDataTypes\" : [ { \"classId\" : \"http://edamontology.org/data_0850\", \"preferredLabel\" : \"Sequence set\", \"id\" : 1 }, { \"classId\" : \"http://edamontology.org/data_0850\", \"preferredLabel\" : \"Sequence set\", \"id\" : 1 } ], \"updatedAt\" : \"2022-07-04T22:19:11Z\" }"; ApiUtil.setExampleResponse(request, "application/json", exampleString); break; } diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/ChallengeDto.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/ChallengeDto.java index 7115926e34..e8ff9c2a4b 100644 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/ChallengeDto.java +++ b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/ChallengeDto.java @@ -61,7 +61,7 @@ public class ChallengeDto { @JsonProperty("inputDataTypes") @Valid - private List inputDataTypes = null; + private List inputDataTypes = null; @JsonProperty("categories") @Valid @@ -380,12 +380,12 @@ public void setSubmissionTypes(List submissionTypes) this.submissionTypes = submissionTypes; } - public ChallengeDto inputDataTypes(List inputDataTypes) { + public ChallengeDto inputDataTypes(List inputDataTypes) { this.inputDataTypes = inputDataTypes; return this; } - public ChallengeDto addInputDataTypesItem(EdamDataDto inputDataTypesItem) { + public ChallengeDto addInputDataTypesItem(EdamConceptDto inputDataTypesItem) { if (this.inputDataTypes == null) { this.inputDataTypes = new ArrayList<>(); } @@ -400,11 +400,11 @@ public ChallengeDto addInputDataTypesItem(EdamDataDto inputDataTypesItem) { */ @Valid @Schema(name = "inputDataTypes", required = false) - public List getInputDataTypes() { + public List getInputDataTypes() { return inputDataTypes; } - public void setInputDataTypes(List inputDataTypes) { + public void setInputDataTypes(List inputDataTypes) { this.inputDataTypes = inputDataTypes; } diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/ChallengeSearchQueryDto.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/ChallengeSearchQueryDto.java index 1e3e4c0f34..2ac7d2aece 100644 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/ChallengeSearchQueryDto.java +++ b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/ChallengeSearchQueryDto.java @@ -63,6 +63,10 @@ public class ChallengeSearchQueryDto { @Valid private List submissionTypes = null; + @JsonProperty("inputDataTypes") + @Valid + private List inputDataTypes = null; + @JsonProperty("categories") @Valid private List categories = null; @@ -379,6 +383,36 @@ public void setSubmissionTypes(List submissionTypes) this.submissionTypes = submissionTypes; } + public ChallengeSearchQueryDto inputDataTypes(List inputDataTypes) { + this.inputDataTypes = inputDataTypes; + return this; + } + + public ChallengeSearchQueryDto addInputDataTypesItem(Long inputDataTypesItem) { + if (this.inputDataTypes == null) { + this.inputDataTypes = new ArrayList<>(); + } + this.inputDataTypes.add(inputDataTypesItem); + return this; + } + + /** + * An array of EDAM concept ID used to filter the results. + * + * @return inputDataTypes + */ + @Schema( + name = "inputDataTypes", + description = "An array of EDAM concept ID used to filter the results.", + required = false) + public List getInputDataTypes() { + return inputDataTypes; + } + + public void setInputDataTypes(List inputDataTypes) { + this.inputDataTypes = inputDataTypes; + } + public ChallengeSearchQueryDto categories(List categories) { this.categories = categories; return this; @@ -454,6 +488,7 @@ public boolean equals(Object o) { && Objects.equals(this.organizations, challengeSearchQuery.organizations) && Objects.equals(this.status, challengeSearchQuery.status) && Objects.equals(this.submissionTypes, challengeSearchQuery.submissionTypes) + && Objects.equals(this.inputDataTypes, challengeSearchQuery.inputDataTypes) && Objects.equals(this.categories, challengeSearchQuery.categories) && Objects.equals(this.searchTerms, challengeSearchQuery.searchTerms); } @@ -473,6 +508,7 @@ public int hashCode() { organizations, status, submissionTypes, + inputDataTypes, categories, searchTerms); } @@ -493,6 +529,7 @@ public String toString() { sb.append(" organizations: ").append(toIndentedString(organizations)).append("\n"); sb.append(" status: ").append(toIndentedString(status)).append("\n"); sb.append(" submissionTypes: ").append(toIndentedString(submissionTypes)).append("\n"); + sb.append(" inputDataTypes: ").append(toIndentedString(inputDataTypes)).append("\n"); sb.append(" categories: ").append(toIndentedString(categories)).append("\n"); sb.append(" searchTerms: ").append(toIndentedString(searchTerms)).append("\n"); sb.append("}"); diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamDataDto.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamDataDto.java deleted file mode 100644 index cef3fa99d3..0000000000 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamDataDto.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.sagebionetworks.openchallenges.challenge.service.model.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonTypeName; -import io.swagger.v3.oas.annotations.media.Schema; -import java.util.*; -import java.util.Objects; -import javax.annotation.Generated; -import javax.validation.constraints.*; - -/** The EDAM Data concept. */ -@Schema(name = "EdamData", description = "The EDAM Data concept.") -@JsonTypeName("EdamData") -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -// TODO Add x-java-class-annotations -public class EdamDataDto { - - @JsonProperty("classId") - private String classId; - - @JsonProperty("preferredLabel") - private String preferredLabel; - - public EdamDataDto classId(String classId) { - this.classId = classId; - return this; - } - - /** - * Get classId - * - * @return classId - */ - @NotNull - @Pattern(regexp = "^http://edamontology\\.org/data_\\d+$") - @Size(max = 60) - @Schema(name = "classId", example = "http://edamontology.org/data_0850", required = true) - public String getClassId() { - return classId; - } - - public void setClassId(String classId) { - this.classId = classId; - } - - public EdamDataDto preferredLabel(String preferredLabel) { - this.preferredLabel = preferredLabel; - return this; - } - - /** - * Get preferredLabel - * - * @return preferredLabel - */ - @NotNull - @Size(max = 80) - @Schema(name = "preferredLabel", example = "Sequence set", required = true) - public String getPreferredLabel() { - return preferredLabel; - } - - public void setPreferredLabel(String preferredLabel) { - this.preferredLabel = preferredLabel; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - EdamDataDto edamData = (EdamDataDto) o; - return Objects.equals(this.classId, edamData.classId) - && Objects.equals(this.preferredLabel, edamData.preferredLabel); - } - - @Override - public int hashCode() { - return Objects.hash(classId, preferredLabel); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class EdamDataDto {\n"); - sb.append(" classId: ").append(toIndentedString(classId)).append("\n"); - sb.append(" preferredLabel: ").append(toIndentedString(preferredLabel)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/ChallengeEntity.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/ChallengeEntity.java index e8b8ae50b5..32e9296e3b 100644 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/ChallengeEntity.java +++ b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/ChallengeEntity.java @@ -101,9 +101,9 @@ public class ChallengeEntity { inverseJoinColumns = @JoinColumn(name = "edam_concept_id")) @IndexedEmbedded( name = "input_data_types", - includePaths = {"class_id", "preferred_label"}) + includePaths = {"id", "class_id", "preferred_label"}) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) - private List inputDataTypes; + private List inputDataTypes; @OneToMany(mappedBy = "challenge", fetch = FetchType.LAZY) @IndexedEmbedded(includePaths = {"name"}) diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/ChallengeInputDataTypeEntity.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/ChallengeInputDataTypeEntity.java index 037ea05ab7..ae6a94b080 100644 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/ChallengeInputDataTypeEntity.java +++ b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/ChallengeInputDataTypeEntity.java @@ -34,7 +34,7 @@ public class ChallengeInputDataTypeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "edam_concept_id", nullable = false) - private EdamDataEntity edamData; + private EdamConceptEntity edamConcept; @Column(name = "created_at") private OffsetDateTime createdAt; diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/EdamConceptEntity.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/EdamConceptEntity.java index 00a0e189f9..2b8b32c118 100644 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/EdamConceptEntity.java +++ b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/EdamConceptEntity.java @@ -30,6 +30,7 @@ public class EdamConceptEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false, updatable = false) + @GenericField(name = "id") private Long id; @Column(name = "class_id", nullable = false) diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/EdamDataEntity.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/EdamDataEntity.java deleted file mode 100644 index 2fe9429063..0000000000 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/entity/EdamDataEntity.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.sagebionetworks.openchallenges.challenge.service.model.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; -import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; - -@Entity -@Table(name = "edam_concept") -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Indexed(index = "openchallenges-edam-data") -public class EdamDataEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(nullable = false, updatable = false) - private Long id; - - @Column(name = "class_id", nullable = false) - @FullTextField(name = "class_id") - private String classId; - - @Column(name = "preferred_label", nullable = false) - @FullTextField(name = "preferred_label") - private String preferredLabel; -} diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/mapper/ChallengeMapper.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/mapper/ChallengeMapper.java index 2a06e6585f..364708362b 100644 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/mapper/ChallengeMapper.java +++ b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/mapper/ChallengeMapper.java @@ -17,7 +17,7 @@ public class ChallengeMapper extends BaseMapper { private SimpleChallengePlatformMapper platformMapper = new SimpleChallengePlatformMapper(); private EdamOperationMapper edamOperationMapper = new EdamOperationMapper(); - private EdamDataMapper edamDataMapper = new EdamDataMapper(); + private EdamConceptMapper edamConceptMapper = new EdamConceptMapper(); @Override public ChallengeEntity convertToEntity(ChallengeDto dto, Object... args) { @@ -31,10 +31,10 @@ public ChallengeEntity convertToEntity(ChallengeDto dto, Object... args) { @Override public ChallengeDto convertToDto(ChallengeEntity entity, Object... args) { ChallengeDto dto = new ChallengeDto(); - LOG.info("challenge dto initial: {}", dto); + LOG.trace("challenge dto initial: {}", dto); if (entity != null) { BeanUtils.copyProperties(entity, dto, "stars", "inputDataTypes", "platform", "operation"); - LOG.info("challenge dto before set: {}", dto); + LOG.trace("challenge dto before set: {}", dto); dto.setStatus(ChallengeStatusDto.fromValue(entity.getStatus())); dto.setPlatform(platformMapper.convertToDto(entity.getPlatform())); if (entity.getOperation() != null) { @@ -52,9 +52,9 @@ public ChallengeDto convertToDto(ChallengeEntity entity, Object... args) { entity.getCategories().stream() .map(o -> ChallengeCategoryDto.fromValue(o.getName())) .toList()); - dto.inputDataTypes(edamDataMapper.convertToDtoList(entity.getInputDataTypes())); + dto.inputDataTypes(edamConceptMapper.convertToDtoList(entity.getInputDataTypes())); dto.starredCount(entity.getStars().size()); - LOG.info("challenge dto: {}", dto); + LOG.trace("challenge dto: {}", dto); } return dto; } diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/mapper/EdamDataMapper.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/mapper/EdamDataMapper.java deleted file mode 100644 index fbde7395f7..0000000000 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/mapper/EdamDataMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.sagebionetworks.openchallenges.challenge.service.model.mapper; - -import org.sagebionetworks.openchallenges.challenge.service.model.dto.EdamDataDto; -import org.sagebionetworks.openchallenges.challenge.service.model.entity.EdamDataEntity; -import org.sagebionetworks.util.model.mapper.BaseMapper; -import org.springframework.beans.BeanUtils; - -public class EdamDataMapper extends BaseMapper { - @Override - public EdamDataEntity convertToEntity(EdamDataDto dto, Object... args) { - EdamDataEntity entity = new EdamDataEntity(); - if (dto != null) { - BeanUtils.copyProperties(dto, entity); - } - return entity; - } - - @Override - public EdamDataDto convertToDto(EdamDataEntity entity, Object... args) { - EdamDataDto dto = new EdamDataDto(); - if (entity != null) { - BeanUtils.copyProperties(entity, dto); - } - return dto; - } -} diff --git a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/repository/CustomChallengeRepositoryImpl.java b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/repository/CustomChallengeRepositoryImpl.java index 770c0c3f54..c56775234d 100644 --- a/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/repository/CustomChallengeRepositoryImpl.java +++ b/apps/openchallenges/challenge-service/src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/repository/CustomChallengeRepositoryImpl.java @@ -64,6 +64,9 @@ private SearchResult getSearchResult( if (query.getSubmissionTypes() != null && !query.getSubmissionTypes().isEmpty()) { predicates.add(getChallengeSubmissionTypesPredicate(pf, query)); } + if (query.getInputDataTypes() != null && !query.getInputDataTypes().isEmpty()) { + predicates.add(getInputDataTypesPredicate(pf, query)); + } if (query.getIncentives() != null && !query.getIncentives().isEmpty()) { predicates.add(getChallengeIncentivesPredicate(pf, query)); } @@ -167,6 +170,17 @@ private SearchPredicate getChallengeSubmissionTypesPredicate( .toPredicate(); } + private SearchPredicate getInputDataTypesPredicate( + SearchPredicateFactory pf, ChallengeSearchQueryDto query) { + return pf.bool( + b -> { + for (Long edamConceptId : query.getInputDataTypes()) { + b.should(pf.match().field("input_data_types.id").matching(edamConceptId)); + } + }) + .toPredicate(); + } + /** * Matches the challenges whose at least one of their contributors is in the list of * contributors/organizations specified. diff --git a/apps/openchallenges/challenge-service/src/main/resources/openapi.yaml b/apps/openchallenges/challenge-service/src/main/resources/openapi.yaml index b6551f7eb3..c35003d0cb 100644 --- a/apps/openchallenges/challenge-service/src/main/resources/openapi.yaml +++ b/apps/openchallenges/challenge-service/src/main/resources/openapi.yaml @@ -404,6 +404,11 @@ components: - other example: container_image type: string + EdamConceptId: + description: The unique identifier of the EDAM concept. + example: 1 + format: int64 + type: integer ChallengeCategory: description: The category of the challenge. enum: @@ -479,6 +484,11 @@ components: items: $ref: '#/components/schemas/ChallengeSubmissionType' type: array + inputDataTypes: + description: An array of EDAM concept ID used to filter the results. + items: + $ref: '#/components/schemas/EdamConceptId' + type: array categories: description: The array of challenge categories used to filter the results. items: @@ -612,17 +622,22 @@ components: maxLength: 500 nullable: true type: string - EdamData: - description: The EDAM Data concept. + EdamConcept: + description: The EDAM concept. example: classId: http://edamontology.org/data_0850 preferredLabel: Sequence set + id: 1 nullable: true properties: + id: + description: The unique identifier of the EDAM concept. + example: 1 + format: int64 + type: integer classId: example: http://edamontology.org/data_0850 maxLength: 60 - pattern: ^http:\/\/edamontology\.org\/data_\d+$ type: string preferredLabel: example: Sequence set @@ -630,6 +645,7 @@ components: type: string required: - classId + - id - preferredLabel type: object ChallengeStartDate: @@ -709,8 +725,10 @@ components: inputDataTypes: - classId: http://edamontology.org/data_0850 preferredLabel: Sequence set + id: 1 - classId: http://edamontology.org/data_0850 preferredLabel: Sequence set + id: 1 updatedAt: 2022-07-04T22:19:11Z properties: id: @@ -778,7 +796,7 @@ components: type: array inputDataTypes: items: - $ref: '#/components/schemas/EdamData' + $ref: '#/components/schemas/EdamConcept' type: array categories: items: @@ -1078,33 +1096,6 @@ components: $ref: '#/components/schemas/EdamSection' type: array type: object - EdamConceptId: - description: The unique identifier of the EDAM concept. - example: 1 - format: int64 - type: integer - EdamConcept: - description: The EDAM concept. - nullable: true - properties: - id: - description: The unique identifier of the EDAM concept. - example: 1 - format: int64 - type: integer - classId: - example: http://edamontology.org/data_0850 - maxLength: 60 - type: string - preferredLabel: - example: Sequence set - maxLength: 80 - type: string - required: - - classId - - id - - preferredLabel - type: object EdamConceptsPage: allOf: - $ref: '#/components/schemas/PageMetadata' diff --git a/libs/openchallenges/api-client-angular/src/lib/.openapi-generator/FILES b/libs/openchallenges/api-client-angular/src/lib/.openapi-generator/FILES index 71e37b39ba..8cc4e855cb 100644 --- a/libs/openchallenges/api-client-angular/src/lib/.openapi-generator/FILES +++ b/libs/openchallenges/api-client-angular/src/lib/.openapi-generator/FILES @@ -42,7 +42,6 @@ model/edamConceptSearchQuery.ts model/edamConceptSort.ts model/edamConceptsPage.ts model/edamConceptsPageAllOf.ts -model/edamData.ts model/edamOperation.ts model/edamSection.ts model/image.ts diff --git a/libs/openchallenges/api-client-angular/src/lib/model/challenge.ts b/libs/openchallenges/api-client-angular/src/lib/model/challenge.ts index 8eb9f14d4b..cb3703a0ba 100644 --- a/libs/openchallenges/api-client-angular/src/lib/model/challenge.ts +++ b/libs/openchallenges/api-client-angular/src/lib/model/challenge.ts @@ -9,9 +9,9 @@ * https://openapi-generator.tech * Do not edit the class manually. */ -import { EdamData } from './edamData'; import { EdamOperation } from './edamOperation'; import { ChallengeCategory } from './challengeCategory'; +import { EdamConcept } from './edamConcept'; import { SimpleChallengePlatform } from './simpleChallengePlatform'; import { ChallengeStatus } from './challengeStatus'; import { ChallengeIncentive } from './challengeIncentive'; @@ -58,7 +58,7 @@ export interface Challenge { avatarUrl?: string | null; incentives: Array; submissionTypes: Array; - inputDataTypes?: Array; + inputDataTypes?: Array; categories: Array; /** * The start date of the challenge. diff --git a/libs/openchallenges/api-client-angular/src/lib/model/challengeSearchQuery.ts b/libs/openchallenges/api-client-angular/src/lib/model/challengeSearchQuery.ts index 4d1bfd01f7..4cdd7836ae 100644 --- a/libs/openchallenges/api-client-angular/src/lib/model/challengeSearchQuery.ts +++ b/libs/openchallenges/api-client-angular/src/lib/model/challengeSearchQuery.ts @@ -63,6 +63,10 @@ export interface ChallengeSearchQuery { * An array of challenge submission types used to filter the results. */ submissionTypes?: Array; + /** + * An array of EDAM concept ID used to filter the results. + */ + inputDataTypes?: Array; /** * The array of challenge categories used to filter the results. */ diff --git a/libs/openchallenges/api-client-angular/src/lib/model/edamData.ts b/libs/openchallenges/api-client-angular/src/lib/model/edamData.ts deleted file mode 100644 index 74d483b4c2..0000000000 --- a/libs/openchallenges/api-client-angular/src/lib/model/edamData.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * OpenChallenges REST API - * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - * - * The version of the OpenAPI document: 1.0.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -/** - * The EDAM Data concept. - */ -export interface EdamData { - classId: string; - preferredLabel: string; -} - diff --git a/libs/openchallenges/api-client-angular/src/lib/model/models.ts b/libs/openchallenges/api-client-angular/src/lib/model/models.ts index ab85bf5419..7e44f53f9b 100644 --- a/libs/openchallenges/api-client-angular/src/lib/model/models.ts +++ b/libs/openchallenges/api-client-angular/src/lib/model/models.ts @@ -26,7 +26,6 @@ export * from './edamConceptSearchQuery'; export * from './edamConceptSort'; export * from './edamConceptsPage'; export * from './edamConceptsPageAllOf'; -export * from './edamData'; export * from './edamOperation'; export * from './edamSection'; export * from './image'; diff --git a/libs/openchallenges/api-description/build/challenge.openapi.yaml b/libs/openchallenges/api-description/build/challenge.openapi.yaml index 2924f6e4ee..3f3fb78331 100644 --- a/libs/openchallenges/api-description/build/challenge.openapi.yaml +++ b/libs/openchallenges/api-description/build/challenge.openapi.yaml @@ -217,6 +217,11 @@ components: - mlcube - other example: container_image + EdamConceptId: + description: The unique identifier of the EDAM concept. + type: integer + format: int64 + example: 1 ChallengeCategory: description: The category of the challenge. type: string @@ -293,6 +298,11 @@ components: type: array items: $ref: '#/components/schemas/ChallengeSubmissionType' + inputDataTypes: + description: An array of EDAM concept ID used to filter the results. + type: array + items: + $ref: '#/components/schemas/EdamConceptId' categories: description: The array of challenge categories used to filter the results. type: array @@ -410,20 +420,22 @@ components: maxLength: 500 nullable: true example: https://openchallenges.io - EdamData: + EdamConcept: type: object - description: The EDAM Data concept. + description: The EDAM concept. properties: + id: + $ref: '#/components/schemas/EdamConceptId' classId: type: string example: http://edamontology.org/data_0850 maxLength: 60 - pattern: ^http:\/\/edamontology\.org\/data_\d+$ preferredLabel: type: string example: Sequence set maxLength: 80 required: + - id - classId - preferredLabel nullable: true @@ -501,7 +513,7 @@ components: inputDataTypes: type: array items: - $ref: '#/components/schemas/EdamData' + $ref: '#/components/schemas/EdamConcept' categories: type: array items: @@ -774,30 +786,6 @@ components: type: array items: $ref: '#/components/schemas/EdamSection' - EdamConceptId: - description: The unique identifier of the EDAM concept. - type: integer - format: int64 - example: 1 - EdamConcept: - type: object - description: The EDAM concept. - properties: - id: - $ref: '#/components/schemas/EdamConceptId' - classId: - type: string - example: http://edamontology.org/data_0850 - maxLength: 60 - preferredLabel: - type: string - example: Sequence set - maxLength: 80 - required: - - id - - classId - - preferredLabel - nullable: true EdamConceptsPage: type: object description: A page of EDAM concepts. diff --git a/libs/openchallenges/api-description/build/openapi.yaml b/libs/openchallenges/api-description/build/openapi.yaml index 6843c46711..90d2eacd5e 100644 --- a/libs/openchallenges/api-description/build/openapi.yaml +++ b/libs/openchallenges/api-description/build/openapi.yaml @@ -367,6 +367,11 @@ components: - mlcube - other example: container_image + EdamConceptId: + description: The unique identifier of the EDAM concept. + type: integer + format: int64 + example: 1 ChallengeCategory: description: The category of the challenge. type: string @@ -443,6 +448,11 @@ components: type: array items: $ref: '#/components/schemas/ChallengeSubmissionType' + inputDataTypes: + description: An array of EDAM concept ID used to filter the results. + type: array + items: + $ref: '#/components/schemas/EdamConceptId' categories: description: The array of challenge categories used to filter the results. type: array @@ -560,20 +570,22 @@ components: maxLength: 500 nullable: true example: 'https://openchallenges.io' - EdamData: + EdamConcept: type: object - description: The EDAM Data concept. + description: The EDAM concept. properties: + id: + $ref: '#/components/schemas/EdamConceptId' classId: type: string example: 'http://edamontology.org/data_0850' maxLength: 60 - pattern: '^http:\/\/edamontology\.org\/data_\d+$' preferredLabel: type: string example: Sequence set maxLength: 80 required: + - id - classId - preferredLabel nullable: true @@ -651,7 +663,7 @@ components: inputDataTypes: type: array items: - $ref: '#/components/schemas/EdamData' + $ref: '#/components/schemas/EdamConcept' categories: type: array items: @@ -928,30 +940,6 @@ components: type: array items: $ref: '#/components/schemas/EdamSection' - EdamConceptId: - description: The unique identifier of the EDAM concept. - type: integer - format: int64 - example: 1 - EdamConcept: - type: object - description: The EDAM concept. - properties: - id: - $ref: '#/components/schemas/EdamConceptId' - classId: - type: string - example: 'http://edamontology.org/data_0850' - maxLength: 60 - preferredLabel: - type: string - example: Sequence set - maxLength: 80 - required: - - id - - classId - - preferredLabel - nullable: true EdamConceptsPage: type: object description: A page of EDAM concepts. diff --git a/libs/openchallenges/api-description/src/components/schemas/Challenge.yaml b/libs/openchallenges/api-description/src/components/schemas/Challenge.yaml index e84a899650..405a89beea 100644 --- a/libs/openchallenges/api-description/src/components/schemas/Challenge.yaml +++ b/libs/openchallenges/api-description/src/components/schemas/Challenge.yaml @@ -32,7 +32,7 @@ properties: inputDataTypes: type: array items: - $ref: EdamData.yaml + $ref: EdamConcept.yaml categories: type: array items: diff --git a/libs/openchallenges/api-description/src/components/schemas/ChallengeSearchQuery.yaml b/libs/openchallenges/api-description/src/components/schemas/ChallengeSearchQuery.yaml index 4ddf4f9258..8d19afb52e 100644 --- a/libs/openchallenges/api-description/src/components/schemas/ChallengeSearchQuery.yaml +++ b/libs/openchallenges/api-description/src/components/schemas/ChallengeSearchQuery.yaml @@ -61,6 +61,11 @@ properties: type: array items: $ref: ChallengeSubmissionType.yaml + inputDataTypes: + description: An array of EDAM concept ID used to filter the results. + type: array + items: + $ref: EdamConceptId.yaml categories: description: The array of challenge categories used to filter the results. type: array diff --git a/libs/openchallenges/api-description/src/components/schemas/EdamData.yaml b/libs/openchallenges/api-description/src/components/schemas/EdamData.yaml deleted file mode 100644 index 4fd91b59d8..0000000000 --- a/libs/openchallenges/api-description/src/components/schemas/EdamData.yaml +++ /dev/null @@ -1,16 +0,0 @@ -type: object -description: The EDAM Data concept. -properties: - classId: - type: string - example: 'http://edamontology.org/data_0850' - maxLength: 60 - pattern: '^http:\/\/edamontology\.org\/data_\d+$' - preferredLabel: - type: string - example: 'Sequence set' - maxLength: 80 -required: - - classId - - preferredLabel -nullable: true