From c71eb39298670aff8d3cba105be692df7e9b106b Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 26 Jun 2024 23:37:59 +0100 Subject: [PATCH 01/82] Initial GFF loading code --- .../curation_api/constants/Gff3Constants.java | 14 ++ .../constants/LinkMLSchemaConstants.java | 2 +- .../curation_api/dao/CodingSequenceDAO.java | 15 ++ .../curation_api/dao/ExonDAO.java | 15 ++ .../curation_api/dao/GenomeAssemblyDAO.java | 15 ++ .../curation_api/dao/TranscriptDAO.java | 15 ++ .../jobs/executors/Gff3Executor.java | 146 ++++++++++++++++++ .../jobs/util/CsvSchemaBuilder.java | 20 +++ .../model/entities/CodingSequence.java | 46 ++++++ .../curation_api/model/entities/Exon.java | 46 ++++++ .../model/entities/GenomeAssembly.java | 52 +++++++ .../model/entities/Transcript.java | 46 ++++++ .../model/ingest/dto/fms/Gff3DTO.java | 24 +++ .../curation_api/services/ExonService.java | 44 ++++++ .../curation_api/services/Gff3Service.java | 91 +++++++++++ .../validation/dto/Gff3DtoValidator.java | 88 +++++++++++ 16 files changed, 678 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/CodingSequenceDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/ExonDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/GenomeAssemblyDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/TranscriptDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/ingest/dto/fms/Gff3DTO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/ExonService.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java diff --git a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java new file mode 100644 index 000000000..b2681db8c --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java @@ -0,0 +1,14 @@ +package org.alliancegenome.curation_api.constants; + +import java.util.List; + +public final class Gff3Constants { + private Gff3Constants() { + // Hidden from view, as it is a utility class + } + public static final List TRANSCRIPT_TYPES = List.of( + "mRNA", "ncRNA", "piRNA", "lincRNA", "miRNA", "pre_miRNA", "snoRNA", "lncRNA", + "tRNA", "snRNA", "rRNA", "antisense_RNA", "C_gene_segment", "V_gene_segment", + "pseudogene_attribute", "snoRNA_gene", "pseudogenic_transcript", "lnc_RNA"); + +} \ No newline at end of file diff --git a/src/main/java/org/alliancegenome/curation_api/constants/LinkMLSchemaConstants.java b/src/main/java/org/alliancegenome/curation_api/constants/LinkMLSchemaConstants.java index c2126f426..65fdf41c8 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/LinkMLSchemaConstants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/LinkMLSchemaConstants.java @@ -5,7 +5,7 @@ public class LinkMLSchemaConstants { private LinkMLSchemaConstants() { // Hidden from view, as it is a utility class } - public static final String LATEST_RELEASE = "2.2.3"; + public static final String LATEST_RELEASE = "2.4.0"; public static final String MIN_ONTOLOGY_RELEASE = "1.2.4"; public static final String MAX_ONTOLOGY_RELEASE = LATEST_RELEASE; diff --git a/src/main/java/org/alliancegenome/curation_api/dao/CodingSequenceDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/CodingSequenceDAO.java new file mode 100644 index 000000000..12903065f --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/CodingSequenceDAO.java @@ -0,0 +1,15 @@ +package org.alliancegenome.curation_api.dao; + +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.CodingSequence; + +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class CodingSequenceDAO extends BaseSQLDAO { + + protected CodingSequenceDAO() { + super(CodingSequence.class); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/dao/ExonDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/ExonDAO.java new file mode 100644 index 000000000..95c7a71a5 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/ExonDAO.java @@ -0,0 +1,15 @@ +package org.alliancegenome.curation_api.dao; + +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.Exon; + +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class ExonDAO extends BaseSQLDAO { + + protected ExonDAO() { + super(Exon.class); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/dao/GenomeAssemblyDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/GenomeAssemblyDAO.java new file mode 100644 index 000000000..5b3dba8d5 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/GenomeAssemblyDAO.java @@ -0,0 +1,15 @@ +package org.alliancegenome.curation_api.dao; + +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.GenomeAssembly; + +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class GenomeAssemblyDAO extends BaseSQLDAO { + + protected GenomeAssemblyDAO() { + super(GenomeAssembly.class); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/dao/TranscriptDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/TranscriptDAO.java new file mode 100644 index 000000000..1052c3e36 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/TranscriptDAO.java @@ -0,0 +1,15 @@ +package org.alliancegenome.curation_api.dao; + +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.Transcript; + +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class TranscriptDAO extends BaseSQLDAO { + + protected TranscriptDAO() { + super(Transcript.class); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java new file mode 100644 index 000000000..f4a98997e --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java @@ -0,0 +1,146 @@ +package org.alliancegenome.curation_api.jobs.executors; + +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.GZIPInputStream; + +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; +import org.alliancegenome.curation_api.exceptions.ObjectUpdateException.ObjectUpdateExceptionData; +import org.alliancegenome.curation_api.jobs.util.CsvSchemaBuilder; +import org.alliancegenome.curation_api.model.entities.GenomeAssembly; +import org.alliancegenome.curation_api.model.entities.bulkloads.BulkFMSLoad; +import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFile; +import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.model.ingest.dto.fms.PsiMiTabDTO; +import org.alliancegenome.curation_api.services.Gff3Service; +import org.alliancegenome.curation_api.util.ProcessDisplayHelper; +import org.apache.commons.lang3.ObjectUtils; + +import com.fasterxml.jackson.databind.MappingIterator; +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvParser; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +@ApplicationScoped +public class Gff3Executor extends LoadFileExecutor { + + @Inject Gff3Service gff3Service; + + public void execLoad(BulkLoadFile bulkLoadFile) { + try { + + CsvSchema psiMiTabSchema = CsvSchemaBuilder.gff3Schema(); + CsvMapper csvMapper = new CsvMapper(); + MappingIterator it = csvMapper.enable(CsvParser.Feature.INSERT_NULLS_FOR_MISSING_COLUMNS).readerFor(PsiMiTabDTO.class).with(psiMiTabSchema).readValues(new GZIPInputStream(new FileInputStream(bulkLoadFile.getLocalFilePath()))); + List gffData = it.readAll(); + List gffHeaderData = new ArrayList<>(); + for (Gff3DTO gffLine : gffData) { + if (gffLine.getSeqId().startsWith("#")) { + gffHeaderData.add(gffLine.getSeqId()); + } else { + break; + } + } + gffData.subList(0, gffHeaderData.size() - 1).clear(); + + + BulkFMSLoad fmsLoad = (BulkFMSLoad) bulkLoadFile.getBulkLoad(); + BackendBulkDataProvider dataProvider = BackendBulkDataProvider.valueOf(fmsLoad.getFmsDataSubType()); + + Map> idsAdded = new HashMap>(); + + // TODO: get ids of previously loaded entities + + BulkLoadFileHistory history = new BulkLoadFileHistory(gffData.size()); + createHistory(history, bulkLoadFile); + runLoad(history, gffHeaderData, gffData, idsAdded, dataProvider); + + // TODO: run cleanup + + history.finishLoad(); + finalSaveHistory(history); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void runLoad(BulkLoadFileHistory history, List gffHeaderData, List gffData, + Map> idsAdded, BackendBulkDataProvider dataProvider) { + + ProcessDisplayHelper ph = new ProcessDisplayHelper(); + ph.addDisplayHandler(loadProcessDisplayService); + ph.startProcess("GFF update for " + dataProvider.name(), (gffData.size() * 2) + 1); + + GenomeAssembly assembly = loadGenomeAssembly(history, gffHeaderData, dataProvider, ph); + loadEntities(history, gffData, idsAdded, dataProvider, ph); + if (ObjectUtils.isNotEmpty(assembly)) { + loadAssociations(history, gffData, idsAdded, dataProvider, assembly, ph); + } + } + + private GenomeAssembly loadGenomeAssembly(BulkLoadFileHistory history, List gffHeaderData, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { + GenomeAssembly assembly = null; + try { + assembly = gff3Service.loadGenomeAssembly(gffHeaderData, dataProvider); + history.incrementCompleted(); + } catch (ObjectUpdateException e) { + history.incrementFailed(); + addException(history, e.getData()); + } catch (Exception e) { + e.printStackTrace(); + history.incrementFailed(); + addException(history, new ObjectUpdateExceptionData(gffHeaderData, e.getMessage(), e.getStackTrace())); + } + updateHistory(history); + ph.progressProcess(); + return assembly; + } + + private void loadEntities(BulkLoadFileHistory history, List gffData, Map> idsAdded, + BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { + for (Gff3DTO gff3Entry : gffData) { + try { + idsAdded = gff3Service.loadEntities(history, gff3Entry, idsAdded, dataProvider); + history.incrementCompleted(); + } catch (ObjectUpdateException e) { + history.incrementFailed(); + addException(history, e.getData()); + } catch (Exception e) { + e.printStackTrace(); + history.incrementFailed(); + addException(history, new ObjectUpdateExceptionData(gff3Entry, e.getMessage(), e.getStackTrace())); + } + updateHistory(history); + ph.progressProcess(); + } + } + + private void loadAssociations(BulkLoadFileHistory history, List gffData, Map> idsAdded, + BackendBulkDataProvider dataProvider, GenomeAssembly assembly, ProcessDisplayHelper ph) { + for (Gff3DTO gff3Entry : gffData) { + try { + idsAdded = gff3Service.loadAssociations(history, gff3Entry, idsAdded, dataProvider, assembly); + history.incrementCompleted(); + } catch (ObjectUpdateException e) { + history.incrementFailed(); + addException(history, e.getData()); + } catch (Exception e) { + e.printStackTrace(); + history.incrementFailed(); + addException(history, new ObjectUpdateExceptionData(gff3Entry, e.getMessage(), e.getStackTrace())); + } + updateHistory(history); + ph.progressProcess(); + history.incrementCompleted(); + } + } +} diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/util/CsvSchemaBuilder.java b/src/main/java/org/alliancegenome/curation_api/jobs/util/CsvSchemaBuilder.java index 87778e0a4..677f4579c 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/util/CsvSchemaBuilder.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/util/CsvSchemaBuilder.java @@ -59,4 +59,24 @@ public static CsvSchema psiMiTabSchema() { return schema; } + + public static CsvSchema gff3Schema() { + CsvSchema schema = CsvSchema.builder() + .setColumnSeparator('\t') + .setArrayElementSeparator(";") + .setNullValue(".") + .disableQuoteChar() + .addColumn("seqId") + .addColumn("source") + .addColumn("type") + .addColumn("start") + .addColumn("end") + .addColumn("score") + .addColumn("strand") + .addColumn("phase") + .addColumn("attributes") + .build(); + + return schema; + } } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java b/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java new file mode 100644 index 000000000..89edeeabf --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java @@ -0,0 +1,46 @@ +package org.alliancegenome.curation_api.model.entities; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.ManyToOne; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Indexed +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@Schema(name = "CodingSequence", description = "POJO that represents the CodingSequence (CDS)") +@AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) +public class CodingSequence extends GenomicEntity { + + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @JsonView({ View.FieldsOnly.class }) + private String name; + + @IndexedEmbedded(includePaths = {"curie", "name", "curie_keyword", "name_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + private SOTerm cdsType; + +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java b/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java new file mode 100644 index 000000000..b1b583c87 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java @@ -0,0 +1,46 @@ +package org.alliancegenome.curation_api.model.entities; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.ManyToOne; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Indexed +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@Schema(name = "Exon", description = "POJO that represents the Exon") +@AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) +public class Exon extends GenomicEntity { + + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @JsonView({ View.FieldsOnly.class }) + private String name; + + @IndexedEmbedded(includePaths = {"curie", "name", "curie_keyword", "name_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + private SOTerm exonType; + +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java b/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java new file mode 100644 index 000000000..944443cdf --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java @@ -0,0 +1,52 @@ +package org.alliancegenome.curation_api.model.entities; + +import java.util.List; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +@Indexed +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@Schema(name = "GenomeAssembly", description = "POJO that represents a GenomeAssembly") +@AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { BiologicalEntity.class }) +public class GenomeAssembly extends BiologicalEntity { + + @IndexedEmbedded(includePaths = {"referencedCurie", "displayName", "resourceDescriptorPage.name", "referencedCurie_keyword", "displayName_keyword", "resourceDescriptorPage.name_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinTable(indexes = { + @Index(columnList = "genomeassembly_id, crossreferences_id", name = "genomeassembly_crossreference_genomeassembly_xref_index"), + @Index(columnList = "genomeassembly_id", name = "genomeassembly_crossreference_genomeassembly_index"), + @Index(columnList = "crossreferences_id", name = "genomeassembly_crossreference_crossreferences_index") + }) + @EqualsAndHashCode.Include + @JsonView({ View.FieldsAndLists.class }) + private List crossReferences; + + @IndexedEmbedded(includePaths = {"name", "name_keyword", "curie", "curie_keyword", "modEntityId", "modEntityId_keyword", "modInternalId", "modInternalId_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + private AffectedGenomicModel specimenGenomicModel; + +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java b/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java new file mode 100644 index 000000000..01a850532 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java @@ -0,0 +1,46 @@ +package org.alliancegenome.curation_api.model.entities; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.ManyToOne; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Indexed +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@Schema(name = "Transcript", description = "POJO that represents the Transcript") +@AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) +public class Transcript extends GenomicEntity { + + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @JsonView({ View.FieldsOnly.class }) + private String name; + + @IndexedEmbedded(includePaths = {"curie", "name", "curie_keyword", "name_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + private SOTerm transcriptType; + +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/ingest/dto/fms/Gff3DTO.java b/src/main/java/org/alliancegenome/curation_api/model/ingest/dto/fms/Gff3DTO.java new file mode 100644 index 000000000..c5dddaeca --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/ingest/dto/fms/Gff3DTO.java @@ -0,0 +1,24 @@ +package org.alliancegenome.curation_api.model.ingest.dto.fms; + +import java.util.List; + +import org.alliancegenome.curation_api.model.ingest.dto.base.BaseDTO; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class Gff3DTO extends BaseDTO { + + private String seqId; + private String source; + private String type; + private Integer start; + private Integer end; + private Float score; + private String strand; + private Integer phase; + private List attributes; + +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/ExonService.java b/src/main/java/org/alliancegenome/curation_api/services/ExonService.java new file mode 100644 index 000000000..7eea708d8 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/ExonService.java @@ -0,0 +1,44 @@ +package org.alliancegenome.curation_api.services; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.alliancegenome.curation_api.constants.EntityFieldConstants; +import org.alliancegenome.curation_api.dao.ExonDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.model.entities.Exon; +import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; +import org.alliancegenome.curation_api.services.validation.dto.Gff3DtoValidator; +import org.apache.commons.lang.StringUtils; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; + +@RequestScoped +public class ExonService extends BaseEntityCrudService { + + @Inject ExonDAO exonDAO; + @Inject PersonService personService; + @Inject Gff3DtoValidator gff3DtoValidator; + + @Override + @PostConstruct + protected void init() { + setSQLDao(exonDAO); + } + + public List getIdsByDataProvider(BackendBulkDataProvider dataProvider) { + Map params = new HashMap<>(); + params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider.sourceOrganization); + if (StringUtils.equals(dataProvider.sourceOrganization, "RGD")) { + params.put(EntityFieldConstants.TAXON, dataProvider.canonicalTaxonCurie); + } + List ids = exonDAO.findIdsByParams(params); + ids.removeIf(Objects::isNull); + return ids; + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java new file mode 100644 index 000000000..128e96939 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java @@ -0,0 +1,91 @@ +package org.alliancegenome.curation_api.services; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alliancegenome.curation_api.constants.EntityFieldConstants; +import org.alliancegenome.curation_api.constants.Gff3Constants; +import org.alliancegenome.curation_api.constants.ValidationConstants; +import org.alliancegenome.curation_api.dao.GenomeAssemblyDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; +import org.alliancegenome.curation_api.exceptions.ObjectValidationException; +import org.alliancegenome.curation_api.model.entities.GenomeAssembly; +import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; +import org.apache.commons.codec.binary.StringUtils; +import org.apache.commons.collections.CollectionUtils; + +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; + +@RequestScoped +public class Gff3Service { + + @Inject GenomeAssemblyDAO genomeAssemblyDAO; + @Inject DataProviderService dataProviderService; + @Inject NcbiTaxonTermService ncbiTaxonTermService; + + @Transactional + public GenomeAssembly loadGenomeAssembly(List gffHeaderData, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { + + for (String header : gffHeaderData) { + if (header.startsWith("#!assembly")) { + String assemblyName = header.split(" ")[1]; + Map params = new HashMap<>(); + params.put("modEntityId", assemblyName); + params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider.sourceOrganization); + params.put(EntityFieldConstants.TAXON, dataProvider.canonicalTaxonCurie); + + SearchResponse resp = genomeAssemblyDAO.findByParams(params); + if (resp != null && resp.getSingleResult() != null) { + return resp.getSingleResult(); + } + + GenomeAssembly assembly = new GenomeAssembly(); + assembly.setModEntityId(assemblyName); + assembly.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProvider.sourceOrganization)); + assembly.setTaxon(ncbiTaxonTermService.getByCurie(dataProvider.canonicalTaxonCurie).getEntity()); + + return genomeAssemblyDAO.persist(assembly); + } + } + throw new ObjectValidationException(gffHeaderData, "#!assembly - " + ValidationConstants.REQUIRED_MESSAGE); + } + + public Map> loadEntities(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { + Map attributes = getAttributes(gffEntry); + if (StringUtils.equals(gffEntry.getType(), "exon")) { + + } else if (StringUtils.equals(gffEntry.getType(), "CDS")) { + + } else if (Gff3Constants.TRANSCRIPT_TYPES.contains(gffEntry.getType())) { + if (StringUtils.equals(gffEntry.getType(), "lnc_RNA")) { + gffEntry.setType("lncRNA"); + } + } + return idsAdded; + } + + public Map> loadAssociations(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider, GenomeAssembly assembly) throws ObjectUpdateException { + // TODO: implement association loading + return idsAdded; + } + + private Map getAttributes (Gff3DTO gffEntry) { + Map attributes = new HashMap(); + if (CollectionUtils.isNotEmpty(gffEntry.getAttributes())) { + for (String keyValue : gffEntry.getAttributes()) { + String[] parts = keyValue.split("="); + if (parts.length == 2) { + attributes.put(parts[0], parts[1]); + } + } + } + return attributes; + } +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java new file mode 100644 index 000000000..550765199 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -0,0 +1,88 @@ +package org.alliancegenome.curation_api.services.validation.dto; + +import java.util.HashMap; +import java.util.Map; + +import org.alliancegenome.curation_api.constants.ValidationConstants; +import org.alliancegenome.curation_api.dao.CodingSequenceDAO; +import org.alliancegenome.curation_api.dao.ExonDAO; +import org.alliancegenome.curation_api.dao.TranscriptDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.exceptions.ObjectValidationException; +import org.alliancegenome.curation_api.model.entities.Exon; +import org.alliancegenome.curation_api.model.entities.GenomicEntity; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.services.DataProviderService; +import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; +import org.alliancegenome.curation_api.services.validation.dto.base.BaseDTOValidator; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; + +@RequestScoped +public class Gff3DtoValidator extends BaseDTOValidator { + + @Inject ExonDAO exonDAO; + @Inject TranscriptDAO transcriptDAO; + @Inject CodingSequenceDAO codingSequenceDAO; + @Inject DataProviderService dataProviderService; + @Inject NcbiTaxonTermService ncbiTaxonTermService; + + private ObjectResponse exonResponse; + + @Transactional + public Exon validateExonEntry(Gff3DTO dto, BackendBulkDataProvider dataProvider) throws ObjectValidationException { + + exonResponse = new ObjectResponse<>(); + + Exon exon = new Exon(); + if (StringUtils.isNotBlank(dto.getSeqId())) { + SearchResponse exonResponse = exonDAO.findByField("modEntityId", dto.getSeqId()); + if (exonResponse != null && exonResponse.getSingleResult() != null) { + exon = exonResponse.getSingleResult(); + } + } + + ObjectResponse geResponse = validateGffEntry(exon, dto, dataProvider); + + + + return exonDAO.persist(exon); + } + + private ObjectResponse validateGffEntry(E entity, Gff3DTO dto, BackendBulkDataProvider dataProvider) { + ObjectResponse geResponse = new ObjectResponse(); + + if (StringUtils.isBlank(dto.getSeqId())) { + geResponse.addErrorMessage("seqId", ValidationConstants.REQUIRED_MESSAGE); + } + entity.setModEntityId(dto.getSeqId()); + + entity.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProvider.sourceOrganization)); + entity.setTaxon(ncbiTaxonTermService.getByCurie(dataProvider.canonicalTaxonCurie).getEntity()); + + + Map attributes = getAttributes(dto); + + return geResponse; + } + + private Map getAttributes (Gff3DTO dto) { + Map attributes = new HashMap(); + if (CollectionUtils.isNotEmpty(dto.getAttributes())) { + for (String keyValue : dto.getAttributes()) { + String[] parts = keyValue.split("="); + if (parts.length == 2) { + attributes.put(parts[0], parts[1]); + } + } + } + return attributes; + } + +} From 5fa2e7c2a742d4d629a3bba64349565d08b713da Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Tue, 2 Jul 2024 13:46:55 +0100 Subject: [PATCH 02/82] GFF entity loading --- .../cliapp/src/service/DataLoadService.js | 1 + .../crud/CodingSequenceCrudController.java | 47 +++++++ .../controllers/crud/ExonCrudController.java | 48 +++++++ .../crud/TranscriptCrudController.java | 47 +++++++ .../enums/BackendBulkLoadType.java | 1 + .../crud/CodingSequenceCrudInterface.java | 32 +++++ .../interfaces/crud/ExonCrudInterface.java | 32 +++++ .../crud/TranscriptCrudInterface.java | 33 +++++ .../jobs/executors/Gff3Executor.java | 82 +++++++++--- .../bridges/BiologicalEntityTypeBridge.java | 15 +++ .../model/entities/CodingSequence.java | 9 +- .../curation_api/model/entities/Exon.java | 9 +- .../model/entities/GenomeAssembly.java | 2 +- .../model/entities/Transcript.java | 2 - .../services/CodingSequenceService.java | 54 ++++++++ .../curation_api/services/ExonService.java | 11 +- .../curation_api/services/Gff3Service.java | 79 ++++++----- .../services/TranscriptService.java | 61 +++++++++ .../helpers/UniqueIdGeneratorHelper.java | 6 + .../helpers/gff3/Gff3UniqueIdHelper.java | 46 +++++++ .../validation/dto/Gff3DtoValidator.java | 126 +++++++++++++++--- .../v0.35.0.9__gff_entity_tables.sql | 101 ++++++++++++++ .../curation_api/AlleleITCase.java | 2 +- .../curation_api/GeneITCase.java | 6 +- .../curation_api/Gff3BulkUploadFmsITCase.java | 107 +++++++++++++++ .../curation_api/base/BaseITCase.java | 64 +++++++-- .../fms/08_gff_data/GFF01_transcript.json | 14 ++ .../bulk/fms/08_gff_data/GFF02_exon.json | 14 ++ .../bulk/fms/08_gff_data/GFF03_CDS.json | 14 ++ 29 files changed, 968 insertions(+), 97 deletions(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/controllers/crud/CodingSequenceCrudController.java create mode 100644 src/main/java/org/alliancegenome/curation_api/controllers/crud/ExonCrudController.java create mode 100644 src/main/java/org/alliancegenome/curation_api/controllers/crud/TranscriptCrudController.java create mode 100644 src/main/java/org/alliancegenome/curation_api/interfaces/crud/CodingSequenceCrudInterface.java create mode 100644 src/main/java/org/alliancegenome/curation_api/interfaces/crud/ExonCrudInterface.java create mode 100644 src/main/java/org/alliancegenome/curation_api/interfaces/crud/TranscriptCrudInterface.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/CodingSequenceService.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/TranscriptService.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3UniqueIdHelper.java create mode 100644 src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql create mode 100644 src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadFmsITCase.java create mode 100644 src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json create mode 100644 src/test/resources/bulk/fms/08_gff_data/GFF02_exon.json create mode 100644 src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json diff --git a/src/main/cliapp/src/service/DataLoadService.js b/src/main/cliapp/src/service/DataLoadService.js index a77432c81..90612fe46 100644 --- a/src/main/cliapp/src/service/DataLoadService.js +++ b/src/main/cliapp/src/service/DataLoadService.js @@ -80,6 +80,7 @@ export class DataLoadService extends BaseAuthService { getBackendBulkLoadTypes(loadType) { const bulkLoadTypes = { BulkFMSLoad: [ + 'GFF', 'INTERACTION-GEN', 'INTERACTION-MOL', 'MOLECULE', diff --git a/src/main/java/org/alliancegenome/curation_api/controllers/crud/CodingSequenceCrudController.java b/src/main/java/org/alliancegenome/curation_api/controllers/crud/CodingSequenceCrudController.java new file mode 100644 index 000000000..5585ab971 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/controllers/crud/CodingSequenceCrudController.java @@ -0,0 +1,47 @@ +package org.alliancegenome.curation_api.controllers.crud; + +import java.util.List; + +import org.alliancegenome.curation_api.controllers.base.BaseEntityCrudController; +import org.alliancegenome.curation_api.dao.CodingSequenceDAO; +import org.alliancegenome.curation_api.interfaces.crud.CodingSequenceCrudInterface; +import org.alliancegenome.curation_api.jobs.executors.Gff3Executor; +import org.alliancegenome.curation_api.model.entities.CodingSequence; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.services.CodingSequenceService; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; + +@RequestScoped +public class CodingSequenceCrudController extends BaseEntityCrudController implements CodingSequenceCrudInterface { + + @Inject + CodingSequenceService codingSequenceService; + @Inject + Gff3Executor gff3Executor; + + @Override + @PostConstruct + protected void init() { + setService(codingSequenceService); + } + + public APIResponse updateCodingSequences(String dataProvider, String assembly, List gffData) { + return gff3Executor.runLoadApi(dataProvider, assembly, gffData); + } + + @Override + public ObjectResponse getByIdentifier(String identifierString) { + return codingSequenceService.getByIdentifier(identifierString); + } + + @Override + public ObjectResponse deleteByIdentifier(String identifierString) { + return codingSequenceService.deleteByIdentifier(identifierString); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/controllers/crud/ExonCrudController.java b/src/main/java/org/alliancegenome/curation_api/controllers/crud/ExonCrudController.java new file mode 100644 index 000000000..bf4c105dd --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/controllers/crud/ExonCrudController.java @@ -0,0 +1,48 @@ +package org.alliancegenome.curation_api.controllers.crud; + +import java.util.List; + +import org.alliancegenome.curation_api.controllers.base.BaseEntityCrudController; +import org.alliancegenome.curation_api.dao.ExonDAO; +import org.alliancegenome.curation_api.interfaces.crud.ExonCrudInterface; +import org.alliancegenome.curation_api.jobs.executors.Gff3Executor; +import org.alliancegenome.curation_api.model.entities.Exon; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.services.ExonService; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; + +@RequestScoped +public class ExonCrudController extends BaseEntityCrudController implements ExonCrudInterface { + + @Inject + ExonService exonService; + @Inject + Gff3Executor gff3Executor; + + @Override + @PostConstruct + protected void init() { + setService(exonService); + } + + @Override + public APIResponse updateExons(String dataProvider, String assembly, List gffData) { + return gff3Executor.runLoadApi(dataProvider, assembly, gffData); + } + + @Override + public ObjectResponse getByIdentifier(String identifierString) { + return exonService.getByIdentifier(identifierString); + } + + @Override + public ObjectResponse deleteByIdentifier(String identifierString) { + return exonService.deleteByIdentifier(identifierString); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/controllers/crud/TranscriptCrudController.java b/src/main/java/org/alliancegenome/curation_api/controllers/crud/TranscriptCrudController.java new file mode 100644 index 000000000..a2b5e6c2a --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/controllers/crud/TranscriptCrudController.java @@ -0,0 +1,47 @@ +package org.alliancegenome.curation_api.controllers.crud; + +import java.util.List; + +import org.alliancegenome.curation_api.controllers.base.BaseEntityCrudController; +import org.alliancegenome.curation_api.dao.TranscriptDAO; +import org.alliancegenome.curation_api.interfaces.crud.TranscriptCrudInterface; +import org.alliancegenome.curation_api.jobs.executors.Gff3Executor; +import org.alliancegenome.curation_api.model.entities.Transcript; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.services.TranscriptService; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; + +@RequestScoped +public class TranscriptCrudController extends BaseEntityCrudController implements TranscriptCrudInterface { + + @Inject + TranscriptService transcriptService; + @Inject + Gff3Executor gff3Executor; + + @Override + @PostConstruct + protected void init() { + setService(transcriptService); + } + + public APIResponse updateTranscripts(String dataProvider, String assembly, List gffData) { + return gff3Executor.runLoadApi(dataProvider, assembly, gffData); + } + + @Override + public ObjectResponse getByIdentifier(String identifierString) { + return transcriptService.getByIdentifier(identifierString); + } + + @Override + public ObjectResponse deleteByIdentifier(String identifierString) { + return transcriptService.deleteByIdentifier(identifierString); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java index 1569bc30d..9172530be 100644 --- a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java +++ b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java @@ -18,6 +18,7 @@ public enum BackendBulkLoadType { ALLELE_ASSOCIATION("json"), CONSTRUCT_ASSOCIATION("json"), VARIANT("json"), + GFF("gff"), INTERACTION_MOL("tsv"), INTERACTION_GEN("tsv"), PARALOGY("json"), diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/CodingSequenceCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/CodingSequenceCrudInterface.java new file mode 100644 index 000000000..fff9b2b44 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/CodingSequenceCrudInterface.java @@ -0,0 +1,32 @@ +package org.alliancegenome.curation_api.interfaces.crud; + +import java.util.List; + +import org.alliancegenome.curation_api.interfaces.base.BaseSubmittedObjectCrudInterface; +import org.alliancegenome.curation_api.model.entities.CodingSequence; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +@Path("/cds") +@Tag(name = "CRUD - Coding Sequence") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface CodingSequenceCrudInterface extends BaseSubmittedObjectCrudInterface { + + @POST + @Path("/bulk/{dataProvider}_{assemblyName}/codingSequences") + @JsonView(View.FieldsAndLists.class) + APIResponse updateCodingSequences(@PathParam("dataProvider") String dataProvider, @PathParam("assemblyName") String assemblyName, List gff3Data); + +} diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/ExonCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/ExonCrudInterface.java new file mode 100644 index 000000000..bee4338c1 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/ExonCrudInterface.java @@ -0,0 +1,32 @@ +package org.alliancegenome.curation_api.interfaces.crud; + +import java.util.List; + +import org.alliancegenome.curation_api.interfaces.base.BaseSubmittedObjectCrudInterface; +import org.alliancegenome.curation_api.model.entities.Exon; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +@Path("/exon") +@Tag(name = "CRUD - Exon") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface ExonCrudInterface extends BaseSubmittedObjectCrudInterface { + + @POST + @Path("/bulk/{dataProvider}_{assemblyName}/exons") + @JsonView(View.FieldsAndLists.class) + APIResponse updateExons(@PathParam("dataProvider") String dataProvider, @PathParam("assemblyName") String assemblyName, List gff3Data); + +} diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/TranscriptCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/TranscriptCrudInterface.java new file mode 100644 index 000000000..ac1b81a3a --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/TranscriptCrudInterface.java @@ -0,0 +1,33 @@ +package org.alliancegenome.curation_api.interfaces.crud; + +import java.util.List; + +import org.alliancegenome.curation_api.interfaces.base.BaseSubmittedObjectCrudInterface; +import org.alliancegenome.curation_api.interfaces.base.crud.BaseReadIdentifierControllerInterface; +import org.alliancegenome.curation_api.model.entities.Transcript; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +@Path("/transcript") +@Tag(name = "CRUD - Transcript") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface TranscriptCrudInterface extends BaseSubmittedObjectCrudInterface { + + @POST + @Path("/bulk/{dataProvider}_{assemblyName}/transcripts") + @JsonView(View.FieldsAndLists.class) + APIResponse updateTranscripts(@PathParam("dataProvider") String dataProvider, @PathParam("assemblyName") String assemblyName, List gff3Data); + +} diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java index f4a98997e..06db63852 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java @@ -10,14 +10,22 @@ import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException.ObjectUpdateExceptionData; +import org.alliancegenome.curation_api.interfaces.crud.BaseUpsertServiceInterface; import org.alliancegenome.curation_api.jobs.util.CsvSchemaBuilder; import org.alliancegenome.curation_api.model.entities.GenomeAssembly; +import org.alliancegenome.curation_api.model.entities.base.AuditedObject; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkFMSLoad; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFile; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; +import org.alliancegenome.curation_api.model.ingest.dto.base.BaseDTO; import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; import org.alliancegenome.curation_api.model.ingest.dto.fms.PsiMiTabDTO; +import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.response.LoadHistoryResponce; +import org.alliancegenome.curation_api.services.CodingSequenceService; +import org.alliancegenome.curation_api.services.ExonService; import org.alliancegenome.curation_api.services.Gff3Service; +import org.alliancegenome.curation_api.services.TranscriptService; import org.alliancegenome.curation_api.util.ProcessDisplayHelper; import org.apache.commons.lang3.ObjectUtils; @@ -33,6 +41,9 @@ public class Gff3Executor extends LoadFileExecutor { @Inject Gff3Service gff3Service; + @Inject ExonService exonService; + @Inject CodingSequenceService cdsService; + @Inject TranscriptService transcriptService; public void execLoad(BulkLoadFile bulkLoadFile) { try { @@ -56,14 +67,18 @@ public void execLoad(BulkLoadFile bulkLoadFile) { BackendBulkDataProvider dataProvider = BackendBulkDataProvider.valueOf(fmsLoad.getFmsDataSubType()); Map> idsAdded = new HashMap>(); + idsAdded.put("Transcript", new ArrayList()); + idsAdded.put("Exon", new ArrayList()); + idsAdded.put("CodingSequence", new ArrayList()); - // TODO: get ids of previously loaded entities + Map> previousIds = getPreviouslyLoadedIds(dataProvider); BulkLoadFileHistory history = new BulkLoadFileHistory(gffData.size()); createHistory(history, bulkLoadFile); - runLoad(history, gffHeaderData, gffData, idsAdded, dataProvider); - - // TODO: run cleanup + idsAdded = runLoad(history, gffHeaderData, gffData, idsAdded, dataProvider); + runCleanup(transcriptService, history, dataProvider.name(), previousIds.get("Transcript"), idsAdded.get("Transcript"), "GFF transcript", bulkLoadFile.getMd5Sum()); + runCleanup(exonService, history, dataProvider.name(), previousIds.get("Exon"), idsAdded.get("Exon"), "GFF exon", bulkLoadFile.getMd5Sum()); + runCleanup(cdsService, history, dataProvider.name(), previousIds.get("CodingSequence"), idsAdded.get("CodingSequence"), "GFF coding sequence", bulkLoadFile.getMd5Sum()); history.finishLoad(); finalSaveHistory(history); @@ -72,25 +87,55 @@ public void execLoad(BulkLoadFile bulkLoadFile) { e.printStackTrace(); } } - - private void runLoad(BulkLoadFileHistory history, List gffHeaderData, List gffData, + + private Map> getPreviouslyLoadedIds(BackendBulkDataProvider dataProvider) { + Map> previousIds = new HashMap<>(); + + previousIds.put("Transcript", transcriptService.getIdsByDataProvider(dataProvider)); + previousIds.put("Exon", exonService.getIdsByDataProvider(dataProvider)); + previousIds.put("CodingSequence", cdsService.getIdsByDataProvider(dataProvider)); + + return previousIds; + } + + private Map> runLoad(BulkLoadFileHistory history, List gffHeaderData, List gffData, Map> idsAdded, BackendBulkDataProvider dataProvider) { + return runLoad(history, gffHeaderData, gffData, idsAdded, dataProvider, null); + } + + private Map> runLoad(BulkLoadFileHistory history, List gffHeaderData, List gffData, + Map> idsAdded, BackendBulkDataProvider dataProvider, String assemblyName) { ProcessDisplayHelper ph = new ProcessDisplayHelper(); ph.addDisplayHandler(loadProcessDisplayService); ph.startProcess("GFF update for " + dataProvider.name(), (gffData.size() * 2) + 1); - GenomeAssembly assembly = loadGenomeAssembly(history, gffHeaderData, dataProvider, ph); - loadEntities(history, gffData, idsAdded, dataProvider, ph); + GenomeAssembly assembly = loadGenomeAssembly(assemblyName, history, gffHeaderData, dataProvider, ph); + idsAdded = loadEntities(history, gffData, idsAdded, dataProvider, ph); if (ObjectUtils.isNotEmpty(assembly)) { - loadAssociations(history, gffData, idsAdded, dataProvider, assembly, ph); + idsAdded = loadAssociations(history, gffData, idsAdded, dataProvider, assembly, ph); } + + return idsAdded; } - - private GenomeAssembly loadGenomeAssembly(BulkLoadFileHistory history, List gffHeaderData, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { + + public APIResponse runLoadApi(String dataProviderName, String assemblyName, List gffData) { + Map> idsAdded = new HashMap>(); + idsAdded.put("Transcript", new ArrayList()); + idsAdded.put("Exon", new ArrayList()); + idsAdded.put("CodingSequence", new ArrayList()); + BulkLoadFileHistory history = new BulkLoadFileHistory((gffData.size() * 2) + 1); + BackendBulkDataProvider dataProvider = BackendBulkDataProvider.valueOf(dataProviderName); + runLoad(history, null, gffData, idsAdded, dataProvider, assemblyName); + history.finishLoad(); + + return new LoadHistoryResponce(history); + } + + private GenomeAssembly loadGenomeAssembly(String assemblyName, BulkLoadFileHistory history, List gffHeaderData, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { GenomeAssembly assembly = null; try { - assembly = gff3Service.loadGenomeAssembly(gffHeaderData, dataProvider); + assembly = gff3Service.loadGenomeAssembly(assemblyName, gffHeaderData, dataProvider); history.incrementCompleted(); } catch (ObjectUpdateException e) { history.incrementFailed(); @@ -105,11 +150,11 @@ private GenomeAssembly loadGenomeAssembly(BulkLoadFileHistory history, List gffData, Map> idsAdded, + private Map> loadEntities(BulkLoadFileHistory history, List gffData, Map> idsAdded, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { for (Gff3DTO gff3Entry : gffData) { try { - idsAdded = gff3Service.loadEntities(history, gff3Entry, idsAdded, dataProvider); + idsAdded = gff3Service.loadEntity(history, gff3Entry, idsAdded, dataProvider); history.incrementCompleted(); } catch (ObjectUpdateException e) { history.incrementFailed(); @@ -122,13 +167,15 @@ private void loadEntities(BulkLoadFileHistory history, List gffData, Ma updateHistory(history); ph.progressProcess(); } + + return idsAdded; } - private void loadAssociations(BulkLoadFileHistory history, List gffData, Map> idsAdded, + private Map> loadAssociations(BulkLoadFileHistory history, List gffData, Map> idsAdded, BackendBulkDataProvider dataProvider, GenomeAssembly assembly, ProcessDisplayHelper ph) { for (Gff3DTO gff3Entry : gffData) { try { - idsAdded = gff3Service.loadAssociations(history, gff3Entry, idsAdded, dataProvider, assembly); + idsAdded = gff3Service.loadAssociation(history, gff3Entry, idsAdded, dataProvider, assembly); history.incrementCompleted(); } catch (ObjectUpdateException e) { history.incrementFailed(); @@ -140,7 +187,8 @@ private void loadAssociations(BulkLoadFileHistory history, List gffData } updateHistory(history); ph.progressProcess(); - history.incrementCompleted(); } + + return idsAdded; } } diff --git a/src/main/java/org/alliancegenome/curation_api/model/bridges/BiologicalEntityTypeBridge.java b/src/main/java/org/alliancegenome/curation_api/model/bridges/BiologicalEntityTypeBridge.java index a0a7d0d9a..efa253b36 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/bridges/BiologicalEntityTypeBridge.java +++ b/src/main/java/org/alliancegenome/curation_api/model/bridges/BiologicalEntityTypeBridge.java @@ -3,8 +3,11 @@ import org.alliancegenome.curation_api.model.entities.AffectedGenomicModel; import org.alliancegenome.curation_api.model.entities.Allele; import org.alliancegenome.curation_api.model.entities.BiologicalEntity; +import org.alliancegenome.curation_api.model.entities.CodingSequence; +import org.alliancegenome.curation_api.model.entities.Exon; import org.alliancegenome.curation_api.model.entities.Gene; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; +import org.alliancegenome.curation_api.model.entities.Transcript; import org.hibernate.search.engine.backend.document.DocumentElement; import org.hibernate.search.engine.backend.document.IndexFieldReference; import org.hibernate.search.engine.backend.document.model.dsl.IndexSchemaElement; @@ -78,6 +81,18 @@ public void write(DocumentElement target, BiologicalEntity bridgedElement, TypeB SequenceTargetingReagent sqtr = (SequenceTargetingReagent) bridgedElement; name = sqtr.getName(); symbol = null; + } else if (bridgedElement instanceof Transcript) { + Transcript transcript = (Transcript) bridgedElement; + name = transcript.getName(); + symbol = null; + } else if (bridgedElement instanceof Exon) { + Exon exon = (Exon) bridgedElement; + name = exon.getName(); + symbol = null; + } else if (bridgedElement instanceof CodingSequence) { + CodingSequence cds = (CodingSequence) bridgedElement; + name = cds.getName(); + symbol = null; } else { name = null; symbol = null; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java b/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java index 89edeeabf..efde35219 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java @@ -18,7 +18,9 @@ import com.fasterxml.jackson.annotation.JsonView; import jakarta.persistence.Entity; +import jakarta.persistence.Index; import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -30,10 +32,15 @@ @ToString(callSuper = true) @Schema(name = "CodingSequence", description = "POJO that represents the CodingSequence (CDS)") @AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) +@Table(indexes = {@Index(name = "codingsequence_uniqueid_index", columnList = "uniqueid")}) public class CodingSequence extends GenomicEntity { @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") - @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @KeywordField(name = "uniqueId_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @JsonView({ View.FieldsOnly.class }) + @EqualsAndHashCode.Include + protected String uniqueId; + @JsonView({ View.FieldsOnly.class }) private String name; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java b/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java index b1b583c87..b3120d196 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java @@ -18,7 +18,9 @@ import com.fasterxml.jackson.annotation.JsonView; import jakarta.persistence.Entity; +import jakarta.persistence.Index; import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -30,10 +32,15 @@ @ToString(callSuper = true) @Schema(name = "Exon", description = "POJO that represents the Exon") @AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) +@Table(indexes = {@Index(name = "exon_uniqueid_index", columnList = "uniqueid")}) public class Exon extends GenomicEntity { @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") - @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @KeywordField(name = "uniqueId_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @JsonView({ View.FieldsOnly.class }) + @EqualsAndHashCode.Include + protected String uniqueId; + @JsonView({ View.FieldsOnly.class }) private String name; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java b/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java index 944443cdf..715057abb 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java @@ -37,7 +37,7 @@ public class GenomeAssembly extends BiologicalEntity { @JoinTable(indexes = { @Index(columnList = "genomeassembly_id, crossreferences_id", name = "genomeassembly_crossreference_genomeassembly_xref_index"), @Index(columnList = "genomeassembly_id", name = "genomeassembly_crossreference_genomeassembly_index"), - @Index(columnList = "crossreferences_id", name = "genomeassembly_crossreference_crossreferences_index") + @Index(columnList = "crossreferences_id", name = "genomeassembly_crossreference_crossreference_index") }) @EqualsAndHashCode.Include @JsonView({ View.FieldsAndLists.class }) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java b/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java index 01a850532..8dc40e0d3 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java @@ -32,8 +32,6 @@ @AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) public class Transcript extends GenomicEntity { - @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") - @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") @JsonView({ View.FieldsOnly.class }) private String name; diff --git a/src/main/java/org/alliancegenome/curation_api/services/CodingSequenceService.java b/src/main/java/org/alliancegenome/curation_api/services/CodingSequenceService.java new file mode 100644 index 000000000..879737409 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/CodingSequenceService.java @@ -0,0 +1,54 @@ +package org.alliancegenome.curation_api.services; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.alliancegenome.curation_api.constants.EntityFieldConstants; +import org.alliancegenome.curation_api.dao.CodingSequenceDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.model.entities.CodingSequence; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; +import org.alliancegenome.curation_api.services.validation.dto.Gff3DtoValidator; +import org.apache.commons.lang.StringUtils; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; + +@RequestScoped +public class CodingSequenceService extends BaseEntityCrudService { + + @Inject CodingSequenceDAO codingSequenceDAO; + @Inject PersonService personService; + @Inject Gff3DtoValidator gff3DtoValidator; + + @Override + @PostConstruct + protected void init() { + setSQLDao(codingSequenceDAO); + } + + public List getIdsByDataProvider(BackendBulkDataProvider dataProvider) { + Map params = new HashMap<>(); + params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider.sourceOrganization); + if (StringUtils.equals(dataProvider.sourceOrganization, "RGD")) { + params.put(EntityFieldConstants.TAXON, dataProvider.canonicalTaxonCurie); + } + List ids = codingSequenceDAO.findIdsByParams(params); + ids.removeIf(Objects::isNull); + return ids; + } + + public ObjectResponse deleteByIdentifier(String identifierString) { + CodingSequence codingSequence = findByAlternativeFields(List.of("modEntityId", "modInternalId", "uniqueId"), identifierString); + if (codingSequence != null) { + codingSequenceDAO.remove(codingSequence.getId()); + } + ObjectResponse ret = new ObjectResponse<>(codingSequence); + return ret; + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/ExonService.java b/src/main/java/org/alliancegenome/curation_api/services/ExonService.java index 7eea708d8..f65601743 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/ExonService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/ExonService.java @@ -9,8 +9,8 @@ import org.alliancegenome.curation_api.dao.ExonDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.model.entities.Exon; +import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; -import org.alliancegenome.curation_api.services.validation.dto.Gff3DtoValidator; import org.apache.commons.lang.StringUtils; import jakarta.annotation.PostConstruct; @@ -22,7 +22,6 @@ public class ExonService extends BaseEntityCrudService { @Inject ExonDAO exonDAO; @Inject PersonService personService; - @Inject Gff3DtoValidator gff3DtoValidator; @Override @PostConstruct @@ -41,4 +40,12 @@ public List getIdsByDataProvider(BackendBulkDataProvider dataProvider) { return ids; } + public ObjectResponse deleteByIdentifier(String identifierString) { + Exon exon = findByAlternativeFields(List.of("modEntityId", "modInternalId", "uniqueId"), identifierString); + if (exon != null) { + exonDAO.remove(exon.getId()); + } + ObjectResponse ret = new ObjectResponse<>(exon); + return ret; + } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java index 128e96939..239018516 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java +++ b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java @@ -11,13 +11,16 @@ import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; import org.alliancegenome.curation_api.exceptions.ObjectValidationException; +import org.alliancegenome.curation_api.model.entities.CodingSequence; +import org.alliancegenome.curation_api.model.entities.Exon; import org.alliancegenome.curation_api.model.entities.GenomeAssembly; +import org.alliancegenome.curation_api.model.entities.Transcript; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; import org.alliancegenome.curation_api.response.SearchResponse; import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; -import org.apache.commons.codec.binary.StringUtils; -import org.apache.commons.collections.CollectionUtils; +import org.alliancegenome.curation_api.services.validation.dto.Gff3DtoValidator; +import org.apache.commons.lang3.StringUtils; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @@ -29,63 +32,65 @@ public class Gff3Service { @Inject GenomeAssemblyDAO genomeAssemblyDAO; @Inject DataProviderService dataProviderService; @Inject NcbiTaxonTermService ncbiTaxonTermService; + @Inject Gff3DtoValidator gff3DtoValidator; @Transactional - public GenomeAssembly loadGenomeAssembly(List gffHeaderData, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { + public GenomeAssembly loadGenomeAssembly(String assemblyName, List gffHeaderData, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { - for (String header : gffHeaderData) { - if (header.startsWith("#!assembly")) { - String assemblyName = header.split(" ")[1]; - Map params = new HashMap<>(); - params.put("modEntityId", assemblyName); - params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider.sourceOrganization); - params.put(EntityFieldConstants.TAXON, dataProvider.canonicalTaxonCurie); - - SearchResponse resp = genomeAssemblyDAO.findByParams(params); - if (resp != null && resp.getSingleResult() != null) { - return resp.getSingleResult(); + if (StringUtils.isBlank(assemblyName)) { + for (String header : gffHeaderData) { + if (header.startsWith("#!assembly")) { + assemblyName = header.split(" ")[1]; } + } + } + if (StringUtils.isNotBlank(assemblyName)) { + Map params = new HashMap<>(); + params.put("modEntityId", assemblyName); + params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider.sourceOrganization); + params.put(EntityFieldConstants.TAXON, dataProvider.canonicalTaxonCurie); + + SearchResponse resp = genomeAssemblyDAO.findByParams(params); + if (resp != null && resp.getSingleResult() != null) { + return resp.getSingleResult(); + } - GenomeAssembly assembly = new GenomeAssembly(); - assembly.setModEntityId(assemblyName); - assembly.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProvider.sourceOrganization)); - assembly.setTaxon(ncbiTaxonTermService.getByCurie(dataProvider.canonicalTaxonCurie).getEntity()); + GenomeAssembly assembly = new GenomeAssembly(); + assembly.setModEntityId(assemblyName); + assembly.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProvider.sourceOrganization)); + assembly.setTaxon(ncbiTaxonTermService.getByCurie(dataProvider.canonicalTaxonCurie).getEntity()); - return genomeAssemblyDAO.persist(assembly); - } + return genomeAssemblyDAO.persist(assembly); } throw new ObjectValidationException(gffHeaderData, "#!assembly - " + ValidationConstants.REQUIRED_MESSAGE); } - public Map> loadEntities(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { - Map attributes = getAttributes(gffEntry); + public Map> loadEntity(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { if (StringUtils.equals(gffEntry.getType(), "exon")) { - + Exon exon = gff3DtoValidator.validateExonEntry(gffEntry, dataProvider); + if (exon != null) { + idsAdded.get("Exon").add(exon.getId()); + } } else if (StringUtils.equals(gffEntry.getType(), "CDS")) { - + CodingSequence cds = gff3DtoValidator.validateCdsEntry(gffEntry, dataProvider); + if (cds != null) { + idsAdded.get("CodingSequence").add(cds.getId()); + } } else if (Gff3Constants.TRANSCRIPT_TYPES.contains(gffEntry.getType())) { if (StringUtils.equals(gffEntry.getType(), "lnc_RNA")) { gffEntry.setType("lncRNA"); } + Transcript transcript = gff3DtoValidator.validateTranscriptEntry(gffEntry, dataProvider); + if (transcript != null) { + idsAdded.get("Transcript").add(transcript.getId()); + } } return idsAdded; } - public Map> loadAssociations(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider, GenomeAssembly assembly) throws ObjectUpdateException { + public Map> loadAssociation(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider, GenomeAssembly assembly) throws ObjectUpdateException { // TODO: implement association loading return idsAdded; } - private Map getAttributes (Gff3DTO gffEntry) { - Map attributes = new HashMap(); - if (CollectionUtils.isNotEmpty(gffEntry.getAttributes())) { - for (String keyValue : gffEntry.getAttributes()) { - String[] parts = keyValue.split("="); - if (parts.length == 2) { - attributes.put(parts[0], parts[1]); - } - } - } - return attributes; - } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/TranscriptService.java b/src/main/java/org/alliancegenome/curation_api/services/TranscriptService.java new file mode 100644 index 000000000..9cf7b422b --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/TranscriptService.java @@ -0,0 +1,61 @@ +package org.alliancegenome.curation_api.services; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.alliancegenome.curation_api.constants.EntityFieldConstants; +import org.alliancegenome.curation_api.dao.TranscriptDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.model.entities.Transcript; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; +import org.alliancegenome.curation_api.services.validation.dto.Gff3DtoValidator; +import org.apache.commons.lang.StringUtils; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; + +@RequestScoped +public class TranscriptService extends BaseEntityCrudService { + + @Inject TranscriptDAO transcriptDAO; + @Inject PersonService personService; + @Inject Gff3DtoValidator gff3DtoValidator; + + @Override + @PostConstruct + protected void init() { + setSQLDao(transcriptDAO); + } + + public List getIdsByDataProvider(BackendBulkDataProvider dataProvider) { + Map params = new HashMap<>(); + params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider.sourceOrganization); + if (StringUtils.equals(dataProvider.sourceOrganization, "RGD")) { + params.put(EntityFieldConstants.TAXON, dataProvider.canonicalTaxonCurie); + } + List ids = transcriptDAO.findIdsByParams(params); + ids.removeIf(Objects::isNull); + return ids; + } + + @Override + public ObjectResponse getByIdentifier(String identifier) { + Transcript object = findByAlternativeFields(List.of("curie", "modEntityId", "modInternalId"), identifier); + ObjectResponse ret = new ObjectResponse(object); + return ret; + } + + public ObjectResponse deleteByIdentifier(String identifierString) { + Transcript transcript = findByAlternativeFields(List.of("modEntityId", "modInternalId"), identifierString); + if (transcript != null) { + transcriptDAO.remove(transcript.getId()); + } + ObjectResponse ret = new ObjectResponse<>(transcript); + return ret; + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/helpers/UniqueIdGeneratorHelper.java b/src/main/java/org/alliancegenome/curation_api/services/helpers/UniqueIdGeneratorHelper.java index 750ea1cc1..e560038b0 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/helpers/UniqueIdGeneratorHelper.java +++ b/src/main/java/org/alliancegenome/curation_api/services/helpers/UniqueIdGeneratorHelper.java @@ -26,6 +26,12 @@ public boolean add(String s) { } return false; } + + public void add(Integer i) { + if (i != null) { + add(Integer.toString(i)); + } + } public void addList(List list) { if (CollectionUtils.isNotEmpty(list)) { diff --git a/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3UniqueIdHelper.java b/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3UniqueIdHelper.java new file mode 100644 index 000000000..bd250dcc0 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3UniqueIdHelper.java @@ -0,0 +1,46 @@ +package org.alliancegenome.curation_api.services.helpers.gff3; + +import java.util.Map; + +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.alliancegenome.curation_api.services.helpers.UniqueIdGeneratorHelper; +import org.apache.commons.lang3.StringUtils; + +import jakarta.enterprise.context.RequestScoped; + +@RequestScoped +public class Gff3UniqueIdHelper { + + public static String getExonOrCodingSequenceUniqueId(Gff3DTO dto, Map attributes, BackendBulkDataProvider dataProvider) { + UniqueIdGeneratorHelper uniqueId = new UniqueIdGeneratorHelper(); + + if (attributes.containsKey("ID")) { + uniqueId.add(removeWormBasePrefix(attributes.get("ID"), dataProvider)); + } else if (attributes.containsKey("Name")) { + uniqueId.add(attributes.get("Name")); + } + + if (attributes.containsKey("Parent")) { + uniqueId.add(removeWormBasePrefix(attributes.get("Parent"), dataProvider)); + } + + uniqueId.add(dto.getSeqId()); + uniqueId.add(dto.getStart()); + uniqueId.add(dto.getEnd()); + uniqueId.add(dto.getStrand()); + + return uniqueId.getUniqueId(); + } + + private static String removeWormBasePrefix(String id, BackendBulkDataProvider dataProvider) { + if (StringUtils.equals("WB", dataProvider.sourceOrganization)) { + String[] idParts = id.split(":"); + if (idParts.length > 1) { + id = idParts[1]; + } + } + return id; + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java index 550765199..dd68f8cc3 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -7,16 +7,20 @@ import org.alliancegenome.curation_api.dao.CodingSequenceDAO; import org.alliancegenome.curation_api.dao.ExonDAO; import org.alliancegenome.curation_api.dao.TranscriptDAO; +import org.alliancegenome.curation_api.dao.ontology.SoTermDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectValidationException; +import org.alliancegenome.curation_api.model.entities.CodingSequence; import org.alliancegenome.curation_api.model.entities.Exon; import org.alliancegenome.curation_api.model.entities.GenomicEntity; +import org.alliancegenome.curation_api.model.entities.Transcript; +import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.response.SearchResponse; import org.alliancegenome.curation_api.services.DataProviderService; +import org.alliancegenome.curation_api.services.helpers.gff3.Gff3UniqueIdHelper; import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; -import org.alliancegenome.curation_api.services.validation.dto.base.BaseDTOValidator; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -25,49 +29,133 @@ import jakarta.transaction.Transactional; @RequestScoped -public class Gff3DtoValidator extends BaseDTOValidator { +public class Gff3DtoValidator { @Inject ExonDAO exonDAO; @Inject TranscriptDAO transcriptDAO; @Inject CodingSequenceDAO codingSequenceDAO; @Inject DataProviderService dataProviderService; @Inject NcbiTaxonTermService ncbiTaxonTermService; + @Inject SoTermDAO soTermDAO; - private ObjectResponse exonResponse; - @Transactional public Exon validateExonEntry(Gff3DTO dto, BackendBulkDataProvider dataProvider) throws ObjectValidationException { - exonResponse = new ObjectResponse<>(); + Exon exon = null; + + Map attributes = getAttributes(dto); + String uniqueId = Gff3UniqueIdHelper.getExonOrCodingSequenceUniqueId(dto, attributes, dataProvider); + SearchResponse searchResponse = exonDAO.findByField("uniqueId", uniqueId); + if (searchResponse != null && searchResponse.getSingleResult() != null) { + exon = searchResponse.getSingleResult(); + } else { + exon = new Exon(); + exon.setUniqueId(uniqueId); + } + + if (attributes.containsKey("Name")) { + exon.setName(attributes.get("Name")); + } + + ObjectResponse exonResponse = validateGffEntity(exon, dto, attributes, dataProvider); + + if (exonResponse.hasErrors()) { + throw new ObjectValidationException(dto, exonResponse.errorMessagesString()); + } + + return exonDAO.persist(exonResponse.getEntity()); + } + + @Transactional + public CodingSequence validateCdsEntry(Gff3DTO dto, BackendBulkDataProvider dataProvider) throws ObjectValidationException { - Exon exon = new Exon(); - if (StringUtils.isNotBlank(dto.getSeqId())) { - SearchResponse exonResponse = exonDAO.findByField("modEntityId", dto.getSeqId()); - if (exonResponse != null && exonResponse.getSingleResult() != null) { - exon = exonResponse.getSingleResult(); - } + CodingSequence cds = null; + + Map attributes = getAttributes(dto); + String uniqueId = Gff3UniqueIdHelper.getExonOrCodingSequenceUniqueId(dto, attributes, dataProvider); + SearchResponse searchResponse = codingSequenceDAO.findByField("uniqueId", uniqueId); + if (searchResponse != null && searchResponse.getSingleResult() != null) { + cds = searchResponse.getSingleResult(); + } else { + cds = new CodingSequence(); + cds.setUniqueId(uniqueId); + } + + if (attributes.containsKey("Name")) { + cds.setName(attributes.get("Name")); } - ObjectResponse geResponse = validateGffEntry(exon, dto, dataProvider); + ObjectResponse cdsResponse = validateGffEntity(cds, dto, attributes, dataProvider); + + if (cdsResponse.hasErrors()) { + throw new ObjectValidationException(dto, cdsResponse.errorMessagesString()); + } + return codingSequenceDAO.persist(cdsResponse.getEntity()); + } + + @Transactional + public Transcript validateTranscriptEntry(Gff3DTO dto, BackendBulkDataProvider dataProvider) throws ObjectValidationException { + Transcript transcript = null; + + Map attributes = getAttributes(dto); + if (attributes.containsKey("ID")) { + SearchResponse searchResponse = transcriptDAO.findByField("modInternalId", attributes.get("ID")); + if (searchResponse != null && searchResponse.getSingleResult() != null) { + transcript = searchResponse.getSingleResult(); + } else { + transcript = new Transcript(); + } + } + + SearchResponse soResponse = soTermDAO.findByField("name", dto.getType()); + if (soResponse != null) { + transcript.setTranscriptType(soResponse.getSingleResult()); + } + + if (attributes.containsKey("Name")) { + transcript.setName(attributes.get("Name")); + } - return exonDAO.persist(exon); + ObjectResponse transcriptResponse = validateGffEntity(transcript, dto, attributes, dataProvider); + if (!attributes.containsKey("ID")) { + transcriptResponse.addErrorMessage("attributes - ID", ValidationConstants.REQUIRED_MESSAGE); + } + + if (transcriptResponse.hasErrors()) { + throw new ObjectValidationException(dto, transcriptResponse.errorMessagesString()); + } + + return transcriptDAO.persist(transcriptResponse.getEntity()); } - private ObjectResponse validateGffEntry(E entity, Gff3DTO dto, BackendBulkDataProvider dataProvider) { + private ObjectResponse validateGffEntity(E entity, Gff3DTO dto, Map attributes, BackendBulkDataProvider dataProvider) { ObjectResponse geResponse = new ObjectResponse(); - if (StringUtils.isBlank(dto.getSeqId())) { - geResponse.addErrorMessage("seqId", ValidationConstants.REQUIRED_MESSAGE); + if (attributes.containsKey("ID")) { + String id = attributes.get("ID"); + if (StringUtils.equals(dataProvider.sourceOrganization, "WB")) { + String[] idParts = id.split(":"); + if (idParts.length > 1) { + id = idParts[1]; + } + } + entity.setModInternalId(id); + } else if (attributes.containsKey("exon_id")) { + entity.setModInternalId(attributes.get("exon_id")); + } else if (attributes.containsKey("transcript_id")) { + entity.setModInternalId(attributes.get("transcript_id")); + } + + if (attributes.containsKey("curie")) { + entity.setModEntityId(attributes.get("curie")); } - entity.setModEntityId(dto.getSeqId()); entity.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProvider.sourceOrganization)); entity.setTaxon(ncbiTaxonTermService.getByCurie(dataProvider.canonicalTaxonCurie).getEntity()); - - Map attributes = getAttributes(dto); + geResponse.setEntity(entity); return geResponse; } diff --git a/src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql b/src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql new file mode 100644 index 000000000..84aad7534 --- /dev/null +++ b/src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql @@ -0,0 +1,101 @@ +CREATE TABLE transcript ( + id bigint NOT NULL, + transcripttype_id bigint, + name varchar(255) +); +ALTER TABLE transcript ADD CONSTRAINT transcript_pkey PRIMARY KEY (id); +ALTER TABLE transcript + ADD CONSTRAINT transcript_id_fk FOREIGN KEY (id) REFERENCES genomicentity(id); +ALTER TABLE transcript + ADD CONSTRAINT transcript_transcripttype_id_fk FOREIGN KEY (transcripttype_id) REFERENCES ontologyterm(id); + +CREATE TABLE exon ( + id bigint NOT NULL, + exontype_id bigint, + name varchar(255), + uniqueid varchar(255) +); +ALTER TABLE exon ADD CONSTRAINT exon_pkey PRIMARY KEY (id); +ALTER TABLE exon + ADD CONSTRAINT exon_id_fk FOREIGN KEY (id) REFERENCES genomicentity(id); +ALTER TABLE exon + ADD CONSTRAINT exon_exontype_id_fk FOREIGN KEY (exontype_id) REFERENCES ontologyterm(id); +CREATE INDEX exon_uniqueid_index ON exon USING btree (uniqueid); + +CREATE TABLE codingsequence ( + id bigint NOT NULL, + cdstype_id bigint, + name varchar(255), + uniqueid varchar(255) +); +ALTER TABLE codingsequence ADD CONSTRAINT codingsequence_pkey PRIMARY KEY (id); +ALTER TABLE codingsequence + ADD CONSTRAINT codingsequence_id_fk FOREIGN KEY (id) REFERENCES genomicentity(id); +ALTER TABLE codingsequence + ADD CONSTRAINT codingsequence_cdstype_id_fk FOREIGN KEY (cdstype_id) REFERENCES ontologyterm(id); +CREATE INDEX codingsequence_uniqueid_index ON codingsequence USING btree (uniqueid); + +CREATE TABLE genomeassembly ( + id bigint NOT NULL, + specimengenomicmodel_id bigint +); +ALTER TABLE genomeassembly ADD CONSTRAINT genomeassembly_pkey PRIMARY KEY (id); +ALTER TABLE genomeassembly + ADD CONSTRAINT genomeassembly_id_fk FOREIGN KEY (id) REFERENCES biologicalentity(id); +ALTER TABLE genomeassembly + ADD CONSTRAINT genomeassembly_specimengenomicmodel_id_fk FOREIGN KEY (specimengenomicmodel_id) REFERENCES affectedgenomicmodel(id); + +CREATE TABLE genomeassembly_crossreference ( + genomeassembly_id bigint NOT NULL, + crossreferences_id bigint NOT NULL +); +ALTER TABLE genomeassembly_crossreference + ADD CONSTRAINT genomeassembly_crossreference_genomeassembly_id_fk FOREIGN KEY (genomeassembly_id) REFERENCES genomeassembly(id); +ALTER TABLE genomeassembly_crossreference + ADD CONSTRAINT genomeassembly_crossreference_crossreferences_id_fk FOREIGN KEY (crossreferences_id) REFERENCES crossreference(id); +CREATE INDEX genomeassembly_crossreference_genomeassembly_xref_index ON genomeassembly_crossreference USING btree(genomeassembly_id, crossreferences_id); +CREATE INDEX genomeassembly_crossreference_genomeassembly_index ON genomeassembly_crossreference USING btree(genomeassembly_id); +CREATE INDEX genomeassembly_crossreference_crossreference_index ON genomeassembly_crossreference USING btree(crossreferences_id); + +INSERT INTO bulkloadgroup (id, name) VALUES (nextval('bulkloadgroup_seq'), 'GFF Loads'); + +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'FB GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'Human GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'MGI GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'RGD GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'WGD GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'WB GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'XBXL GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'XBXT GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'ZFIN GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; + +INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) + SELECT id, '0 0 22 ? * SUN-THU', false FROM bulkload WHERE backendbulkloadtype = 'GFF'; + +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'FB' FROM bulkload WHERE name = 'FB GFF Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'HUMAN' FROM bulkload WHERE name = 'HUMAN GFF Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'MGI' FROM bulkload WHERE name = 'MGI GFF Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'RGD' FROM bulkload WHERE name = 'RGD GFF Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'SGD' FROM bulkload WHERE name = 'SGD GFF Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'WB' FROM bulkload WHERE name = 'WB GFF Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'XBXL' FROM bulkload WHERE name = 'XBXL GFF Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'XBXT' FROM bulkload WHERE name = 'XBXT GFF Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'ZFIN' FROM bulkload WHERE name = 'ZFIN GFF Load'; \ No newline at end of file diff --git a/src/test/java/org/alliancegenome/curation_api/AlleleITCase.java b/src/test/java/org/alliancegenome/curation_api/AlleleITCase.java index 79c7b126f..0eefb703a 100644 --- a/src/test/java/org/alliancegenome/curation_api/AlleleITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/AlleleITCase.java @@ -182,7 +182,7 @@ private void loadRequiredEntities() { datetime2 = OffsetDateTime.parse("2022-04-10T22:10:11+00:00"); soTerm = getSoTerm("SO:00001"); soTerm2 = getSoTerm("SO:00002"); - obsoleteSoTerm = createSoTerm("SO:00000", true); + obsoleteSoTerm = createSoTerm("SO:00000", "obsoleteTest", true); mpTerm = getMpTerm("MP:00001"); mpTerm2 = getMpTerm("MP:00002"); obsoleteMpTerm = createMpTerm("MP:00000", true); diff --git a/src/test/java/org/alliancegenome/curation_api/GeneITCase.java b/src/test/java/org/alliancegenome/curation_api/GeneITCase.java index f13fabd51..dbda64419 100644 --- a/src/test/java/org/alliancegenome/curation_api/GeneITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/GeneITCase.java @@ -84,9 +84,9 @@ public class GeneITCase extends BaseITCase { private void loadRequiredEntities() { - soTerm = createSoTerm("SO:0001", false); - soTerm2 = createSoTerm("SO:0002", false); - obsoleteSoTerm = createSoTerm("SO:0000", true); + soTerm = createSoTerm("SO:0001", "test1", false); + soTerm2 = createSoTerm("SO:0002", "test2", false); + obsoleteSoTerm = createSoTerm("SO:0000", "testObsolete", true); nameType = getVocabulary(VocabularyConstants.NAME_TYPE_VOCABULARY); synonymScope = getVocabulary(VocabularyConstants.SYNONYM_SCOPE_VOCABULARY); symbolNameType = getVocabularyTerm(nameType, "nomenclature_symbol"); diff --git a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadFmsITCase.java b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadFmsITCase.java new file mode 100644 index 000000000..0e543e776 --- /dev/null +++ b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadFmsITCase.java @@ -0,0 +1,107 @@ +package org.alliancegenome.curation_api; + +import static org.hamcrest.Matchers.is; + +import org.alliancegenome.curation_api.base.BaseITCase; +import org.alliancegenome.curation_api.resources.TestContainerResource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestMethodOrder; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import io.restassured.RestAssured; +import io.restassured.config.HttpClientConfig; +import io.restassured.config.RestAssuredConfig; + +@QuarkusIntegrationTest +@QuarkusTestResource(TestContainerResource.Initializer.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@DisplayName("608 - GFF data bulk upload - FMS") +@Order(608) +public class Gff3BulkUploadFmsITCase extends BaseITCase { + + @BeforeEach + public void init() { + RestAssured.config = RestAssuredConfig.config() + .httpClient(HttpClientConfig.httpClientConfig() + .setParam("http.socket.timeout", 100000) + .setParam("http.connection.timeout", 100000)); + } + + private final String transcriptBulkPostEndpoint = "/api/transcript/bulk/WB_WBcel235/transcripts"; + private final String exonBulkPostEndpoint = "/api/exon/bulk/WB_WBcel235/exons"; + private final String cdsBulkPostEndpoint = "/api/cds/bulk/WB_WBcel235/codingSequences"; + private final String gffDataTestFilePath = "src/test/resources/bulk/fms/08_gff_data/"; + private final String transcriptGetEndpoint = "/api/transcript/"; + private final String exonGetEndpoint = "/api/exon/"; + private final String cdsGetEndpoint = "/api/cds/"; + private final String transcriptId = "Y74C9A.2a.1"; + private final String exonId = "Y74C9A.2a_exon"; + private final String cdsId = "Y74C9A.2a"; + + private void loadRequiredEntities() throws Exception { + createSoTerm("SO:0000234", "mRNA", false); + createSoTerm("SO:0000147", "exon", false); + createSoTerm("SO:0000316", "CDS", false); + } + + @Test + @Order(1) + public void gff3DataBulkUploadTranscriptEntity() throws Exception { + loadRequiredEntities(); + + checkSuccessfulBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "GFF01_transcript.json", 3); + + RestAssured.given(). + when(). + get(transcriptGetEndpoint + transcriptId). + then(). + statusCode(200). + body("entity.modInternalId", is(transcriptId)). + body("entity.taxon.curie", is("NCBITaxon:6239")). + body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")). + body("entity.transcriptType.curie", is("SO:0000234")); + + } + + @Test + @Order(2) + public void gff3DataBulkUploadExonEntity() throws Exception { + checkSuccessfulBulkLoad(exonBulkPostEndpoint, gffDataTestFilePath + "GFF02_exon.json", 3); + + RestAssured.given(). + when(). + get(exonGetEndpoint + exonId). + then(). + statusCode(200). + body("entity.modInternalId", is(exonId)). + body("entity.uniqueId", is("Y74C9A.2a_exon|Y74C9A.2a.1|I|1|100|+")). + body("entity.taxon.curie", is("NCBITaxon:6239")). + body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")); + + } + + @Test + @Order(2) + public void gff3DataBulkUploadCodingSequenceEntity() throws Exception { + checkSuccessfulBulkLoad(cdsBulkPostEndpoint, gffDataTestFilePath + "GFF03_CDS.json", 3); + + RestAssured.given(). + when(). + get(cdsGetEndpoint + cdsId). + then(). + statusCode(200). + body("entity.modInternalId", is(cdsId)). + body("entity.uniqueId", is("Y74C9A.2a|Y74C9A.2a.1|I|10|100|+")). + body("entity.taxon.curie", is("NCBITaxon:6239")). + body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")); + + } + +} diff --git a/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java b/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java index f6ea383bf..f03086b3b 100644 --- a/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java @@ -1,13 +1,56 @@ package org.alliancegenome.curation_api.base; -import io.restassured.RestAssured; -import io.restassured.common.mapper.TypeRef; +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.is; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + import org.alliancegenome.curation_api.constants.OntologyConstants; import org.alliancegenome.curation_api.constants.VocabularyConstants; -import org.alliancegenome.curation_api.model.entities.*; +import org.alliancegenome.curation_api.model.entities.AGMDiseaseAnnotation; +import org.alliancegenome.curation_api.model.entities.AGMPhenotypeAnnotation; +import org.alliancegenome.curation_api.model.entities.AffectedGenomicModel; +import org.alliancegenome.curation_api.model.entities.Allele; +import org.alliancegenome.curation_api.model.entities.AlleleDiseaseAnnotation; +import org.alliancegenome.curation_api.model.entities.AllelePhenotypeAnnotation; +import org.alliancegenome.curation_api.model.entities.BiologicalEntity; +import org.alliancegenome.curation_api.model.entities.ConditionRelation; +import org.alliancegenome.curation_api.model.entities.Construct; +import org.alliancegenome.curation_api.model.entities.CrossReference; +import org.alliancegenome.curation_api.model.entities.DataProvider; +import org.alliancegenome.curation_api.model.entities.ExperimentalCondition; +import org.alliancegenome.curation_api.model.entities.Gene; +import org.alliancegenome.curation_api.model.entities.GeneDiseaseAnnotation; +import org.alliancegenome.curation_api.model.entities.Note; +import org.alliancegenome.curation_api.model.entities.Organization; +import org.alliancegenome.curation_api.model.entities.Person; +import org.alliancegenome.curation_api.model.entities.Reference; +import org.alliancegenome.curation_api.model.entities.ResourceDescriptor; +import org.alliancegenome.curation_api.model.entities.ResourceDescriptorPage; +import org.alliancegenome.curation_api.model.entities.Variant; +import org.alliancegenome.curation_api.model.entities.Vocabulary; +import org.alliancegenome.curation_api.model.entities.VocabularyTerm; +import org.alliancegenome.curation_api.model.entities.VocabularyTermSet; import org.alliancegenome.curation_api.model.entities.associations.alleleAssociations.AlleleGeneAssociation; import org.alliancegenome.curation_api.model.entities.associations.constructAssociations.ConstructGenomicEntityAssociation; -import org.alliancegenome.curation_api.model.entities.ontology.*; +import org.alliancegenome.curation_api.model.entities.ontology.AnatomicalTerm; +import org.alliancegenome.curation_api.model.entities.ontology.CHEBITerm; +import org.alliancegenome.curation_api.model.entities.ontology.ChemicalTerm; +import org.alliancegenome.curation_api.model.entities.ontology.DOTerm; +import org.alliancegenome.curation_api.model.entities.ontology.ECOTerm; +import org.alliancegenome.curation_api.model.entities.ontology.ExperimentalConditionOntologyTerm; +import org.alliancegenome.curation_api.model.entities.ontology.GOTerm; +import org.alliancegenome.curation_api.model.entities.ontology.MITerm; +import org.alliancegenome.curation_api.model.entities.ontology.MPTerm; +import org.alliancegenome.curation_api.model.entities.ontology.NCBITaxonTerm; +import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; +import org.alliancegenome.curation_api.model.entities.ontology.WBPhenotypeTerm; +import org.alliancegenome.curation_api.model.entities.ontology.ZECOTerm; +import org.alliancegenome.curation_api.model.entities.ontology.ZFATerm; import org.alliancegenome.curation_api.model.entities.slotAnnotations.alleleSlotAnnotations.AlleleSymbolSlotAnnotation; import org.alliancegenome.curation_api.model.entities.slotAnnotations.constructSlotAnnotations.ConstructSymbolSlotAnnotation; import org.alliancegenome.curation_api.model.entities.slotAnnotations.geneSlotAnnotations.GeneSymbolSlotAnnotation; @@ -16,14 +59,8 @@ import org.alliancegenome.curation_api.response.SearchResponse; import org.apache.commons.lang3.StringUtils; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.Matchers.is; +import io.restassured.RestAssured; +import io.restassured.common.mapper.TypeRef; public class BaseITCase { @@ -485,9 +522,10 @@ public ResourceDescriptorPage createResourceDescriptorPage(String name, String u return response.getEntity(); } - public SOTerm createSoTerm(String curie, Boolean obsolete) { + public SOTerm createSoTerm(String curie, String name, Boolean obsolete) { SOTerm term = new SOTerm(); term.setCurie(curie); + term.setName(name); term.setObsolete(obsolete); term.setSecondaryIdentifiers(List.of(curie + "secondary")); diff --git a/src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json b/src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json new file mode 100644 index 000000000..bd1d4ecfc --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json @@ -0,0 +1,14 @@ +[ + { + "seqId": "I", + "source": "WormBase", + "type": "mRNA", + "start": 1, + "end": 1000, + "strand": "+", + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/GFF02_exon.json b/src/test/resources/bulk/fms/08_gff_data/GFF02_exon.json new file mode 100644 index 000000000..06b8abf5c --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/GFF02_exon.json @@ -0,0 +1,14 @@ +[ + { + "seqId": "I", + "source": "WormBase", + "type": "exon", + "start": 1, + "end": 100, + "strand": "+", + "attributes": [ + "ID=Exon:Y74C9A.2a_exon", + "Parent=Transcript:Y74C9A.2a.1" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json b/src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json new file mode 100644 index 000000000..75fbd719f --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json @@ -0,0 +1,14 @@ +[ + { + "seqId": "I", + "source": "WormBase", + "type": "CDS", + "start": 10, + "end": 100, + "strand": "+", + "attributes": [ + "ID=CDS:Y74C9A.2a", + "Parent=Transcript:Y74C9A.2a.1" + ] + } +] From 90efffbf1e1ff81b8e8f2af2e1cc803835bc23e2 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 09:13:29 +0100 Subject: [PATCH 03/82] Executor fixes --- .../curation_api/jobs/executors/BulkLoadJobExecutor.java | 3 +++ .../curation_api/jobs/executors/Gff3Executor.java | 4 ++-- .../resources/db/migration/v0.35.0.9__gff_entity_tables.sql | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/BulkLoadJobExecutor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/BulkLoadJobExecutor.java index 64766dd12..2c1728e20 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/BulkLoadJobExecutor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/BulkLoadJobExecutor.java @@ -51,6 +51,7 @@ public class BulkLoadJobExecutor { @Inject ParalogyExecutor paralogyExecutor; @Inject GeneExpressionExecutor geneExpressionExecutor; @Inject SequenceTargetingReagentExecutor sqtrExecutor; + @Inject Gff3Executor gff3Executor; public void process(BulkLoadFile bulkLoadFile, Boolean cleanUp) throws Exception { @@ -114,6 +115,8 @@ public void process(BulkLoadFile bulkLoadFile, Boolean cleanUp) throws Exception resourceDescriptorExecutor.execLoad(bulkLoadFile); } else if (bulkLoadFile.getBulkLoad().getBackendBulkLoadType() == BackendBulkLoadType.EXPRESSION) { geneExpressionExecutor.execLoad(bulkLoadFile); + } else if (bulkLoadFile.getBulkLoad().getBackendBulkLoadType() == BackendBulkLoadType.GFF) { + gff3Executor.execLoad(bulkLoadFile); } else { log.info("Load: " + bulkLoadFile.getBulkLoad().getName() + " not implemented"); throw new Exception("Load: " + bulkLoadFile.getBulkLoad().getName() + " not implemented"); diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java index 06db63852..f0a33a8e5 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java @@ -48,9 +48,9 @@ public class Gff3Executor extends LoadFileExecutor { public void execLoad(BulkLoadFile bulkLoadFile) { try { - CsvSchema psiMiTabSchema = CsvSchemaBuilder.gff3Schema(); + CsvSchema gff3Schema = CsvSchemaBuilder.gff3Schema(); CsvMapper csvMapper = new CsvMapper(); - MappingIterator it = csvMapper.enable(CsvParser.Feature.INSERT_NULLS_FOR_MISSING_COLUMNS).readerFor(PsiMiTabDTO.class).with(psiMiTabSchema).readValues(new GZIPInputStream(new FileInputStream(bulkLoadFile.getLocalFilePath()))); + MappingIterator it = csvMapper.enable(CsvParser.Feature.INSERT_NULLS_FOR_MISSING_COLUMNS).readerFor(Gff3DTO.class).with(gff3Schema).readValues(new GZIPInputStream(new FileInputStream(bulkLoadFile.getLocalFilePath()))); List gffData = it.readAll(); List gffHeaderData = new ArrayList<>(); for (Gff3DTO gffLine : gffData) { diff --git a/src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql b/src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql index 84aad7534..7347d43ec 100644 --- a/src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql +++ b/src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql @@ -57,6 +57,8 @@ CREATE INDEX genomeassembly_crossreference_genomeassembly_xref_index ON genomeas CREATE INDEX genomeassembly_crossreference_genomeassembly_index ON genomeassembly_crossreference USING btree(genomeassembly_id); CREATE INDEX genomeassembly_crossreference_crossreference_index ON genomeassembly_crossreference USING btree(crossreferences_id); + +/* INSERT INTO bulkloadgroup (id, name) VALUES (nextval('bulkloadgroup_seq'), 'GFF Loads'); INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) @@ -98,4 +100,5 @@ INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) SELECT id, 'GFF', 'XBXT' FROM bulkload WHERE name = 'XBXT GFF Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) - SELECT id, 'GFF', 'ZFIN' FROM bulkload WHERE name = 'ZFIN GFF Load'; \ No newline at end of file + SELECT id, 'GFF', 'ZFIN' FROM bulkload WHERE name = 'ZFIN GFF Load'; +*/ \ No newline at end of file From e6415fc2e1ee847c8e8d971f76d9f256c8b5a9f7 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 09:27:16 +0100 Subject: [PATCH 04/82] Bump migration version no. --- ...9__gff_entity_tables.sql => v0.35.0.10__gff_entity_tables.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{v0.35.0.9__gff_entity_tables.sql => v0.35.0.10__gff_entity_tables.sql} (100%) diff --git a/src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql b/src/main/resources/db/migration/v0.35.0.10__gff_entity_tables.sql similarity index 100% rename from src/main/resources/db/migration/v0.35.0.9__gff_entity_tables.sql rename to src/main/resources/db/migration/v0.35.0.10__gff_entity_tables.sql From 1ad8669914888b2c587a7b7cbdea334d8fe3da0f Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 11:33:48 +0100 Subject: [PATCH 05/82] Change ID handling --- .../jobs/executors/Gff3Executor.java | 2 +- .../helpers/gff3/Gff3UniqueIdHelper.java | 21 ++++------ .../validation/dto/Gff3DtoValidator.java | 39 ++++++++++--------- ...sITCase.java => Gff3BulkUploadITCase.java} | 16 ++++---- 4 files changed, 35 insertions(+), 43 deletions(-) rename src/test/java/org/alliancegenome/curation_api/{Gff3BulkUploadFmsITCase.java => Gff3BulkUploadITCase.java} (88%) diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java index f0a33a8e5..134eba67f 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java @@ -60,7 +60,7 @@ public void execLoad(BulkLoadFile bulkLoadFile) { break; } } - gffData.subList(0, gffHeaderData.size() - 1).clear(); + gffData.subList(0, gffHeaderData.size()).clear(); BulkFMSLoad fmsLoad = (BulkFMSLoad) bulkLoadFile.getBulkLoad(); diff --git a/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3UniqueIdHelper.java b/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3UniqueIdHelper.java index bd250dcc0..9a8b8f1f9 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3UniqueIdHelper.java +++ b/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3UniqueIdHelper.java @@ -5,7 +5,6 @@ import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; import org.alliancegenome.curation_api.services.helpers.UniqueIdGeneratorHelper; -import org.apache.commons.lang3.StringUtils; import jakarta.enterprise.context.RequestScoped; @@ -15,14 +14,18 @@ public class Gff3UniqueIdHelper { public static String getExonOrCodingSequenceUniqueId(Gff3DTO dto, Map attributes, BackendBulkDataProvider dataProvider) { UniqueIdGeneratorHelper uniqueId = new UniqueIdGeneratorHelper(); - if (attributes.containsKey("ID")) { - uniqueId.add(removeWormBasePrefix(attributes.get("ID"), dataProvider)); + if (attributes.containsKey("curie")) { + uniqueId.add(attributes.get("curie")); + } else if (attributes.containsKey("ID")) { + uniqueId.add(attributes.get("ID")); } else if (attributes.containsKey("Name")) { uniqueId.add(attributes.get("Name")); + } else if (attributes.containsKey("exon_id")) { + uniqueId.add(attributes.get("exon_id")); } if (attributes.containsKey("Parent")) { - uniqueId.add(removeWormBasePrefix(attributes.get("Parent"), dataProvider)); + uniqueId.add(attributes.get("Parent")); } uniqueId.add(dto.getSeqId()); @@ -33,14 +36,4 @@ public static String getExonOrCodingSequenceUniqueId(Gff3DTO dto, Map 1) { - id = idParts[1]; - } - } - return id; - } - } diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java index dd68f8cc3..2dca95631 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -1,6 +1,7 @@ package org.alliancegenome.curation_api.services.validation.dto; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.alliancegenome.curation_api.constants.ValidationConstants; @@ -43,7 +44,7 @@ public Exon validateExonEntry(Gff3DTO dto, BackendBulkDataProvider dataProvider) Exon exon = null; - Map attributes = getAttributes(dto); + Map attributes = getAttributes(dto, dataProvider); String uniqueId = Gff3UniqueIdHelper.getExonOrCodingSequenceUniqueId(dto, attributes, dataProvider); SearchResponse searchResponse = exonDAO.findByField("uniqueId", uniqueId); if (searchResponse != null && searchResponse.getSingleResult() != null) { @@ -71,7 +72,7 @@ public CodingSequence validateCdsEntry(Gff3DTO dto, BackendBulkDataProvider data CodingSequence cds = null; - Map attributes = getAttributes(dto); + Map attributes = getAttributes(dto, dataProvider); String uniqueId = Gff3UniqueIdHelper.getExonOrCodingSequenceUniqueId(dto, attributes, dataProvider); SearchResponse searchResponse = codingSequenceDAO.findByField("uniqueId", uniqueId); if (searchResponse != null && searchResponse.getSingleResult() != null) { @@ -99,13 +100,14 @@ public Transcript validateTranscriptEntry(Gff3DTO dto, BackendBulkDataProvider d Transcript transcript = null; - Map attributes = getAttributes(dto); + Map attributes = getAttributes(dto, dataProvider); if (attributes.containsKey("ID")) { SearchResponse searchResponse = transcriptDAO.findByField("modInternalId", attributes.get("ID")); if (searchResponse != null && searchResponse.getSingleResult() != null) { transcript = searchResponse.getSingleResult(); } else { transcript = new Transcript(); + transcript.setModInternalId(attributes.get("ID")); } } @@ -133,21 +135,6 @@ public Transcript validateTranscriptEntry(Gff3DTO dto, BackendBulkDataProvider d private ObjectResponse validateGffEntity(E entity, Gff3DTO dto, Map attributes, BackendBulkDataProvider dataProvider) { ObjectResponse geResponse = new ObjectResponse(); - if (attributes.containsKey("ID")) { - String id = attributes.get("ID"); - if (StringUtils.equals(dataProvider.sourceOrganization, "WB")) { - String[] idParts = id.split(":"); - if (idParts.length > 1) { - id = idParts[1]; - } - } - entity.setModInternalId(id); - } else if (attributes.containsKey("exon_id")) { - entity.setModInternalId(attributes.get("exon_id")); - } else if (attributes.containsKey("transcript_id")) { - entity.setModInternalId(attributes.get("transcript_id")); - } - if (attributes.containsKey("curie")) { entity.setModEntityId(attributes.get("curie")); } @@ -160,7 +147,7 @@ private ObjectResponse validateGffEntity(E entity, return geResponse; } - private Map getAttributes (Gff3DTO dto) { + private Map getAttributes (Gff3DTO dto, BackendBulkDataProvider dataProvider) { Map attributes = new HashMap(); if (CollectionUtils.isNotEmpty(dto.getAttributes())) { for (String keyValue : dto.getAttributes()) { @@ -170,6 +157,20 @@ private Map getAttributes (Gff3DTO dto) { } } } + + if (StringUtils.equals(dataProvider.sourceOrganization, "WB")) { + for (String key : List.of("ID", "Parent")) { + if (attributes.containsKey(key)) { + String id = attributes.get(key); + String[] idParts = id.split(":"); + if (idParts.length > 1) { + id = idParts[1]; + } + attributes.put(key, id); + } + } + } + return attributes; } diff --git a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadFmsITCase.java b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java similarity index 88% rename from src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadFmsITCase.java rename to src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java index 0e543e776..ec9e06414 100644 --- a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadFmsITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java @@ -24,7 +24,7 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) @DisplayName("608 - GFF data bulk upload - FMS") @Order(608) -public class Gff3BulkUploadFmsITCase extends BaseITCase { +public class Gff3BulkUploadITCase extends BaseITCase { @BeforeEach public void init() { @@ -42,8 +42,8 @@ public void init() { private final String exonGetEndpoint = "/api/exon/"; private final String cdsGetEndpoint = "/api/cds/"; private final String transcriptId = "Y74C9A.2a.1"; - private final String exonId = "Y74C9A.2a_exon"; - private final String cdsId = "Y74C9A.2a"; + private final String exonUniqueId = "Y74C9A.2a_exon|Y74C9A.2a.1|I|1|100|+"; + private final String cdsUniqueId = "Y74C9A.2a|Y74C9A.2a.1|I|10|100|+"; private void loadRequiredEntities() throws Exception { createSoTerm("SO:0000234", "mRNA", false); @@ -77,11 +77,10 @@ public void gff3DataBulkUploadExonEntity() throws Exception { RestAssured.given(). when(). - get(exonGetEndpoint + exonId). + get(exonGetEndpoint + exonUniqueId). then(). statusCode(200). - body("entity.modInternalId", is(exonId)). - body("entity.uniqueId", is("Y74C9A.2a_exon|Y74C9A.2a.1|I|1|100|+")). + body("entity.uniqueId", is(exonUniqueId)). body("entity.taxon.curie", is("NCBITaxon:6239")). body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")); @@ -94,11 +93,10 @@ public void gff3DataBulkUploadCodingSequenceEntity() throws Exception { RestAssured.given(). when(). - get(cdsGetEndpoint + cdsId). + get(cdsGetEndpoint + cdsUniqueId). then(). statusCode(200). - body("entity.modInternalId", is(cdsId)). - body("entity.uniqueId", is("Y74C9A.2a|Y74C9A.2a.1|I|10|100|+")). + body("entity.uniqueId", is(cdsUniqueId)). body("entity.taxon.curie", is("NCBITaxon:6239")). body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")); From c3e0e10a21e2bbcca1baf877bdb029bebc9b0cb6 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 16:32:33 +0100 Subject: [PATCH 06/82] Update migration --- .../db/migration/v0.35.0.10__gff_entity_tables.sql | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/resources/db/migration/v0.35.0.10__gff_entity_tables.sql b/src/main/resources/db/migration/v0.35.0.10__gff_entity_tables.sql index 7347d43ec..754623b31 100644 --- a/src/main/resources/db/migration/v0.35.0.10__gff_entity_tables.sql +++ b/src/main/resources/db/migration/v0.35.0.10__gff_entity_tables.sql @@ -57,8 +57,6 @@ CREATE INDEX genomeassembly_crossreference_genomeassembly_xref_index ON genomeas CREATE INDEX genomeassembly_crossreference_genomeassembly_index ON genomeassembly_crossreference USING btree(genomeassembly_id); CREATE INDEX genomeassembly_crossreference_crossreference_index ON genomeassembly_crossreference USING btree(crossreferences_id); - -/* INSERT INTO bulkloadgroup (id, name) VALUES (nextval('bulkloadgroup_seq'), 'GFF Loads'); INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) @@ -81,7 +79,7 @@ INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) SELECT nextval('bulkload_seq'), 'GFF', 'ZFIN GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) - SELECT id, '0 0 22 ? * SUN-THU', false FROM bulkload WHERE backendbulkloadtype = 'GFF'; + SELECT id, '0 0 22 ? * SUN-THU', true FROM bulkload WHERE backendbulkloadtype = 'GFF'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) SELECT id, 'GFF', 'FB' FROM bulkload WHERE name = 'FB GFF Load'; @@ -100,5 +98,4 @@ INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) SELECT id, 'GFF', 'XBXT' FROM bulkload WHERE name = 'XBXT GFF Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) - SELECT id, 'GFF', 'ZFIN' FROM bulkload WHERE name = 'ZFIN GFF Load'; -*/ \ No newline at end of file + SELECT id, 'GFF', 'ZFIN' FROM bulkload WHERE name = 'ZFIN GFF Load'; \ No newline at end of file From a6fcacfae60b5563bc7c53c82c2477b690da6d64 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 16:43:00 +0100 Subject: [PATCH 07/82] Checkstyle fixes --- .../curation_api/constants/Gff3Constants.java | 15 ++++++++------- .../interfaces/crud/TranscriptCrudInterface.java | 1 - .../curation_api/jobs/executors/Gff3Executor.java | 4 ---- .../curation_api/model/entities/Transcript.java | 5 ----- .../curation_api/services/Gff3Service.java | 2 +- .../services/validation/dto/Gff3DtoValidator.java | 4 ++-- 6 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java index b2681db8c..fe4c914f6 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java @@ -2,13 +2,14 @@ import java.util.List; -public final class Gff3Constants { - private Gff3Constants() { - // Hidden from view, as it is a utility class - } +import lombok.experimental.UtilityClass; + +@UtilityClass +public class Gff3Constants { public static final List TRANSCRIPT_TYPES = List.of( - "mRNA", "ncRNA", "piRNA", "lincRNA", "miRNA", "pre_miRNA", "snoRNA", "lncRNA", - "tRNA", "snRNA", "rRNA", "antisense_RNA", "C_gene_segment", "V_gene_segment", - "pseudogene_attribute", "snoRNA_gene", "pseudogenic_transcript", "lnc_RNA"); + "mRNA", "ncRNA", "piRNA", "lincRNA", "miRNA", "pre_miRNA", "snoRNA", "lncRNA", + "tRNA", "snRNA", "rRNA", "antisense_RNA", "C_gene_segment", "V_gene_segment", + "pseudogene_attribute", "snoRNA_gene", "pseudogenic_transcript", "lnc_RNA" + ); } \ No newline at end of file diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/TranscriptCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/TranscriptCrudInterface.java index ac1b81a3a..6e6c2ee23 100644 --- a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/TranscriptCrudInterface.java +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/TranscriptCrudInterface.java @@ -3,7 +3,6 @@ import java.util.List; import org.alliancegenome.curation_api.interfaces.base.BaseSubmittedObjectCrudInterface; -import org.alliancegenome.curation_api.interfaces.base.crud.BaseReadIdentifierControllerInterface; import org.alliancegenome.curation_api.model.entities.Transcript; import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; import org.alliancegenome.curation_api.response.APIResponse; diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java index 134eba67f..f4839f59c 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java @@ -10,16 +10,12 @@ import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException.ObjectUpdateExceptionData; -import org.alliancegenome.curation_api.interfaces.crud.BaseUpsertServiceInterface; import org.alliancegenome.curation_api.jobs.util.CsvSchemaBuilder; import org.alliancegenome.curation_api.model.entities.GenomeAssembly; -import org.alliancegenome.curation_api.model.entities.base.AuditedObject; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkFMSLoad; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFile; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; -import org.alliancegenome.curation_api.model.ingest.dto.base.BaseDTO; import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; -import org.alliancegenome.curation_api.model.ingest.dto.fms.PsiMiTabDTO; import org.alliancegenome.curation_api.response.APIResponse; import org.alliancegenome.curation_api.response.LoadHistoryResponce; import org.alliancegenome.curation_api.services.CodingSequenceService; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java b/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java index 8dc40e0d3..403322155 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java @@ -5,15 +5,10 @@ import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.media.Schema; -import org.hibernate.search.engine.backend.types.Aggregable; -import org.hibernate.search.engine.backend.types.Searchable; -import org.hibernate.search.engine.backend.types.Sortable; import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; -import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; -import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonView; diff --git a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java index 239018516..311d7e895 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java +++ b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java @@ -27,7 +27,7 @@ import jakarta.transaction.Transactional; @RequestScoped -public class Gff3Service { +public class Gff3Service { @Inject GenomeAssemblyDAO genomeAssemblyDAO; @Inject DataProviderService dataProviderService; diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java index 2dca95631..f53ac4a7c 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -108,7 +108,7 @@ public Transcript validateTranscriptEntry(Gff3DTO dto, BackendBulkDataProvider d } else { transcript = new Transcript(); transcript.setModInternalId(attributes.get("ID")); - } + } } SearchResponse soResponse = soTermDAO.findByField("name", dto.getType()); @@ -147,7 +147,7 @@ private ObjectResponse validateGffEntity(E entity, return geResponse; } - private Map getAttributes (Gff3DTO dto, BackendBulkDataProvider dataProvider) { + private Map getAttributes(Gff3DTO dto, BackendBulkDataProvider dataProvider) { Map attributes = new HashMap(); if (CollectionUtils.isNotEmpty(dto.getAttributes())) { for (String keyValue : dto.getAttributes()) { From 0a7b14d85d5b5819e464dd93af585b4404d6f0f8 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 16:47:58 +0100 Subject: [PATCH 08/82] 2nd attempt at checkstyle fixes --- .../curation_api/constants/Gff3Constants.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java index fe4c914f6..c03ff3e22 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java @@ -2,10 +2,10 @@ import java.util.List; -import lombok.experimental.UtilityClass; - -@UtilityClass -public class Gff3Constants { +public final class Gff3Constants { + private Gff3Constants() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } public static final List TRANSCRIPT_TYPES = List.of( "mRNA", "ncRNA", "piRNA", "lincRNA", "miRNA", "pre_miRNA", "snoRNA", "lncRNA", "tRNA", "snRNA", "rRNA", "antisense_RNA", "C_gene_segment", "V_gene_segment", From dcd8a00b2f5559f1eb8378f0b187148b3e38d947 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 16:51:26 +0100 Subject: [PATCH 09/82] 3rd attempt at checkstyle fixes --- .../alliancegenome/curation_api/constants/Gff3Constants.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java index c03ff3e22..576a4692d 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java @@ -2,11 +2,11 @@ import java.util.List; -public final class Gff3Constants { +public class Gff3Constants { private Gff3Constants() { throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); } - public static final List TRANSCRIPT_TYPES = List.of( + public static List TRANSCRIPT_TYPES = List.of( "mRNA", "ncRNA", "piRNA", "lincRNA", "miRNA", "pre_miRNA", "snoRNA", "lncRNA", "tRNA", "snRNA", "rRNA", "antisense_RNA", "C_gene_segment", "V_gene_segment", "pseudogene_attribute", "snoRNA_gene", "pseudogenic_transcript", "lnc_RNA" From c3f88d712471054805820cc23bc9cff3acf7037f Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 16:54:47 +0100 Subject: [PATCH 10/82] Maybe this time --- .../alliancegenome/curation_api/constants/Gff3Constants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java index 576a4692d..e27ec3547 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java @@ -6,7 +6,7 @@ public class Gff3Constants { private Gff3Constants() { throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); } - public static List TRANSCRIPT_TYPES = List.of( + public static final List TRANSCRIPT_TYPES = List.of( "mRNA", "ncRNA", "piRNA", "lincRNA", "miRNA", "pre_miRNA", "snoRNA", "lncRNA", "tRNA", "snRNA", "rRNA", "antisense_RNA", "C_gene_segment", "V_gene_segment", "pseudogene_attribute", "snoRNA_gene", "pseudogenic_transcript", "lnc_RNA" From 3988dc531a45b68b7fa8f14588b2362deede4d68 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 17:38:46 +0100 Subject: [PATCH 11/82] Suppress warning --- .../alliancegenome/curation_api/constants/Gff3Constants.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java index e27ec3547..49f6ba6d4 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java @@ -2,8 +2,10 @@ import java.util.List; -public class Gff3Constants { +@SuppressWarnings("checkstyle:hideutilityclassconstructor") +public final class Gff3Constants { private Gff3Constants() { + // Hidden from view, as it is a utility class throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); } public static final List TRANSCRIPT_TYPES = List.of( From 78421ad96f00c44e2862bf498ee622ddc5f25e1e Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 17:41:27 +0100 Subject: [PATCH 12/82] Remove HideUtilityClassConstructor check --- checkstyle.xml | 2 +- .../alliancegenome/curation_api/constants/Gff3Constants.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/checkstyle.xml b/checkstyle.xml index 4881979be..bd600114a 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -27,7 +27,7 @@ - + diff --git a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java index 49f6ba6d4..55b9ed3c2 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java @@ -2,7 +2,6 @@ import java.util.List; -@SuppressWarnings("checkstyle:hideutilityclassconstructor") public final class Gff3Constants { private Gff3Constants() { // Hidden from view, as it is a utility class From 6bad602c8dbcaec0c7215d81b83039e5f968eb00 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 17:47:30 +0100 Subject: [PATCH 13/82] Rename migration as this will go out with next release --- ...10__gff_entity_tables.sql => v0.36.0.1__gff_entity_tables.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{v0.35.0.10__gff_entity_tables.sql => v0.36.0.1__gff_entity_tables.sql} (100%) diff --git a/src/main/resources/db/migration/v0.35.0.10__gff_entity_tables.sql b/src/main/resources/db/migration/v0.36.0.1__gff_entity_tables.sql similarity index 100% rename from src/main/resources/db/migration/v0.35.0.10__gff_entity_tables.sql rename to src/main/resources/db/migration/v0.36.0.1__gff_entity_tables.sql From edf7d9e37fbe6666b9f55a02cccb7669d535d0ea Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Wed, 3 Jul 2024 12:13:58 -0500 Subject: [PATCH 14/82] Change to use stringlist template for synonyms in controlled vocabulary --- .../ControlledVocabularyTable.js | 30 ++----------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/src/main/cliapp/src/containers/controlledVocabularyPage/ControlledVocabularyTable.js b/src/main/cliapp/src/containers/controlledVocabularyPage/ControlledVocabularyTable.js index 4a8cbb65f..6ce57cdf0 100644 --- a/src/main/cliapp/src/containers/controlledVocabularyPage/ControlledVocabularyTable.js +++ b/src/main/cliapp/src/containers/controlledVocabularyPage/ControlledVocabularyTable.js @@ -21,6 +21,7 @@ import { useGetTableData } from '../../service/useGetTableData'; import { useGetUserSettings } from '../../service/useGetUserSettings'; import { SearchService } from '../../service/SearchService'; import { setNewEntity } from '../../utils/utils'; +import { StringListTemplate } from '../../components/Templates/StringListTemplate'; export const ControlledVocabularyTable = () => { const newTermReducer = (state, action) => { @@ -216,33 +217,6 @@ export const ControlledVocabularyTable = () => { } }; - const synonymsBodyTemplate = (rowData) => { - if (rowData?.synonyms && rowData.synonyms.length > 0) { - const sortedSynonyms = rowData.synonyms.sort(); - const listTemplate = (synonym) => { - return ( - -
- - ); - }; - return ( - <> -
- -
- - - - - ); - } - }; - const columns = [ { field: 'id', @@ -270,7 +244,7 @@ export const ControlledVocabularyTable = () => { header: 'Synonyms', sortable: true, filterConfig: FILTER_CONFIGS.synonymsFilterConfig, - body: synonymsBodyTemplate, + body: (rowData) => , }, { field: 'vocabulary.name', From c8daf779a85c68a034294bc6954acc0718ee6139 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Wed, 3 Jul 2024 12:16:21 -0500 Subject: [PATCH 15/82] Removed unused import --- .../controlledVocabularyPage/ControlledVocabularyTable.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/cliapp/src/containers/controlledVocabularyPage/ControlledVocabularyTable.js b/src/main/cliapp/src/containers/controlledVocabularyPage/ControlledVocabularyTable.js index 6ce57cdf0..aa5955cf2 100644 --- a/src/main/cliapp/src/containers/controlledVocabularyPage/ControlledVocabularyTable.js +++ b/src/main/cliapp/src/containers/controlledVocabularyPage/ControlledVocabularyTable.js @@ -3,9 +3,6 @@ import { GenericDataTable } from '../../components/GenericDataTable/GenericDataT import { useMutation, useQuery } from '@tanstack/react-query'; import { Toast } from 'primereact/toast'; -import { Tooltip } from 'primereact/tooltip'; -import { EllipsisTableCell } from '../../components/EllipsisTableCell'; -import { ListTableCell } from '../../components/ListTableCell'; import { useControlledVocabularyService } from '../../service/useControlledVocabularyService'; import { VocabularyService } from '../../service/VocabularyService'; import { TrueFalseDropdown } from '../../components/TrueFalseDropDownSelector'; From d183482943d2a5036de68000dc378a62f3e0d9ec Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 19:00:51 +0100 Subject: [PATCH 16/82] Fix previous migration errors --- .../migration/v0.36.0.2__fix_migration_error.sql | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/resources/db/migration/v0.36.0.2__fix_migration_error.sql diff --git a/src/main/resources/db/migration/v0.36.0.2__fix_migration_error.sql b/src/main/resources/db/migration/v0.36.0.2__fix_migration_error.sql new file mode 100644 index 000000000..6d267395d --- /dev/null +++ b/src/main/resources/db/migration/v0.36.0.2__fix_migration_error.sql @@ -0,0 +1,14 @@ +DELETE FROM bulkscheduledload WHERE id = (SELECT id FROM bulkload WHERE name = 'WGD GFF Load'); + +DELETE FROM bulkload WHERE name = 'WGD GFF Load' OR name = 'HUMAN GFF Load'; + +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) + SELECT nextval('bulkload_seq'), 'GFF', 'SGD GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; + +INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) + SELECT id, '0 0 22 ? * SUN-THU', true FROM bulkload WHERE name = 'SGD GFF Load'; + +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'SGD' FROM bulkload WHERE name = 'SGD GFF Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) + SELECT id, 'GFF', 'HUMAN' FROM bulkload WHERE name = 'Human GFF Load'; \ No newline at end of file From 975cc2b5bdecb64ad71e22b7b0d92f4d44d69bca Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 19:02:42 +0100 Subject: [PATCH 17/82] Remove unnecessary clause --- .../resources/db/migration/v0.36.0.2__fix_migration_error.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/migration/v0.36.0.2__fix_migration_error.sql b/src/main/resources/db/migration/v0.36.0.2__fix_migration_error.sql index 6d267395d..dfc3c4634 100644 --- a/src/main/resources/db/migration/v0.36.0.2__fix_migration_error.sql +++ b/src/main/resources/db/migration/v0.36.0.2__fix_migration_error.sql @@ -1,6 +1,6 @@ DELETE FROM bulkscheduledload WHERE id = (SELECT id FROM bulkload WHERE name = 'WGD GFF Load'); -DELETE FROM bulkload WHERE name = 'WGD GFF Load' OR name = 'HUMAN GFF Load'; +DELETE FROM bulkload WHERE name = 'WGD GFF Load'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) SELECT nextval('bulkload_seq'), 'GFF', 'SGD GFF Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'GFF Loads'; From 99ae13f1ea218d73b35f50de3484232ea76f0513 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 3 Jul 2024 23:38:24 +0100 Subject: [PATCH 18/82] Fix total record count --- .../curation_api/jobs/executors/Gff3Executor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java index f4839f59c..34705544d 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java @@ -69,7 +69,7 @@ public void execLoad(BulkLoadFile bulkLoadFile) { Map> previousIds = getPreviouslyLoadedIds(dataProvider); - BulkLoadFileHistory history = new BulkLoadFileHistory(gffData.size()); + BulkLoadFileHistory history = new BulkLoadFileHistory((gffData.size() * 2) + 1); createHistory(history, bulkLoadFile); idsAdded = runLoad(history, gffHeaderData, gffData, idsAdded, dataProvider); runCleanup(transcriptService, history, dataProvider.name(), previousIds.get("Transcript"), idsAdded.get("Transcript"), "GFF transcript", bulkLoadFile.getMd5Sum()); From 9b88a4ab78fc077aefce3fd6ee4b696f279f1552 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 4 Jul 2024 10:48:36 +0100 Subject: [PATCH 19/82] Don't store curie as modEntityId as not unique --- .../services/validation/dto/Gff3DtoValidator.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java index f53ac4a7c..1e31a1c27 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -135,10 +135,6 @@ public Transcript validateTranscriptEntry(Gff3DTO dto, BackendBulkDataProvider d private ObjectResponse validateGffEntity(E entity, Gff3DTO dto, Map attributes, BackendBulkDataProvider dataProvider) { ObjectResponse geResponse = new ObjectResponse(); - if (attributes.containsKey("curie")) { - entity.setModEntityId(attributes.get("curie")); - } - entity.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProvider.sourceOrganization)); entity.setTaxon(ncbiTaxonTermService.getByCurie(dataProvider.canonicalTaxonCurie).getEntity()); From c5fc8807ca5e61525122208edf968b45824ed94c Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 4 Jul 2024 11:01:04 +0100 Subject: [PATCH 20/82] Include non-coding exons --- .../org/alliancegenome/curation_api/services/Gff3Service.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java index 311d7e895..3910b5045 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java +++ b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java @@ -66,7 +66,7 @@ public GenomeAssembly loadGenomeAssembly(String assemblyName, List gffHe } public Map> loadEntity(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { - if (StringUtils.equals(gffEntry.getType(), "exon")) { + if (StringUtils.equals(gffEntry.getType(), "exon") || StringUtils.equals(gffEntry.getType(), "noncoding_exon")) { Exon exon = gff3DtoValidator.validateExonEntry(gffEntry, dataProvider); if (exon != null) { idsAdded.get("Exon").add(exon.getId()); From 49a1457ef40e5a1a82be2aa1c65b77da344bded6 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 4 Jul 2024 16:23:49 +0100 Subject: [PATCH 21/82] Fully implement geneType --- src/main/cliapp/src/constants/FilterFields.js | 5 + src/main/cliapp/src/constants/SortFields.js | 1 + .../src/containers/genesPage/GenesTable.js | 8 ++ .../genesPage/__tests__/GenesTable.test.js | 2 + .../containers/genesPage/mockData/mockData.js | 7 ++ .../curation_api/model/entities/Gene.java | 5 + .../model/ingest/dto/GeneDTO.java | 4 + .../services/validation/GeneValidator.java | 1 + .../validation/dto/GeneDTOValidator.java | 13 ++ .../curation_api/GeneBulkUploadITCase.java | 13 +- .../curation_api/GeneITCase.java | 18 ++- .../curation_api/base/BaseITCase.java | 6 + .../bulk/01_gene/AF_01_all_fields.json | 3 +- .../bulk/01_gene/DX_01_duplicate_xref.json | 3 +- .../EN_01_empty_non_required_fields.json | 3 +- .../bulk/01_gene/ER_01_empty_mod_ids.json | 3 +- .../bulk/01_gene/ER_02_empty_taxon.json | 3 +- .../ER_03_empty_gene_symbol_display_text.json | 3 +- ..._04_empty_gene_full_name_display_text.json | 3 +- ...pty_gene_systematic_name_display_text.json | 3 +- ...ER_06_empty_gene_synonym_display_text.json | 3 +- .../ER_07_empty_gene_symbol_format_text.json | 3 +- ...R_08_empty_gene_full_name_format_text.json | 3 +- ...mpty_gene_systematic_name_format_text.json | 3 +- .../ER_10_empty_gene_synonym_format_text.json | 3 +- .../ER_11_empty_gene_symbol_name_type.json | 3 +- .../ER_12_empty_gene_full_name_name_type.json | 3 +- ..._empty_gene_systematic_name_name_type.json | 3 +- .../ER_14_empty_gene_synonym_name_type.json | 3 +- ...ider_source_organization_abbreviation.json | 3 +- ...ider_cross_reference_referenced_curie.json | 3 +- ...provider_cross_reference_display_name.json | 3 +- ..._data_provider_cross_reference_prefix.json | 3 +- ...ta_provider_cross_reference_page_area.json | 3 +- ..._empty_gene_secondary_id_secondary_id.json | 3 +- .../bulk/01_gene/ER_21_empty_gene_type.json | 114 ++++++++++++++++++ .../01_gene/IV_01_invalid_date_created.json | 3 +- .../01_gene/IV_02_invalid_date_updated.json | 3 +- .../bulk/01_gene/IV_03_invalid_taxon.json | 3 +- .../IV_04_invalid_gene_symbol_name_type.json | 3 +- ...V_05_invalid_gene_full_name_name_type.json | 3 +- ...nvalid_gene_systematic_name_name_type.json | 3 +- .../IV_07_invalid_gene_synonym_name_type.json | 3 +- ..._08_invalid_gene_symbol_synonym_scope.json | 3 +- ..._invalid_gene_full_name_synonym_scope.json | 3 +- ...id_gene_systematic_name_synonym_scope.json | 3 +- ...11_invalid_gene_synonym_synonym_scope.json | 3 +- .../IV_12_invalid_gene_symbol_evidence.json | 3 +- ...IV_13_invalid_gene_full_name_evidence.json | 3 +- ...invalid_gene_systematic_name_evidence.json | 3 +- .../IV_15_invalid_gene_synonym_evidence.json | 3 +- ...ider_source_organization_abbreviation.json | 3 +- ..._data_provider_cross_reference_prefix.json | 3 +- ...ta_provider_cross_reference_page_area.json | 3 +- ...19_invalid_gene_secondary_id_evidence.json | 3 +- .../bulk/01_gene/IV_20_invalid_gene_type.json | 114 ++++++++++++++++++ .../MN_01_no_non_required_fields_level_1.json | 3 +- .../MN_02_no_non_required_fields_level_2.json | 3 +- .../bulk/01_gene/MR_01_no_mod_ids.json | 3 +- .../bulk/01_gene/MR_02_no_taxon.json | 3 +- .../bulk/01_gene/MR_03_no_gene_symbol.json | 3 +- .../MR_04_no_gene_symbol_display_text.json | 3 +- .../MR_05_no_gene_full_name_display_text.json | 3 +- ..._no_gene_systematic_name_display_text.json | 3 +- .../MR_07_no_gene_synonym_display_text.json | 3 +- .../MR_08_no_gene_symbol_format_text.json | 3 +- .../MR_09_no_gene_full_name_format_text.json | 3 +- ...0_no_gene_systematic_name_format_text.json | 3 +- .../MR_11_no_gene_synonym_format_text.json | 3 +- .../MR_12_no_gene_symbol_name_type.json | 3 +- .../MR_13_no_gene_full_name_name_type.json | 3 +- ..._14_no_gene_systematic_name_name_type.json | 3 +- .../MR_15_no_gene_synonym_name_type.json | 3 +- .../bulk/01_gene/MR_16_no_data_provider.json | 3 +- ...ider_source_organization_abbreviation.json | 3 +- ...ider_cross_reference_referenced_curie.json | 3 +- ...provider_cross_reference_display_name.json | 3 +- ..._data_provider_cross_reference_prefix.json | 3 +- ...ta_provider_cross_reference_page_area.json | 3 +- ..._22_no_gene_secondary_id_secondary_id.json | 3 +- .../bulk/01_gene/MR_23_no_gene_type.json | 113 +++++++++++++++++ ...D_01_update_all_except_default_fields.json | 3 +- ...E_01_update_empty_non_required_fields.json | 3 +- ...update_no_non_required_fields_level_1.json | 3 +- ...update_no_non_required_fields_level_2.json | 3 +- .../01_gene/VT_01_valid_taxon_for_HUMAN.json | 3 +- .../01_gene/VT_02_valid_taxon_for_RGD.json | 3 +- 87 files changed, 560 insertions(+), 80 deletions(-) create mode 100644 src/test/resources/bulk/01_gene/ER_21_empty_gene_type.json create mode 100644 src/test/resources/bulk/01_gene/IV_20_invalid_gene_type.json create mode 100644 src/test/resources/bulk/01_gene/MR_23_no_gene_type.json diff --git a/src/main/cliapp/src/constants/FilterFields.js b/src/main/cliapp/src/constants/FilterFields.js index 43f2021f1..b75e08beb 100644 --- a/src/main/cliapp/src/constants/FilterFields.js +++ b/src/main/cliapp/src/constants/FilterFields.js @@ -344,6 +344,10 @@ export const FIELD_SETS = Object.freeze({ filterName: 'geneticSexFilter', fields: ['geneticSex.name'], }, + geneTypeFieldSet: { + filterName: 'geneTypeFilter', + fields: ['geneType.curie', 'geneType.name'], + }, gmiAggregationFieldSet: { filterName: 'gmiAggregationFilter', fields: ['relation.name'], @@ -788,6 +792,7 @@ export const FILTER_CONFIGS = Object.freeze({ geneSymbolFilterConfig: { filterComponentType: 'input', fieldSets: [FIELD_SETS.geneSymbolFieldSet] }, geneSynonymsFilterConfig: { filterComponentType: 'input', fieldSets: [FIELD_SETS.geneSynonymsFieldSet] }, geneSystematicNameFilterConfig: { filterComponentType: 'input', fieldSets: [FIELD_SETS.geneSystematicNameFieldSet] }, + geneTypeFilterConfig: { filterComponentType: 'input', fieldSets: [FIELD_SETS.geneTypeFieldSet] }, geneticModifiersFilterConfig: { filterComponentType: 'input', fieldSets: [FIELD_SETS.geneticModifiersFieldSet] }, idExampleFilterConfig: { filterComponentType: 'input', fieldSets: [FIELD_SETS.idExampleFieldSet] }, idPatternFilterConfig: { filterComponentType: 'input', fieldSets: [FIELD_SETS.idPatternFieldSet] }, diff --git a/src/main/cliapp/src/constants/SortFields.js b/src/main/cliapp/src/constants/SortFields.js index 487b4f062..8c0471a92 100644 --- a/src/main/cliapp/src/constants/SortFields.js +++ b/src/main/cliapp/src/constants/SortFields.js @@ -73,6 +73,7 @@ export const SORT_FIELDS = Object.freeze([ 'geneSymbol.displayText', 'geneSecondaryIds.secondaryId', 'geneSystematicName.displayText', + "geneType.name", 'inchi', 'inchiKey', 'iupac', diff --git a/src/main/cliapp/src/containers/genesPage/GenesTable.js b/src/main/cliapp/src/containers/genesPage/GenesTable.js index db05c530c..e6054770e 100644 --- a/src/main/cliapp/src/containers/genesPage/GenesTable.js +++ b/src/main/cliapp/src/containers/genesPage/GenesTable.js @@ -16,6 +16,7 @@ import { TextDialogTemplate } from '../../components/Templates/dialog/TextDialog import { ListDialogTemplate } from '../../components/Templates/dialog/ListDialogTemplate'; import { TaxonTemplate } from '../../components/Templates/TaxonTemplate'; import { BooleanTemplate } from '../../components/Templates/BooleanTemplate'; +import { OntologyTermTemplate } from '../../components/Templates/OntologyTermTemplate'; import { SearchService } from '../../service/SearchService'; @@ -191,6 +192,13 @@ export const GenesTable = () => { filter: true, filterConfig: FILTER_CONFIGS.geneSystematicNameFilterConfig, }, + { + field: 'geneType.name', + header: 'Gene Type', + body: (rowData) => , + sortable: true, + filterConfig: FILTER_CONFIGS.geneTypeFilterConfig, + }, { field: 'taxon.name', header: 'Taxon', diff --git a/src/main/cliapp/src/containers/genesPage/__tests__/GenesTable.test.js b/src/main/cliapp/src/containers/genesPage/__tests__/GenesTable.test.js index 68ff012e2..dc369c34e 100644 --- a/src/main/cliapp/src/containers/genesPage/__tests__/GenesTable.test.js +++ b/src/main/cliapp/src/containers/genesPage/__tests__/GenesTable.test.js @@ -46,6 +46,7 @@ describe('', () => { const systematicNameTd = await result.findByText('C35C5.5'); const taxonTd = await result.findByText(/Caenorhabditis elegans/i); const xrefsTd = await result.findByText(/WBGene00003771Xref \(gene\)/); + const geneTypeTd = await result.findByText(/tRNA_gene \(SO:0001271\)/i); await waitFor(() => { expect(modEntityIdTd).toBeInTheDocument(); @@ -56,6 +57,7 @@ describe('', () => { expect(systematicNameTd).toBeInTheDocument(); expect(taxonTd).toBeInTheDocument(); expect(xrefsTd).toBeInTheDocument(); + expect(geneTypeTd).toBeInTheDocument(); }); }); }); diff --git a/src/main/cliapp/src/containers/genesPage/mockData/mockData.js b/src/main/cliapp/src/containers/genesPage/mockData/mockData.js index 56b1376a3..15cd71d69 100644 --- a/src/main/cliapp/src/containers/genesPage/mockData/mockData.js +++ b/src/main/cliapp/src/containers/genesPage/mockData/mockData.js @@ -28,6 +28,13 @@ export const data = { curie: 'NCBITaxon:6239', name: 'Caenorhabditis elegans', }, + geneType: { + internal: false, + obsolete: false, + curie: "SO:0001272", + name: "tRNA_gene", + id: 25665 + }, dataProvider: { internal: false, obsolete: false, diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/Gene.java b/src/main/java/org/alliancegenome/curation_api/model/entities/Gene.java index 14431b18a..fbb6dff68 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/Gene.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/Gene.java @@ -15,8 +15,10 @@ import org.alliancegenome.curation_api.model.entities.slotAnnotations.geneSlotAnnotations.GeneSystematicNameSlotAnnotation; import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; import com.fasterxml.jackson.annotation.JsonManagedReference; import com.fasterxml.jackson.annotation.JsonView; @@ -42,6 +44,9 @@ @Table(indexes = { @Index(name = "gene_genetype_index", columnList = "geneType_id") }) public class Gene extends GenomicEntity { + @IndexedEmbedded(includePaths = {"curie", "name", "secondaryIdentifiers", "synonyms.name", "namespace", + "curie_keyword", "name_keyword", "secondaryIdentifiers_keyword", "synonyms.name_keyword", "namespace_keyword" }) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @ManyToOne @JsonView({ View.FieldsOnly.class }) private SOTerm geneType; diff --git a/src/main/java/org/alliancegenome/curation_api/model/ingest/dto/GeneDTO.java b/src/main/java/org/alliancegenome/curation_api/model/ingest/dto/GeneDTO.java index b1ace4eec..6565589e9 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/ingest/dto/GeneDTO.java +++ b/src/main/java/org/alliancegenome/curation_api/model/ingest/dto/GeneDTO.java @@ -38,4 +38,8 @@ public class GeneDTO extends GenomicEntityDTO { @JsonView({ View.FieldsAndLists.class }) @JsonProperty("gene_secondary_id_dtos") private List geneSecondaryIdDtos; + + @JsonView({ View.FieldsOnly.class }) + @JsonProperty("gene_type_curie") + private String geneTypeCurie; } diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/GeneValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/GeneValidator.java index 9752a3632..e10a219a7 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/GeneValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/GeneValidator.java @@ -136,6 +136,7 @@ private Gene validateGene(Gene uiEntity, Gene dbEntity) { private SOTerm validateGeneType(Gene uiEntity, Gene dbEntity) { if (ObjectUtils.isEmpty(uiEntity.getGeneType())) { + addMessageResponse("geneType", ValidationConstants.REQUIRED_MESSAGE); return null; } diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/GeneDTOValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/GeneDTOValidator.java index a61ab55ce..fb7fedd13 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/GeneDTOValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/GeneDTOValidator.java @@ -10,6 +10,7 @@ import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectValidationException; import org.alliancegenome.curation_api.model.entities.Gene; +import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; import org.alliancegenome.curation_api.model.entities.slotAnnotations.geneSlotAnnotations.GeneFullNameSlotAnnotation; import org.alliancegenome.curation_api.model.entities.slotAnnotations.geneSlotAnnotations.GeneSecondaryIdSlotAnnotation; import org.alliancegenome.curation_api.model.entities.slotAnnotations.geneSlotAnnotations.GeneSymbolSlotAnnotation; @@ -21,6 +22,7 @@ import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.response.SearchResponse; import org.alliancegenome.curation_api.services.helpers.slotAnnotations.SlotAnnotationIdentityHelper; +import org.alliancegenome.curation_api.services.ontology.SoTermService; import org.alliancegenome.curation_api.services.validation.dto.base.BaseDTOValidator; import org.alliancegenome.curation_api.services.validation.dto.slotAnnotations.geneSlotAnnotations.GeneFullNameSlotAnnotationDTOValidator; import org.alliancegenome.curation_api.services.validation.dto.slotAnnotations.geneSlotAnnotations.GeneSecondaryIdSlotAnnotationDTOValidator; @@ -44,6 +46,7 @@ public class GeneDTOValidator extends BaseDTOValidator { @Inject GeneSynonymSlotAnnotationDTOValidator geneSynonymDtoValidator; @Inject GeneSecondaryIdSlotAnnotationDTOValidator geneSecondaryIdDtoValidator; @Inject SlotAnnotationIdentityHelper identityHelper; + @Inject SoTermService soTermService; private ObjectResponse geneResponse; @@ -103,6 +106,16 @@ public Gene validateGeneDTO(GeneDTO dto, BackendBulkDataProvider dataProvider) t } gene.getGeneSecondaryIds().addAll(secondaryIds); } + + if (StringUtils.isBlank(dto.getGeneTypeCurie())) { + geneResponse.addErrorMessage("gene_type_curie", ValidationConstants.REQUIRED_MESSAGE); + } else { + SOTerm geneType = soTermService.findByCurieOrSecondaryId(dto.getGeneTypeCurie()); + if (geneType == null) { + geneResponse.addErrorMessage("gene_type_curie", ValidationConstants.INVALID_MESSAGE + " (" + dto.getGeneTypeCurie() + ")"); + } + gene.setGeneType(geneType); + } geneResponse.convertErrorMessagesToMap(); diff --git a/src/test/java/org/alliancegenome/curation_api/GeneBulkUploadITCase.java b/src/test/java/org/alliancegenome/curation_api/GeneBulkUploadITCase.java index c6208e9d6..f42adcd72 100644 --- a/src/test/java/org/alliancegenome/curation_api/GeneBulkUploadITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/GeneBulkUploadITCase.java @@ -46,6 +46,8 @@ public void init() { private String requiredReferenceXref2 = "PMID:25920551"; private String requiredDataProvider = "WB"; private String requiredDataProvider2 = "RGD"; + private String soTerm = "SO:0001217"; + private String soTerm2 = "SO:0000336"; private final String geneBulkPostEndpoint = "/api/gene/bulk/WB/genes"; private final String geneBulkPostEndpointRGD = "/api/gene/bulk/RGD/genes"; @@ -60,6 +62,8 @@ private void loadRequiredEntities() throws Exception { createResourceDescriptorPage("homepage", "http://test.org", rd); ResourceDescriptor rd2 = createResourceDescriptor("TEST2"); createResourceDescriptorPage("homepage2", "http://test2.org", rd2); + createSoTerm(soTerm, "protein_coding_gene", false); + createSoTerm(soTerm2, "pseudogene", false); } @Test @@ -147,7 +151,8 @@ public void geneBulkUploadCheckFields() throws Exception { body("entity.crossReferences", hasSize(1)). body("entity.crossReferences[0].referencedCurie", is("TEST:Xref01")). body("entity.crossReferences[0].displayName", is("TEST:Xref01Display")). - body("entity.crossReferences[0].resourceDescriptorPage.name", is("homepage")); + body("entity.crossReferences[0].resourceDescriptorPage.name", is("homepage")). + body("entity.geneType.curie", is(soTerm)); } @Test @@ -233,7 +238,8 @@ public void geneBulkUploadUpdateFields() throws Exception { body("entity.crossReferences", hasSize(1)). body("entity.crossReferences[0].referencedCurie", is("TEST2:Xref02")). body("entity.crossReferences[0].displayName", is("TEST2:Xref02Display")). - body("entity.crossReferences[0].resourceDescriptorPage.name", is("homepage2")); + body("entity.crossReferences[0].resourceDescriptorPage.name", is("homepage2")). + body("entity.geneType.curie", is(soTerm2)); } @Test @@ -261,6 +267,7 @@ public void geneBulkUploadMissingRequiredFields() throws Exception { checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "MR_20_no_data_provider_cross_reference_prefix.json"); checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "MR_21_no_data_provider_cross_reference_page_area.json"); checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "MR_22_no_gene_secondary_id_secondary_id.json"); + checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "MR_23_no_gene_type.json"); } @Test @@ -286,6 +293,7 @@ public void geneBulkUploadEmptyRequiredFields() throws Exception { checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "ER_18_empty_data_provider_cross_reference_prefix.json"); checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "ER_19_empty_data_provider_cross_reference_page_area.json"); checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "ER_20_empty_gene_secondary_id_secondary_id.json"); + checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "ER_21_empty_gene_type.json"); } @Test @@ -310,6 +318,7 @@ public void geneBulkUploadInvalidFields() throws Exception { checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "IV_17_invalid_data_provider_cross_reference_prefix.json"); checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "IV_18_invalid_data_provider_cross_reference_page_area.json"); checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "IV_19_invalid_gene_secondary_id_evidence.json"); + checkFailedBulkLoad(geneBulkPostEndpoint, geneTestFilePath + "IV_20_invalid_gene_type.json"); } @Test diff --git a/src/test/java/org/alliancegenome/curation_api/GeneITCase.java b/src/test/java/org/alliancegenome/curation_api/GeneITCase.java index dbda64419..95167bfcf 100644 --- a/src/test/java/org/alliancegenome/curation_api/GeneITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/GeneITCase.java @@ -301,10 +301,11 @@ public void createGeneWithMissingRequiredFieldsLevel1() { post("/api/gene"). then(). statusCode(400). - body("errorMessages", is(aMapWithSize(3))). + body("errorMessages", is(aMapWithSize(4))). body("errorMessages.modInternalId", is(ValidationConstants.REQUIRED_UNLESS_OTHER_FIELD_POPULATED_MESSAGE + "modEntityId")). body("errorMessages.taxon", is(ValidationConstants.REQUIRED_MESSAGE)). - body("errorMessages.geneSymbol", is(ValidationConstants.REQUIRED_MESSAGE)); + body("errorMessages.geneSymbol", is(ValidationConstants.REQUIRED_MESSAGE)). + body("errorMessages.geneType", is(ValidationConstants.REQUIRED_MESSAGE)); } @Test @@ -331,6 +332,7 @@ public void editGeneWithMissingRequiredFieldsLevel1() { gene.setTaxon(null); gene.setGeneSymbol(null); gene.setDataProvider(null); + gene.setGeneType(null); RestAssured.given(). contentType("application/json"). @@ -339,10 +341,11 @@ public void editGeneWithMissingRequiredFieldsLevel1() { put("/api/gene"). then(). statusCode(400). - body("errorMessages", is(aMapWithSize(3))). + body("errorMessages", is(aMapWithSize(4))). body("errorMessages.taxon", is(ValidationConstants.REQUIRED_MESSAGE)). body("errorMessages.geneSymbol", is(ValidationConstants.REQUIRED_MESSAGE)). - body("errorMessages.dataProvider", is(ValidationConstants.REQUIRED_MESSAGE)); + body("errorMessages.dataProvider", is(ValidationConstants.REQUIRED_MESSAGE)). + body("errorMessages.geneType", is(ValidationConstants.REQUIRED_MESSAGE)); } @Test @@ -353,6 +356,7 @@ public void createGeneWithEmptyRequiredFieldsLevel1() { gene.setModEntityId(""); gene.setTaxon(taxon); gene.setGeneSymbol(geneSymbol); + gene.setGeneType(soTerm); RestAssured.given(). contentType("application/json"). @@ -389,6 +393,7 @@ public void createGeneWithMissingRequiredFieldsLevel2() { Gene gene = new Gene(); gene.setModEntityId("GENE:0008"); gene.setTaxon(taxon); + gene.setGeneType(soTerm); GeneSymbolSlotAnnotation invalidSymbol = new GeneSymbolSlotAnnotation(); GeneFullNameSlotAnnotation invalidFullName = new GeneFullNameSlotAnnotation(); @@ -494,6 +499,7 @@ public void createGeneWithEmptyRequiredFieldsLevel2() { Gene gene = new Gene(); gene.setModEntityId("GENE:0010"); gene.setTaxon(taxon); + gene.setGeneType(soTerm); GeneSymbolSlotAnnotation invalidSymbol = createGeneSymbolSlotAnnotation(null, "", symbolNameType, null, null); GeneFullNameSlotAnnotation invalidFullName = createGeneFullNameSlotAnnotation(null, "", fullNameType, null, null); @@ -898,7 +904,6 @@ public void editGeneWithNullNonRequiredFieldsLevel2() { public void editGeneWithNullNonRequiredFieldsLevel1() { Gene gene = getGene(GENE); - gene.setGeneType(null); gene.setGeneFullName(null); gene.setGeneSynonyms(null); gene.setGeneSystematicName(null); @@ -917,7 +922,6 @@ public void editGeneWithNullNonRequiredFieldsLevel1() { get("/api/gene/" + GENE). then(). statusCode(200). - body("entity", not(hasKey("geneType"))). body("entity", not(hasKey("geneFullName"))). body("entity", not(hasKey("geneSynonyms"))). body("entity", not(hasKey("geneSystematicName"))). @@ -931,6 +935,7 @@ public void createGeneWithOnlyRequiredFields() { gene.setModEntityId("GENE:0020"); gene.setTaxon(taxon); gene.setGeneSymbol(geneSymbol); + gene.setGeneType(soTerm); RestAssured.given(). contentType("application/json"). @@ -947,6 +952,7 @@ public void createGeneWithOnlyRequiredFieldsLevel2() { Gene gene = new Gene(); gene.setModEntityId("GENE:0021"); gene.setTaxon(taxon); + gene.setGeneType(soTerm); GeneSymbolSlotAnnotation minimalGeneSymbol = createGeneSymbolSlotAnnotation(null, "Test symbol", symbolNameType, null, null); GeneFullNameSlotAnnotation minimalGeneFullName = createGeneFullNameSlotAnnotation(null, "Test name", fullNameType, null, null); diff --git a/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java b/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java index f03086b3b..1ef4c4cb1 100644 --- a/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java @@ -344,6 +344,9 @@ public Gene createGene(String modEntityId, String taxonCurie, Boolean obsolete, symbol.setFormatText(modEntityId); gene.setGeneSymbol(symbol); + + SOTerm geneType = getSoTerm("SO:0001217"); + gene.setGeneType(geneType); ObjectResponse response = given(). contentType("application/json"). @@ -1211,6 +1214,9 @@ public void loadGeneWithXref(String modEntityId, String taxonCurie, VocabularyTe symbol.setFormatText(modEntityId); gene.setGeneSymbol(symbol); + + SOTerm geneType = getSoTerm("SO:0001217"); + gene.setGeneType(geneType); if (StringUtils.isNotBlank(xrefCurie)) { CrossReference xref = new CrossReference(); diff --git a/src/test/resources/bulk/01_gene/AF_01_all_fields.json b/src/test/resources/bulk/01_gene/AF_01_all_fields.json index cdcbae3d5..5e8304cbf 100644 --- a/src/test/resources/bulk/01_gene/AF_01_all_fields.json +++ b/src/test/resources/bulk/01_gene/AF_01_all_fields.json @@ -108,6 +108,7 @@ "display_name": "TEST:Xref01Display", "prefix": "TEST" } - ] + ], + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/DX_01_duplicate_xref.json b/src/test/resources/bulk/01_gene/DX_01_duplicate_xref.json index 7aa718cb4..87cecd236 100644 --- a/src/test/resources/bulk/01_gene/DX_01_duplicate_xref.json +++ b/src/test/resources/bulk/01_gene/DX_01_duplicate_xref.json @@ -116,6 +116,7 @@ "display_name": "TEST:Xref01Display", "prefix": "TEST" } - ] + ], + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/EN_01_empty_non_required_fields.json b/src/test/resources/bulk/01_gene/EN_01_empty_non_required_fields.json index 9e4b3d71f..a0d76b3c0 100644 --- a/src/test/resources/bulk/01_gene/EN_01_empty_non_required_fields.json +++ b/src/test/resources/bulk/01_gene/EN_01_empty_non_required_fields.json @@ -86,6 +86,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_01_empty_mod_ids.json b/src/test/resources/bulk/01_gene/ER_01_empty_mod_ids.json index 8046374f7..893e850d7 100644 --- a/src/test/resources/bulk/01_gene/ER_01_empty_mod_ids.json +++ b/src/test/resources/bulk/01_gene/ER_01_empty_mod_ids.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_02_empty_taxon.json b/src/test/resources/bulk/01_gene/ER_02_empty_taxon.json index 322d2117c..888924a64 100644 --- a/src/test/resources/bulk/01_gene/ER_02_empty_taxon.json +++ b/src/test/resources/bulk/01_gene/ER_02_empty_taxon.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_03_empty_gene_symbol_display_text.json b/src/test/resources/bulk/01_gene/ER_03_empty_gene_symbol_display_text.json index bce150f7f..07c532d66 100644 --- a/src/test/resources/bulk/01_gene/ER_03_empty_gene_symbol_display_text.json +++ b/src/test/resources/bulk/01_gene/ER_03_empty_gene_symbol_display_text.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_04_empty_gene_full_name_display_text.json b/src/test/resources/bulk/01_gene/ER_04_empty_gene_full_name_display_text.json index a677f1bfe..d01582336 100644 --- a/src/test/resources/bulk/01_gene/ER_04_empty_gene_full_name_display_text.json +++ b/src/test/resources/bulk/01_gene/ER_04_empty_gene_full_name_display_text.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_05_empty_gene_systematic_name_display_text.json b/src/test/resources/bulk/01_gene/ER_05_empty_gene_systematic_name_display_text.json index b61665665..4b9e29ac8 100644 --- a/src/test/resources/bulk/01_gene/ER_05_empty_gene_systematic_name_display_text.json +++ b/src/test/resources/bulk/01_gene/ER_05_empty_gene_systematic_name_display_text.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_06_empty_gene_synonym_display_text.json b/src/test/resources/bulk/01_gene/ER_06_empty_gene_synonym_display_text.json index d73378769..4f6eb9c7f 100644 --- a/src/test/resources/bulk/01_gene/ER_06_empty_gene_synonym_display_text.json +++ b/src/test/resources/bulk/01_gene/ER_06_empty_gene_synonym_display_text.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_07_empty_gene_symbol_format_text.json b/src/test/resources/bulk/01_gene/ER_07_empty_gene_symbol_format_text.json index b6b969d1a..c672ce616 100644 --- a/src/test/resources/bulk/01_gene/ER_07_empty_gene_symbol_format_text.json +++ b/src/test/resources/bulk/01_gene/ER_07_empty_gene_symbol_format_text.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_08_empty_gene_full_name_format_text.json b/src/test/resources/bulk/01_gene/ER_08_empty_gene_full_name_format_text.json index b13598137..f00a8f79c 100644 --- a/src/test/resources/bulk/01_gene/ER_08_empty_gene_full_name_format_text.json +++ b/src/test/resources/bulk/01_gene/ER_08_empty_gene_full_name_format_text.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_09_empty_gene_systematic_name_format_text.json b/src/test/resources/bulk/01_gene/ER_09_empty_gene_systematic_name_format_text.json index 245ddc047..98bfe1d08 100644 --- a/src/test/resources/bulk/01_gene/ER_09_empty_gene_systematic_name_format_text.json +++ b/src/test/resources/bulk/01_gene/ER_09_empty_gene_systematic_name_format_text.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_10_empty_gene_synonym_format_text.json b/src/test/resources/bulk/01_gene/ER_10_empty_gene_synonym_format_text.json index 8adf992ed..e5163011e 100644 --- a/src/test/resources/bulk/01_gene/ER_10_empty_gene_synonym_format_text.json +++ b/src/test/resources/bulk/01_gene/ER_10_empty_gene_synonym_format_text.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_11_empty_gene_symbol_name_type.json b/src/test/resources/bulk/01_gene/ER_11_empty_gene_symbol_name_type.json index ed74c0725..0b5462d86 100644 --- a/src/test/resources/bulk/01_gene/ER_11_empty_gene_symbol_name_type.json +++ b/src/test/resources/bulk/01_gene/ER_11_empty_gene_symbol_name_type.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_12_empty_gene_full_name_name_type.json b/src/test/resources/bulk/01_gene/ER_12_empty_gene_full_name_name_type.json index dc9d88a34..47241c9e7 100644 --- a/src/test/resources/bulk/01_gene/ER_12_empty_gene_full_name_name_type.json +++ b/src/test/resources/bulk/01_gene/ER_12_empty_gene_full_name_name_type.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_13_empty_gene_systematic_name_name_type.json b/src/test/resources/bulk/01_gene/ER_13_empty_gene_systematic_name_name_type.json index 3bba1ce01..77db95829 100644 --- a/src/test/resources/bulk/01_gene/ER_13_empty_gene_systematic_name_name_type.json +++ b/src/test/resources/bulk/01_gene/ER_13_empty_gene_systematic_name_name_type.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_14_empty_gene_synonym_name_type.json b/src/test/resources/bulk/01_gene/ER_14_empty_gene_synonym_name_type.json index bc3f864d5..b688a3169 100644 --- a/src/test/resources/bulk/01_gene/ER_14_empty_gene_synonym_name_type.json +++ b/src/test/resources/bulk/01_gene/ER_14_empty_gene_synonym_name_type.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_15_empty_data_provider_source_organization_abbreviation.json b/src/test/resources/bulk/01_gene/ER_15_empty_data_provider_source_organization_abbreviation.json index 1ef038787..091629de4 100644 --- a/src/test/resources/bulk/01_gene/ER_15_empty_data_provider_source_organization_abbreviation.json +++ b/src/test/resources/bulk/01_gene/ER_15_empty_data_provider_source_organization_abbreviation.json @@ -98,6 +98,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_16_empty_data_provider_cross_reference_referenced_curie.json b/src/test/resources/bulk/01_gene/ER_16_empty_data_provider_cross_reference_referenced_curie.json index 81b5ef619..a688293eb 100644 --- a/src/test/resources/bulk/01_gene/ER_16_empty_data_provider_cross_reference_referenced_curie.json +++ b/src/test/resources/bulk/01_gene/ER_16_empty_data_provider_cross_reference_referenced_curie.json @@ -98,6 +98,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_17_empty_data_provider_cross_reference_display_name.json b/src/test/resources/bulk/01_gene/ER_17_empty_data_provider_cross_reference_display_name.json index d9b5da22c..071e4734e 100644 --- a/src/test/resources/bulk/01_gene/ER_17_empty_data_provider_cross_reference_display_name.json +++ b/src/test/resources/bulk/01_gene/ER_17_empty_data_provider_cross_reference_display_name.json @@ -98,6 +98,7 @@ "page_area": "homepage", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_18_empty_data_provider_cross_reference_prefix.json b/src/test/resources/bulk/01_gene/ER_18_empty_data_provider_cross_reference_prefix.json index 7f99cc953..1b06cc814 100644 --- a/src/test/resources/bulk/01_gene/ER_18_empty_data_provider_cross_reference_prefix.json +++ b/src/test/resources/bulk/01_gene/ER_18_empty_data_provider_cross_reference_prefix.json @@ -98,6 +98,7 @@ "display_name": "TEST:0001", "prefix": "" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_19_empty_data_provider_cross_reference_page_area.json b/src/test/resources/bulk/01_gene/ER_19_empty_data_provider_cross_reference_page_area.json index b18cfde30..21ec4146f 100644 --- a/src/test/resources/bulk/01_gene/ER_19_empty_data_provider_cross_reference_page_area.json +++ b/src/test/resources/bulk/01_gene/ER_19_empty_data_provider_cross_reference_page_area.json @@ -98,6 +98,7 @@ "page_area": "", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_20_empty_gene_secondary_id_secondary_id.json b/src/test/resources/bulk/01_gene/ER_20_empty_gene_secondary_id_secondary_id.json index c0b971f31..8b392c9a8 100644 --- a/src/test/resources/bulk/01_gene/ER_20_empty_gene_secondary_id_secondary_id.json +++ b/src/test/resources/bulk/01_gene/ER_20_empty_gene_secondary_id_secondary_id.json @@ -98,6 +98,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/ER_21_empty_gene_type.json b/src/test/resources/bulk/01_gene/ER_21_empty_gene_type.json new file mode 100644 index 000000000..84a28e1a8 --- /dev/null +++ b/src/test/resources/bulk/01_gene/ER_21_empty_gene_type.json @@ -0,0 +1,114 @@ +[ + { + "mod_entity_id": "GENETEST:ER21", + "taxon_curie": "NCBITaxon:6239", + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00", + "gene_symbol_dto": { + "display_text": "Tg1", + "format_text": "Tg1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "nomenclature_symbol", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + }, + "gene_full_name_dto": { + "display_text": "Test gene 1", + "format_text": "Test gene1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "full_name", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + }, + "gene_systematic_name_dto": { + "display_text": "Tg1.1", + "format_text": "Tg1.1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "systematic_name", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + }, + "gene_synonym_dtos": [ + { + "display_text": "Test gene synonym 1", + "format_text": "Test gene synonym 1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "unspecified", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + } + ], + "gene_secondary_id_dtos": [ + { + "secondary_id": "TEST:Secondary", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + } + ], + "data_provider_dto": { + "internal": false, + "obsolete": false, + "source_organization_abbreviation": "WB", + "cross_reference_dto": { + "referenced_curie": "TEST:0001", + "page_area": "homepage", + "display_name": "TEST:0001", + "prefix": "TEST" + } + }, + "cross_reference_dtos": [ + { + "internal": false, + "obsolete": false, + "referenced_curie": "TEST:Xref01", + "page_area": "homepage", + "display_name": "TEST:Xref01Display", + "prefix": "TEST" + } + ], + "gene_type_curie": "" + } +] diff --git a/src/test/resources/bulk/01_gene/IV_01_invalid_date_created.json b/src/test/resources/bulk/01_gene/IV_01_invalid_date_created.json index 6790bdcfa..a9b14b566 100644 --- a/src/test/resources/bulk/01_gene/IV_01_invalid_date_created.json +++ b/src/test/resources/bulk/01_gene/IV_01_invalid_date_created.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_02_invalid_date_updated.json b/src/test/resources/bulk/01_gene/IV_02_invalid_date_updated.json index a98c2819c..2d2c71be7 100644 --- a/src/test/resources/bulk/01_gene/IV_02_invalid_date_updated.json +++ b/src/test/resources/bulk/01_gene/IV_02_invalid_date_updated.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_03_invalid_taxon.json b/src/test/resources/bulk/01_gene/IV_03_invalid_taxon.json index 5e5b55f0b..bef77931c 100644 --- a/src/test/resources/bulk/01_gene/IV_03_invalid_taxon.json +++ b/src/test/resources/bulk/01_gene/IV_03_invalid_taxon.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_04_invalid_gene_symbol_name_type.json b/src/test/resources/bulk/01_gene/IV_04_invalid_gene_symbol_name_type.json index 9def50c3d..92b609db8 100644 --- a/src/test/resources/bulk/01_gene/IV_04_invalid_gene_symbol_name_type.json +++ b/src/test/resources/bulk/01_gene/IV_04_invalid_gene_symbol_name_type.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_05_invalid_gene_full_name_name_type.json b/src/test/resources/bulk/01_gene/IV_05_invalid_gene_full_name_name_type.json index d1c6b37a4..c1ad84955 100644 --- a/src/test/resources/bulk/01_gene/IV_05_invalid_gene_full_name_name_type.json +++ b/src/test/resources/bulk/01_gene/IV_05_invalid_gene_full_name_name_type.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_06_invalid_gene_systematic_name_name_type.json b/src/test/resources/bulk/01_gene/IV_06_invalid_gene_systematic_name_name_type.json index f8a85a8b2..a7dba910a 100644 --- a/src/test/resources/bulk/01_gene/IV_06_invalid_gene_systematic_name_name_type.json +++ b/src/test/resources/bulk/01_gene/IV_06_invalid_gene_systematic_name_name_type.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_07_invalid_gene_synonym_name_type.json b/src/test/resources/bulk/01_gene/IV_07_invalid_gene_synonym_name_type.json index 8c61f47ab..a7d85d4d7 100644 --- a/src/test/resources/bulk/01_gene/IV_07_invalid_gene_synonym_name_type.json +++ b/src/test/resources/bulk/01_gene/IV_07_invalid_gene_synonym_name_type.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_08_invalid_gene_symbol_synonym_scope.json b/src/test/resources/bulk/01_gene/IV_08_invalid_gene_symbol_synonym_scope.json index b696e0b3a..1505c46f4 100644 --- a/src/test/resources/bulk/01_gene/IV_08_invalid_gene_symbol_synonym_scope.json +++ b/src/test/resources/bulk/01_gene/IV_08_invalid_gene_symbol_synonym_scope.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_09_invalid_gene_full_name_synonym_scope.json b/src/test/resources/bulk/01_gene/IV_09_invalid_gene_full_name_synonym_scope.json index fbf328751..81e5be8d9 100644 --- a/src/test/resources/bulk/01_gene/IV_09_invalid_gene_full_name_synonym_scope.json +++ b/src/test/resources/bulk/01_gene/IV_09_invalid_gene_full_name_synonym_scope.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_10_invalid_gene_systematic_name_synonym_scope.json b/src/test/resources/bulk/01_gene/IV_10_invalid_gene_systematic_name_synonym_scope.json index 1f7b5a658..3781edcf5 100644 --- a/src/test/resources/bulk/01_gene/IV_10_invalid_gene_systematic_name_synonym_scope.json +++ b/src/test/resources/bulk/01_gene/IV_10_invalid_gene_systematic_name_synonym_scope.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_11_invalid_gene_synonym_synonym_scope.json b/src/test/resources/bulk/01_gene/IV_11_invalid_gene_synonym_synonym_scope.json index cacf4f6d6..3e96424f2 100644 --- a/src/test/resources/bulk/01_gene/IV_11_invalid_gene_synonym_synonym_scope.json +++ b/src/test/resources/bulk/01_gene/IV_11_invalid_gene_synonym_synonym_scope.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_12_invalid_gene_symbol_evidence.json b/src/test/resources/bulk/01_gene/IV_12_invalid_gene_symbol_evidence.json index d368562b6..1cf8558ae 100644 --- a/src/test/resources/bulk/01_gene/IV_12_invalid_gene_symbol_evidence.json +++ b/src/test/resources/bulk/01_gene/IV_12_invalid_gene_symbol_evidence.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_13_invalid_gene_full_name_evidence.json b/src/test/resources/bulk/01_gene/IV_13_invalid_gene_full_name_evidence.json index c08bcab4f..ad9055667 100644 --- a/src/test/resources/bulk/01_gene/IV_13_invalid_gene_full_name_evidence.json +++ b/src/test/resources/bulk/01_gene/IV_13_invalid_gene_full_name_evidence.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_14_invalid_gene_systematic_name_evidence.json b/src/test/resources/bulk/01_gene/IV_14_invalid_gene_systematic_name_evidence.json index d1bea9873..dba40ca74 100644 --- a/src/test/resources/bulk/01_gene/IV_14_invalid_gene_systematic_name_evidence.json +++ b/src/test/resources/bulk/01_gene/IV_14_invalid_gene_systematic_name_evidence.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_15_invalid_gene_synonym_evidence.json b/src/test/resources/bulk/01_gene/IV_15_invalid_gene_synonym_evidence.json index 0b93b444b..48b02ef70 100644 --- a/src/test/resources/bulk/01_gene/IV_15_invalid_gene_synonym_evidence.json +++ b/src/test/resources/bulk/01_gene/IV_15_invalid_gene_synonym_evidence.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_16_invalid_data_provider_source_organization_abbreviation.json b/src/test/resources/bulk/01_gene/IV_16_invalid_data_provider_source_organization_abbreviation.json index 025906d64..b721b0683 100644 --- a/src/test/resources/bulk/01_gene/IV_16_invalid_data_provider_source_organization_abbreviation.json +++ b/src/test/resources/bulk/01_gene/IV_16_invalid_data_provider_source_organization_abbreviation.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_17_invalid_data_provider_cross_reference_prefix.json b/src/test/resources/bulk/01_gene/IV_17_invalid_data_provider_cross_reference_prefix.json index 63e7fab44..1b243a094 100644 --- a/src/test/resources/bulk/01_gene/IV_17_invalid_data_provider_cross_reference_prefix.json +++ b/src/test/resources/bulk/01_gene/IV_17_invalid_data_provider_cross_reference_prefix.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "INVALID" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_18_invalid_data_provider_cross_reference_page_area.json b/src/test/resources/bulk/01_gene/IV_18_invalid_data_provider_cross_reference_page_area.json index b5b60c080..836618ff7 100644 --- a/src/test/resources/bulk/01_gene/IV_18_invalid_data_provider_cross_reference_page_area.json +++ b/src/test/resources/bulk/01_gene/IV_18_invalid_data_provider_cross_reference_page_area.json @@ -74,6 +74,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_19_invalid_gene_secondary_id_evidence.json b/src/test/resources/bulk/01_gene/IV_19_invalid_gene_secondary_id_evidence.json index 68469c5ea..817a30d26 100644 --- a/src/test/resources/bulk/01_gene/IV_19_invalid_gene_secondary_id_evidence.json +++ b/src/test/resources/bulk/01_gene/IV_19_invalid_gene_secondary_id_evidence.json @@ -98,6 +98,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/IV_20_invalid_gene_type.json b/src/test/resources/bulk/01_gene/IV_20_invalid_gene_type.json new file mode 100644 index 000000000..0380ddd42 --- /dev/null +++ b/src/test/resources/bulk/01_gene/IV_20_invalid_gene_type.json @@ -0,0 +1,114 @@ +[ + { + "mod_entity_id": "GENETEST:IV20", + "taxon_curie": "NCBITaxon:6239", + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00", + "gene_symbol_dto": { + "display_text": "Tg1", + "format_text": "Tg1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "nomenclature_symbol", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + }, + "gene_full_name_dto": { + "display_text": "Test gene 1", + "format_text": "Test gene1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "full_name", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + }, + "gene_systematic_name_dto": { + "display_text": "Tg1.1", + "format_text": "Tg1.1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "systematic_name", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + }, + "gene_synonym_dtos": [ + { + "display_text": "Test gene synonym 1", + "format_text": "Test gene synonym 1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "unspecified", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + } + ], + "gene_secondary_id_dtos": [ + { + "secondary_id": "TEST:Secondary", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + } + ], + "data_provider_dto": { + "internal": false, + "obsolete": false, + "source_organization_abbreviation": "WB", + "cross_reference_dto": { + "referenced_curie": "TEST:0001", + "page_area": "homepage", + "display_name": "TEST:0001", + "prefix": "TEST" + } + }, + "cross_reference_dtos": [ + { + "internal": false, + "obsolete": false, + "referenced_curie": "TEST:Xref01", + "page_area": "homepage", + "display_name": "TEST:Xref01Display", + "prefix": "TEST" + } + ], + "gene_type_curie": "SO:Invalid" + } +] diff --git a/src/test/resources/bulk/01_gene/MN_01_no_non_required_fields_level_1.json b/src/test/resources/bulk/01_gene/MN_01_no_non_required_fields_level_1.json index 26fa33dd6..12c44bf1f 100644 --- a/src/test/resources/bulk/01_gene/MN_01_no_non_required_fields_level_1.json +++ b/src/test/resources/bulk/01_gene/MN_01_no_non_required_fields_level_1.json @@ -28,6 +28,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MN_02_no_non_required_fields_level_2.json b/src/test/resources/bulk/01_gene/MN_02_no_non_required_fields_level_2.json index 03c4cc582..700d8903b 100644 --- a/src/test/resources/bulk/01_gene/MN_02_no_non_required_fields_level_2.json +++ b/src/test/resources/bulk/01_gene/MN_02_no_non_required_fields_level_2.json @@ -45,6 +45,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_01_no_mod_ids.json b/src/test/resources/bulk/01_gene/MR_01_no_mod_ids.json index 005c6fbae..58d4ba5cf 100644 --- a/src/test/resources/bulk/01_gene/MR_01_no_mod_ids.json +++ b/src/test/resources/bulk/01_gene/MR_01_no_mod_ids.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_02_no_taxon.json b/src/test/resources/bulk/01_gene/MR_02_no_taxon.json index 1ddf2c697..53257323d 100644 --- a/src/test/resources/bulk/01_gene/MR_02_no_taxon.json +++ b/src/test/resources/bulk/01_gene/MR_02_no_taxon.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_03_no_gene_symbol.json b/src/test/resources/bulk/01_gene/MR_03_no_gene_symbol.json index ef2ac4272..dfe024261 100644 --- a/src/test/resources/bulk/01_gene/MR_03_no_gene_symbol.json +++ b/src/test/resources/bulk/01_gene/MR_03_no_gene_symbol.json @@ -64,6 +64,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_04_no_gene_symbol_display_text.json b/src/test/resources/bulk/01_gene/MR_04_no_gene_symbol_display_text.json index cb3c917b0..fff9ac49c 100644 --- a/src/test/resources/bulk/01_gene/MR_04_no_gene_symbol_display_text.json +++ b/src/test/resources/bulk/01_gene/MR_04_no_gene_symbol_display_text.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_05_no_gene_full_name_display_text.json b/src/test/resources/bulk/01_gene/MR_05_no_gene_full_name_display_text.json index 4439345a8..2bc4bf601 100644 --- a/src/test/resources/bulk/01_gene/MR_05_no_gene_full_name_display_text.json +++ b/src/test/resources/bulk/01_gene/MR_05_no_gene_full_name_display_text.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_06_no_gene_systematic_name_display_text.json b/src/test/resources/bulk/01_gene/MR_06_no_gene_systematic_name_display_text.json index f926be018..0213b8ac3 100644 --- a/src/test/resources/bulk/01_gene/MR_06_no_gene_systematic_name_display_text.json +++ b/src/test/resources/bulk/01_gene/MR_06_no_gene_systematic_name_display_text.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_07_no_gene_synonym_display_text.json b/src/test/resources/bulk/01_gene/MR_07_no_gene_synonym_display_text.json index 8be375cf7..b99063361 100644 --- a/src/test/resources/bulk/01_gene/MR_07_no_gene_synonym_display_text.json +++ b/src/test/resources/bulk/01_gene/MR_07_no_gene_synonym_display_text.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_08_no_gene_symbol_format_text.json b/src/test/resources/bulk/01_gene/MR_08_no_gene_symbol_format_text.json index 7a1bbac7e..320cb8664 100644 --- a/src/test/resources/bulk/01_gene/MR_08_no_gene_symbol_format_text.json +++ b/src/test/resources/bulk/01_gene/MR_08_no_gene_symbol_format_text.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_09_no_gene_full_name_format_text.json b/src/test/resources/bulk/01_gene/MR_09_no_gene_full_name_format_text.json index 82981897c..52e04193e 100644 --- a/src/test/resources/bulk/01_gene/MR_09_no_gene_full_name_format_text.json +++ b/src/test/resources/bulk/01_gene/MR_09_no_gene_full_name_format_text.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_10_no_gene_systematic_name_format_text.json b/src/test/resources/bulk/01_gene/MR_10_no_gene_systematic_name_format_text.json index e0ebfe171..b148257cc 100644 --- a/src/test/resources/bulk/01_gene/MR_10_no_gene_systematic_name_format_text.json +++ b/src/test/resources/bulk/01_gene/MR_10_no_gene_systematic_name_format_text.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_11_no_gene_synonym_format_text.json b/src/test/resources/bulk/01_gene/MR_11_no_gene_synonym_format_text.json index 39fda4f39..11104998d 100644 --- a/src/test/resources/bulk/01_gene/MR_11_no_gene_synonym_format_text.json +++ b/src/test/resources/bulk/01_gene/MR_11_no_gene_synonym_format_text.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_12_no_gene_symbol_name_type.json b/src/test/resources/bulk/01_gene/MR_12_no_gene_symbol_name_type.json index de01c6279..d6ae4616d 100644 --- a/src/test/resources/bulk/01_gene/MR_12_no_gene_symbol_name_type.json +++ b/src/test/resources/bulk/01_gene/MR_12_no_gene_symbol_name_type.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_13_no_gene_full_name_name_type.json b/src/test/resources/bulk/01_gene/MR_13_no_gene_full_name_name_type.json index 42ab3d545..dcc2cb915 100644 --- a/src/test/resources/bulk/01_gene/MR_13_no_gene_full_name_name_type.json +++ b/src/test/resources/bulk/01_gene/MR_13_no_gene_full_name_name_type.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_14_no_gene_systematic_name_name_type.json b/src/test/resources/bulk/01_gene/MR_14_no_gene_systematic_name_name_type.json index 4da1983b0..e52147494 100644 --- a/src/test/resources/bulk/01_gene/MR_14_no_gene_systematic_name_name_type.json +++ b/src/test/resources/bulk/01_gene/MR_14_no_gene_systematic_name_name_type.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_15_no_gene_synonym_name_type.json b/src/test/resources/bulk/01_gene/MR_15_no_gene_synonym_name_type.json index 5a43833dc..b90da4e15 100644 --- a/src/test/resources/bulk/01_gene/MR_15_no_gene_synonym_name_type.json +++ b/src/test/resources/bulk/01_gene/MR_15_no_gene_synonym_name_type.json @@ -73,6 +73,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_16_no_data_provider.json b/src/test/resources/bulk/01_gene/MR_16_no_data_provider.json index e11ca8af1..190d123d6 100644 --- a/src/test/resources/bulk/01_gene/MR_16_no_data_provider.json +++ b/src/test/resources/bulk/01_gene/MR_16_no_data_provider.json @@ -87,6 +87,7 @@ "date_created": "2022-03-09T22:10:12+00:00", "date_updated": "2022-03-10T22:10:12+00:00" } - ] + ], + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_17_no_data_provider_source_organization_abbreviation.json b/src/test/resources/bulk/01_gene/MR_17_no_data_provider_source_organization_abbreviation.json index e9fb337b2..e0181c302 100644 --- a/src/test/resources/bulk/01_gene/MR_17_no_data_provider_source_organization_abbreviation.json +++ b/src/test/resources/bulk/01_gene/MR_17_no_data_provider_source_organization_abbreviation.json @@ -97,6 +97,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_18_no_data_provider_cross_reference_referenced_curie.json b/src/test/resources/bulk/01_gene/MR_18_no_data_provider_cross_reference_referenced_curie.json index a10b9fd6c..984655b9a 100644 --- a/src/test/resources/bulk/01_gene/MR_18_no_data_provider_cross_reference_referenced_curie.json +++ b/src/test/resources/bulk/01_gene/MR_18_no_data_provider_cross_reference_referenced_curie.json @@ -97,6 +97,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_19_no_data_provider_cross_reference_display_name.json b/src/test/resources/bulk/01_gene/MR_19_no_data_provider_cross_reference_display_name.json index 9668dfab0..d9ca75371 100644 --- a/src/test/resources/bulk/01_gene/MR_19_no_data_provider_cross_reference_display_name.json +++ b/src/test/resources/bulk/01_gene/MR_19_no_data_provider_cross_reference_display_name.json @@ -97,6 +97,7 @@ "page_area": "homepage", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_20_no_data_provider_cross_reference_prefix.json b/src/test/resources/bulk/01_gene/MR_20_no_data_provider_cross_reference_prefix.json index 34c91a9a3..310a526f9 100644 --- a/src/test/resources/bulk/01_gene/MR_20_no_data_provider_cross_reference_prefix.json +++ b/src/test/resources/bulk/01_gene/MR_20_no_data_provider_cross_reference_prefix.json @@ -97,6 +97,7 @@ "page_area": "homepage", "display_name": "TEST:0001" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_21_no_data_provider_cross_reference_page_area.json b/src/test/resources/bulk/01_gene/MR_21_no_data_provider_cross_reference_page_area.json index 79ec357c4..20d35e158 100644 --- a/src/test/resources/bulk/01_gene/MR_21_no_data_provider_cross_reference_page_area.json +++ b/src/test/resources/bulk/01_gene/MR_21_no_data_provider_cross_reference_page_area.json @@ -97,6 +97,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_22_no_gene_secondary_id_secondary_id.json b/src/test/resources/bulk/01_gene/MR_22_no_gene_secondary_id_secondary_id.json index 7574129c8..08815a027 100644 --- a/src/test/resources/bulk/01_gene/MR_22_no_gene_secondary_id_secondary_id.json +++ b/src/test/resources/bulk/01_gene/MR_22_no_gene_secondary_id_secondary_id.json @@ -97,6 +97,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/MR_23_no_gene_type.json b/src/test/resources/bulk/01_gene/MR_23_no_gene_type.json new file mode 100644 index 000000000..6ea437290 --- /dev/null +++ b/src/test/resources/bulk/01_gene/MR_23_no_gene_type.json @@ -0,0 +1,113 @@ +[ + { + "mod_entity_id": "GENETEST:MR23", + "taxon_curie": "NCBITaxon:6239", + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00", + "gene_symbol_dto": { + "display_text": "Tg1", + "format_text": "Tg1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "nomenclature_symbol", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + }, + "gene_full_name_dto": { + "display_text": "Test gene 1", + "format_text": "Test gene1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "full_name", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + }, + "gene_systematic_name_dto": { + "display_text": "Tg1.1", + "format_text": "Tg1.1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "systematic_name", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + }, + "gene_synonym_dtos": [ + { + "display_text": "Test gene synonym 1", + "format_text": "Test gene synonym 1", + "synonym_scope_name": "exact", + "synonym_url": "https://alliancegenome.org/test", + "name_type_name": "unspecified", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + } + ], + "gene_secondary_id_dtos": [ + { + "secondary_id": "TEST:Secondary", + "evidence_curies": [ + "PMID:25920550" + ], + "internal": true, + "obsolete": true, + "created_by_curie": "GENETEST:Person0001", + "updated_by_curie": "GENETEST:Person0002", + "date_created": "2022-03-09T22:10:12+00:00", + "date_updated": "2022-03-10T22:10:12+00:00" + } + ], + "data_provider_dto": { + "internal": false, + "obsolete": false, + "source_organization_abbreviation": "WB", + "cross_reference_dto": { + "referenced_curie": "TEST:0001", + "page_area": "homepage", + "display_name": "TEST:0001", + "prefix": "TEST" + } + }, + "cross_reference_dtos": [ + { + "internal": false, + "obsolete": false, + "referenced_curie": "TEST:Xref01", + "page_area": "homepage", + "display_name": "TEST:Xref01Display", + "prefix": "TEST" + } + ] + } +] diff --git a/src/test/resources/bulk/01_gene/UD_01_update_all_except_default_fields.json b/src/test/resources/bulk/01_gene/UD_01_update_all_except_default_fields.json index 602bd2553..a545e0d26 100644 --- a/src/test/resources/bulk/01_gene/UD_01_update_all_except_default_fields.json +++ b/src/test/resources/bulk/01_gene/UD_01_update_all_except_default_fields.json @@ -98,6 +98,7 @@ "display_name": "TEST2:Xref02Display", "prefix": "TEST2" } - ] + ], + "gene_type_curie": "SO:0000336" } ] diff --git a/src/test/resources/bulk/01_gene/UE_01_update_empty_non_required_fields.json b/src/test/resources/bulk/01_gene/UE_01_update_empty_non_required_fields.json index f3c43c1a4..ee6325874 100644 --- a/src/test/resources/bulk/01_gene/UE_01_update_empty_non_required_fields.json +++ b/src/test/resources/bulk/01_gene/UE_01_update_empty_non_required_fields.json @@ -87,6 +87,7 @@ "prefix": "TEST" } }, - "cross_reference_dtos": [] + "cross_reference_dtos": [], + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/UM_01_update_no_non_required_fields_level_1.json b/src/test/resources/bulk/01_gene/UM_01_update_no_non_required_fields_level_1.json index c22bf5575..908fb29df 100644 --- a/src/test/resources/bulk/01_gene/UM_01_update_no_non_required_fields_level_1.json +++ b/src/test/resources/bulk/01_gene/UM_01_update_no_non_required_fields_level_1.json @@ -28,6 +28,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/UM_02_update_no_non_required_fields_level_2.json b/src/test/resources/bulk/01_gene/UM_02_update_no_non_required_fields_level_2.json index e4df9b57c..8b73ec4ae 100644 --- a/src/test/resources/bulk/01_gene/UM_02_update_no_non_required_fields_level_2.json +++ b/src/test/resources/bulk/01_gene/UM_02_update_no_non_required_fields_level_2.json @@ -39,6 +39,7 @@ "internal": false, "obsolete": false, "source_organization_abbreviation": "WB" - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/VT_01_valid_taxon_for_HUMAN.json b/src/test/resources/bulk/01_gene/VT_01_valid_taxon_for_HUMAN.json index 6e1f2ac08..e750a3391 100644 --- a/src/test/resources/bulk/01_gene/VT_01_valid_taxon_for_HUMAN.json +++ b/src/test/resources/bulk/01_gene/VT_01_valid_taxon_for_HUMAN.json @@ -98,6 +98,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] diff --git a/src/test/resources/bulk/01_gene/VT_02_valid_taxon_for_RGD.json b/src/test/resources/bulk/01_gene/VT_02_valid_taxon_for_RGD.json index 3bd4816ad..ad676a5a0 100644 --- a/src/test/resources/bulk/01_gene/VT_02_valid_taxon_for_RGD.json +++ b/src/test/resources/bulk/01_gene/VT_02_valid_taxon_for_RGD.json @@ -98,6 +98,7 @@ "display_name": "TEST:0001", "prefix": "TEST" } - } + }, + "gene_type_curie": "SO:0001217" } ] From ed38d452d8109a439a114ef295c3aeeb67b4f28a Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 4 Jul 2024 16:29:32 +0100 Subject: [PATCH 22/82] Prettify --- src/main/cliapp/src/constants/SortFields.js | 2 +- .../cliapp/src/containers/genesPage/mockData/mockData.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/cliapp/src/constants/SortFields.js b/src/main/cliapp/src/constants/SortFields.js index 8c0471a92..4e7f7ed92 100644 --- a/src/main/cliapp/src/constants/SortFields.js +++ b/src/main/cliapp/src/constants/SortFields.js @@ -73,7 +73,7 @@ export const SORT_FIELDS = Object.freeze([ 'geneSymbol.displayText', 'geneSecondaryIds.secondaryId', 'geneSystematicName.displayText', - "geneType.name", + 'geneType.name', 'inchi', 'inchiKey', 'iupac', diff --git a/src/main/cliapp/src/containers/genesPage/mockData/mockData.js b/src/main/cliapp/src/containers/genesPage/mockData/mockData.js index 15cd71d69..d09b3efe9 100644 --- a/src/main/cliapp/src/containers/genesPage/mockData/mockData.js +++ b/src/main/cliapp/src/containers/genesPage/mockData/mockData.js @@ -31,9 +31,9 @@ export const data = { geneType: { internal: false, obsolete: false, - curie: "SO:0001272", - name: "tRNA_gene", - id: 25665 + curie: 'SO:0001272', + name: 'tRNA_gene', + id: 25665, }, dataProvider: { internal: false, From 4ed7a986ec9939af0f0082ff251c515ec4180ddf Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 4 Jul 2024 16:36:22 +0100 Subject: [PATCH 23/82] Fix UI test --- .../src/containers/genesPage/__tests__/GenesTable.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/cliapp/src/containers/genesPage/__tests__/GenesTable.test.js b/src/main/cliapp/src/containers/genesPage/__tests__/GenesTable.test.js index dc369c34e..2b586bd35 100644 --- a/src/main/cliapp/src/containers/genesPage/__tests__/GenesTable.test.js +++ b/src/main/cliapp/src/containers/genesPage/__tests__/GenesTable.test.js @@ -46,7 +46,7 @@ describe('', () => { const systematicNameTd = await result.findByText('C35C5.5'); const taxonTd = await result.findByText(/Caenorhabditis elegans/i); const xrefsTd = await result.findByText(/WBGene00003771Xref \(gene\)/); - const geneTypeTd = await result.findByText(/tRNA_gene \(SO:0001271\)/i); + const geneTypeTd = await result.findByText(/protein_coding_gene/i); await waitFor(() => { expect(modEntityIdTd).toBeInTheDocument(); From 3fd08cd03db8c05b41c85666019adcf33abfe883 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Mon, 8 Jul 2024 22:56:21 +0100 Subject: [PATCH 24/82] Replace DPO ontology with full FlyBase controlled vocabulary --- .../src/containers/layout/SiteLayout.js | 2 +- src/main/cliapp/src/routes.js | 4 +-- .../cliapp/src/service/DataLoadService.js | 2 +- ...oller.java => FbcvTermCrudController.java} | 16 ++++++------ .../{DpoTermDAO.java => FbcvTermDAO.java} | 8 +++--- .../enums/OntologyBulkLoadType.java | 4 +-- ...erface.java => FbcvTermCrudInterface.java} | 6 ++--- .../jobs/executors/OntologyExecutor.java | 10 ++++---- .../ontology/{DPOTerm.java => FBCVTerm.java} | 4 +-- ...oTermService.java => FbcvTermService.java} | 10 ++++---- .../v0.36.0.3__fbcv_ontology_load.sql | 25 +++++++++++++++++++ 11 files changed, 58 insertions(+), 33 deletions(-) rename src/main/java/org/alliancegenome/curation_api/controllers/crud/ontology/{DpoTermCrudController.java => FbcvTermCrudController.java} (52%) rename src/main/java/org/alliancegenome/curation_api/dao/ontology/{DpoTermDAO.java => FbcvTermDAO.java} (51%) rename src/main/java/org/alliancegenome/curation_api/interfaces/crud/ontology/{DpoTermCrudInterface.java => FbcvTermCrudInterface.java} (71%) rename src/main/java/org/alliancegenome/curation_api/model/entities/ontology/{DPOTerm.java => FBCVTerm.java} (88%) rename src/main/java/org/alliancegenome/curation_api/services/ontology/{DpoTermService.java => FbcvTermService.java} (55%) create mode 100644 src/main/resources/db/migration/v0.36.0.3__fbcv_ontology_load.sql diff --git a/src/main/cliapp/src/containers/layout/SiteLayout.js b/src/main/cliapp/src/containers/layout/SiteLayout.js index 5651a92d1..7c8838a6b 100644 --- a/src/main/cliapp/src/containers/layout/SiteLayout.js +++ b/src/main/cliapp/src/containers/layout/SiteLayout.js @@ -282,6 +282,7 @@ export const SiteLayout = (props) => { }, ], }, + { label: 'Flybase Controlled Vocabulary (FBcv)', icon: 'pi pi-fw pi-home', to: '/ontology/fbcv' }, { label: 'Gene Ontology (GO)', icon: 'pi pi-fw pi-home', to: '/ontology/go' }, { label: 'Genotype Ontology (GENO)', icon: 'pi pi-fw pi-home', to: '/ontology/geno' }, { label: 'Measurement Method Ontology (MMO)', icon: 'pi pi-fw pi-home', to: '/ontology/mmo' }, @@ -304,7 +305,6 @@ export const SiteLayout = (props) => { icon: 'pi pi-fw pi-home', to: '/ontology/wbpheno', }, - { label: 'Drosophila Phenotype Ontology (DPO)', icon: 'pi pi-fw pi-home', to: '/ontology/dpo' }, { label: 'Human Phenotype Ontology (HP)', icon: 'pi pi-fw pi-home', to: '/ontology/hp' }, { label: 'Mammalian Phenotype Ontology (MP)', icon: 'pi pi-fw pi-home', to: '/ontology/mp' }, { label: 'Xenopus Phenotype Ontology (XPO)', icon: 'pi pi-fw pi-home', to: '/ontology/xpo' }, diff --git a/src/main/cliapp/src/routes.js b/src/main/cliapp/src/routes.js index 740db89a3..e771b5c63 100644 --- a/src/main/cliapp/src/routes.js +++ b/src/main/cliapp/src/routes.js @@ -472,10 +472,10 @@ export default ( )} /> ( - + )} /> diff --git a/src/main/cliapp/src/service/DataLoadService.js b/src/main/cliapp/src/service/DataLoadService.js index 90612fe46..5e5b729fc 100644 --- a/src/main/cliapp/src/service/DataLoadService.js +++ b/src/main/cliapp/src/service/DataLoadService.js @@ -122,9 +122,9 @@ export class DataLoadService extends BaseAuthService { 'CMO', 'DAO', 'DO', - 'DPO', 'ECO', 'EMAPA', + 'FBCV', 'FBDV', 'GENO', 'GO', diff --git a/src/main/java/org/alliancegenome/curation_api/controllers/crud/ontology/DpoTermCrudController.java b/src/main/java/org/alliancegenome/curation_api/controllers/crud/ontology/FbcvTermCrudController.java similarity index 52% rename from src/main/java/org/alliancegenome/curation_api/controllers/crud/ontology/DpoTermCrudController.java rename to src/main/java/org/alliancegenome/curation_api/controllers/crud/ontology/FbcvTermCrudController.java index 228eb9190..d15a221be 100644 --- a/src/main/java/org/alliancegenome/curation_api/controllers/crud/ontology/DpoTermCrudController.java +++ b/src/main/java/org/alliancegenome/curation_api/controllers/crud/ontology/FbcvTermCrudController.java @@ -1,28 +1,28 @@ package org.alliancegenome.curation_api.controllers.crud.ontology; import org.alliancegenome.curation_api.controllers.base.BaseOntologyTermController; -import org.alliancegenome.curation_api.dao.ontology.DpoTermDAO; -import org.alliancegenome.curation_api.interfaces.crud.ontology.DpoTermCrudInterface; -import org.alliancegenome.curation_api.model.entities.ontology.DPOTerm; +import org.alliancegenome.curation_api.dao.ontology.FbcvTermDAO; +import org.alliancegenome.curation_api.interfaces.crud.ontology.FbcvTermCrudInterface; +import org.alliancegenome.curation_api.model.entities.ontology.FBCVTerm; import org.alliancegenome.curation_api.services.helpers.GenericOntologyLoadConfig; -import org.alliancegenome.curation_api.services.ontology.DpoTermService; +import org.alliancegenome.curation_api.services.ontology.FbcvTermService; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @RequestScoped -public class DpoTermCrudController extends BaseOntologyTermController implements DpoTermCrudInterface { +public class FbcvTermCrudController extends BaseOntologyTermController implements FbcvTermCrudInterface { @Inject - DpoTermService dpoTermService; + FbcvTermService fbcvTermService; @Override @PostConstruct public void init() { GenericOntologyLoadConfig config = new GenericOntologyLoadConfig(); - config.getAltNameSpaces().add("phenotypic_class"); - setService(dpoTermService, DPOTerm.class, config); + config.setLoadOnlyIRIPrefix("FBcv"); + setService(fbcvTermService, FBCVTerm.class, config); } } diff --git a/src/main/java/org/alliancegenome/curation_api/dao/ontology/DpoTermDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/ontology/FbcvTermDAO.java similarity index 51% rename from src/main/java/org/alliancegenome/curation_api/dao/ontology/DpoTermDAO.java rename to src/main/java/org/alliancegenome/curation_api/dao/ontology/FbcvTermDAO.java index e50a341a1..7047be3ac 100644 --- a/src/main/java/org/alliancegenome/curation_api/dao/ontology/DpoTermDAO.java +++ b/src/main/java/org/alliancegenome/curation_api/dao/ontology/FbcvTermDAO.java @@ -1,15 +1,15 @@ package org.alliancegenome.curation_api.dao.ontology; import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; -import org.alliancegenome.curation_api.model.entities.ontology.DPOTerm; +import org.alliancegenome.curation_api.model.entities.ontology.FBCVTerm; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped -public class DpoTermDAO extends BaseSQLDAO { +public class FbcvTermDAO extends BaseSQLDAO { - protected DpoTermDAO() { - super(DPOTerm.class); + protected FbcvTermDAO() { + super(FBCVTerm.class); } } diff --git a/src/main/java/org/alliancegenome/curation_api/enums/OntologyBulkLoadType.java b/src/main/java/org/alliancegenome/curation_api/enums/OntologyBulkLoadType.java index 683108e9a..666919be6 100644 --- a/src/main/java/org/alliancegenome/curation_api/enums/OntologyBulkLoadType.java +++ b/src/main/java/org/alliancegenome/curation_api/enums/OntologyBulkLoadType.java @@ -8,7 +8,7 @@ import org.alliancegenome.curation_api.model.entities.ontology.CMOTerm; import org.alliancegenome.curation_api.model.entities.ontology.DAOTerm; import org.alliancegenome.curation_api.model.entities.ontology.DOTerm; -import org.alliancegenome.curation_api.model.entities.ontology.DPOTerm; +import org.alliancegenome.curation_api.model.entities.ontology.FBCVTerm; import org.alliancegenome.curation_api.model.entities.ontology.ECOTerm; import org.alliancegenome.curation_api.model.entities.ontology.EMAPATerm; import org.alliancegenome.curation_api.model.entities.ontology.FBDVTerm; @@ -75,7 +75,7 @@ public enum OntologyBulkLoadType { WBPheno(WBPhenotypeTerm.class), VT(VTTerm.class), HP(HPTerm.class), - DPO(DPOTerm.class), + FBCV(FBCVTerm.class), MMO(MMOTerm.class), APO(APOTerm.class), MI(MITerm.class), diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/ontology/DpoTermCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/ontology/FbcvTermCrudInterface.java similarity index 71% rename from src/main/java/org/alliancegenome/curation_api/interfaces/crud/ontology/DpoTermCrudInterface.java rename to src/main/java/org/alliancegenome/curation_api/interfaces/crud/ontology/FbcvTermCrudInterface.java index a393a22c9..ca2f17636 100644 --- a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/ontology/DpoTermCrudInterface.java +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/ontology/FbcvTermCrudInterface.java @@ -1,7 +1,7 @@ package org.alliancegenome.curation_api.interfaces.crud.ontology; import org.alliancegenome.curation_api.interfaces.base.BaseOntologyTermCrudInterface; -import org.alliancegenome.curation_api.model.entities.ontology.DPOTerm; +import org.alliancegenome.curation_api.model.entities.ontology.FBCVTerm; import org.eclipse.microprofile.openapi.annotations.tags.Tag; import jakarta.ws.rs.Consumes; @@ -9,10 +9,10 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; -@Path("/dpoterm") +@Path("/fbcvterm") @Tag(name = "CRUD - Ontology") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public interface DpoTermCrudInterface extends BaseOntologyTermCrudInterface { +public interface FbcvTermCrudInterface extends BaseOntologyTermCrudInterface { } \ No newline at end of file diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/OntologyExecutor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/OntologyExecutor.java index f6cc9d2b3..cbd396d53 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/OntologyExecutor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/OntologyExecutor.java @@ -21,7 +21,7 @@ import org.alliancegenome.curation_api.services.ontology.CmoTermService; import org.alliancegenome.curation_api.services.ontology.DaoTermService; import org.alliancegenome.curation_api.services.ontology.DoTermService; -import org.alliancegenome.curation_api.services.ontology.DpoTermService; +import org.alliancegenome.curation_api.services.ontology.FbcvTermService; import org.alliancegenome.curation_api.services.ontology.EcoTermService; import org.alliancegenome.curation_api.services.ontology.EmapaTermService; import org.alliancegenome.curation_api.services.ontology.FbdvTermService; @@ -95,7 +95,7 @@ public class OntologyExecutor { @Inject ObiTermService obiTermService; @Inject PatoTermService patoTermService; @Inject WbPhenotypeTermService wbPhenotypeTermService; - @Inject DpoTermService dpoTermService; + @Inject FbcvTermService fbcvTermService; @Inject MmoTermService mmoTermService; @Inject ApoTermService apoTermService; @Inject MiTermService miTermService; @@ -202,9 +202,9 @@ public void execLoad(BulkLoadFile bulkLoadFile) throws Exception { config.setLoadOnlyIRIPrefix("HP"); processTerms(bulkLoadFile, hpTermService, config); } - case DPO -> { - config.getAltNameSpaces().add("phenotypic_class"); - processTerms(bulkLoadFile, dpoTermService, config); + case FBCV -> { + config.setLoadOnlyIRIPrefix("FBcv"); + processTerms(bulkLoadFile, fbcvTermService, config); } case MMO -> processTerms(bulkLoadFile, mmoTermService, config); case APO -> { diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/DPOTerm.java b/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/FBCVTerm.java similarity index 88% rename from src/main/java/org/alliancegenome/curation_api/model/entities/ontology/DPOTerm.java rename to src/main/java/org/alliancegenome/curation_api/model/entities/ontology/FBCVTerm.java index ab512be7f..0e4d4fa4d 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/DPOTerm.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/FBCVTerm.java @@ -14,7 +14,7 @@ @Data @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) @ToString(callSuper = true) -@AGRCurationSchemaVersion(min = LinkMLSchemaConstants.MIN_ONTOLOGY_RELEASE, max = LinkMLSchemaConstants.MAX_ONTOLOGY_RELEASE, dependencies = { PhenotypeTerm.class }) -public class DPOTerm extends PhenotypeTerm { +@AGRCurationSchemaVersion(min = LinkMLSchemaConstants.MIN_ONTOLOGY_RELEASE, max = LinkMLSchemaConstants.MAX_ONTOLOGY_RELEASE, dependencies = { OntologyTerm.class }) +public class FBCVTerm extends OntologyTerm { } diff --git a/src/main/java/org/alliancegenome/curation_api/services/ontology/DpoTermService.java b/src/main/java/org/alliancegenome/curation_api/services/ontology/FbcvTermService.java similarity index 55% rename from src/main/java/org/alliancegenome/curation_api/services/ontology/DpoTermService.java rename to src/main/java/org/alliancegenome/curation_api/services/ontology/FbcvTermService.java index b1ed0326e..92b1de910 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/ontology/DpoTermService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/ontology/FbcvTermService.java @@ -1,7 +1,7 @@ package org.alliancegenome.curation_api.services.ontology; -import org.alliancegenome.curation_api.dao.ontology.DpoTermDAO; -import org.alliancegenome.curation_api.model.entities.ontology.DPOTerm; +import org.alliancegenome.curation_api.dao.ontology.FbcvTermDAO; +import org.alliancegenome.curation_api.model.entities.ontology.FBCVTerm; import org.alliancegenome.curation_api.services.base.BaseOntologyTermService; import jakarta.annotation.PostConstruct; @@ -9,15 +9,15 @@ import jakarta.inject.Inject; @RequestScoped -public class DpoTermService extends BaseOntologyTermService { +public class FbcvTermService extends BaseOntologyTermService { @Inject - DpoTermDAO dpoTermDAO; + FbcvTermDAO fbcvTermDAO; @Override @PostConstruct protected void init() { - setSQLDao(dpoTermDAO); + setSQLDao(fbcvTermDAO); } } diff --git a/src/main/resources/db/migration/v0.36.0.3__fbcv_ontology_load.sql b/src/main/resources/db/migration/v0.36.0.3__fbcv_ontology_load.sql new file mode 100644 index 000000000..bd39d30c7 --- /dev/null +++ b/src/main/resources/db/migration/v0.36.0.3__fbcv_ontology_load.sql @@ -0,0 +1,25 @@ +UPDATE ontologyterm SET ontologytermtype = 'FBCVTerm' WHERE ontologytermtype = 'DPOTerm'; + +DELETE FROM bulkloadfileexception WHERE bulkloadfilehistory_id IN ( + SELECT id FROM bulkloadfilehistory WHERE bulkloadfile_id IN ( + SELECT id FROM bulkloadfile WHERE bulkload_id = ( + SELECT id FROM bulkload WHERE ontologytype = 'DPO' + ) + ) +); + +DELETE FROM bulkloadfilehistory WHERE bulkloadfile_id IN ( + SELECT id FROM bulkloadfile WHERE bulkload_id = ( + SELECT id FROM bulkload WHERE ontologytype = 'DPO' + ) +); + +DELETE FROM bulkloadfile WHERE bulkload_id = ( + SELECT id FROM bulkload WHERE ontologytype = 'DPO' +); + +UPDATE bulkurlload SET bulkloadurl = 'http://purl.obolibrary.org/obo/fbcv.owl' WHERE id = ( + SELECT id FROM bulkload WHERE ontologytype = 'DPO' +); + +UPDATE bulkload SET name = 'FBcv Ontology Load', ontologytype = 'FBCV', bulkloadstatus = 'STOPPED' WHERE ontologytype = 'DPO'; From c2534bc3caf5a468475a79fad873a8245b515713 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Tue, 2 Jul 2024 14:24:55 -0500 Subject: [PATCH 25/82] SCRUM-4185 updated executor, service, and validator --- ...equenceTargetingReagentCrudController.java | 2 +- .../SequenceTargetingReagentExecutor.java | 95 +++++++++++++++++-- .../SequenceTargetingReagentService.java | 70 ++++++++++++++ ...quenceTargetingReagentFmsDTOValidator.java | 69 +++++++++++++- 4 files changed, 221 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/controllers/crud/SequenceTargetingReagentCrudController.java b/src/main/java/org/alliancegenome/curation_api/controllers/crud/SequenceTargetingReagentCrudController.java index e3d52bf3c..61afd749a 100644 --- a/src/main/java/org/alliancegenome/curation_api/controllers/crud/SequenceTargetingReagentCrudController.java +++ b/src/main/java/org/alliancegenome/curation_api/controllers/crud/SequenceTargetingReagentCrudController.java @@ -30,7 +30,7 @@ protected void init() { @Override public APIResponse updateSequenceTargetingReagent(String dataProvider, SequenceTargetingReagentIngestFmsDTO sqtrFmsDTO) { - return sqtrExecutor.runLoadApi(sqtrService, dataProvider, sqtrFmsDTO.getData()); + return sqtrExecutor.runLoadApi(dataProvider, sqtrFmsDTO.getData()); } } diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java index 3e48a6edd..69e538733 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java @@ -6,13 +6,19 @@ import java.util.zip.GZIPInputStream; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; +import org.alliancegenome.curation_api.exceptions.ObjectUpdateException.ObjectUpdateExceptionData; import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkFMSLoad; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFile; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; +import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentIngestFmsDTO; +import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.response.LoadHistoryResponce; import org.alliancegenome.curation_api.services.SequenceTargetingReagentService; +import org.alliancegenome.curation_api.util.ProcessDisplayHelper; import org.apache.commons.lang3.StringUtils; import jakarta.enterprise.context.ApplicationScoped; @@ -29,33 +35,38 @@ public void execLoad(BulkLoadFile bulkLoadFile) { BulkFMSLoad fms = (BulkFMSLoad) bulkLoadFile.getBulkLoad(); SequenceTargetingReagentIngestFmsDTO sqtrIngestFmsDTO = mapper.readValue( - new GZIPInputStream(new FileInputStream(bulkLoadFile.getLocalFilePath())), SequenceTargetingReagentIngestFmsDTO.class); + new GZIPInputStream(new FileInputStream(bulkLoadFile.getLocalFilePath())), + SequenceTargetingReagentIngestFmsDTO.class); bulkLoadFile.setRecordCount(sqtrIngestFmsDTO.getData().size()); - AGRCurationSchemaVersion version = SequenceTargetingReagent.class.getAnnotation(AGRCurationSchemaVersion.class); + AGRCurationSchemaVersion version = SequenceTargetingReagent.class + .getAnnotation(AGRCurationSchemaVersion.class); bulkLoadFile.setLinkMLSchemaVersion(version.max()); - if (sqtrIngestFmsDTO.getMetaData() != null && StringUtils.isNotBlank(sqtrIngestFmsDTO.getMetaData().getRelease())) { + if (sqtrIngestFmsDTO.getMetaData() != null + && StringUtils.isNotBlank(sqtrIngestFmsDTO.getMetaData().getRelease())) { bulkLoadFile.setAllianceMemberReleaseVersion(sqtrIngestFmsDTO.getMetaData().getRelease()); } BackendBulkDataProvider dataProvider = BackendBulkDataProvider.valueOf(fms.getFmsDataSubType()); List sqtrIdsLoaded = new ArrayList<>(); - List sqtrIdsBefore = new ArrayList<>(); + List sqtrIdsBefore = sqtrService.getIdsByDataProvider(dataProvider.name()); + List sqtrGeneAssociationIdsLoaded = new ArrayList<>(); + List sqtrGeneAssociationIdsBefore = sqtrService.getIdsByDataProvider(dataProvider.name()); + bulkLoadFileDAO.merge(bulkLoadFile); BulkLoadFileHistory history = new BulkLoadFileHistory(sqtrIngestFmsDTO.getData().size()); - boolean success = runLoad(sqtrService, history, dataProvider, sqtrIngestFmsDTO.getData(), sqtrIdsLoaded); + runLoad(history, dataProvider, sqtrIngestFmsDTO.getData(), sqtrIdsLoaded, sqtrGeneAssociationIdsLoaded); + + runCleanup(sqtrService, history, dataProvider.name(), sqtrIdsBefore, sqtrIdsLoaded, "SQTR", bulkLoadFile.getMd5Sum()); + runCleanup(sqtrService, history, dataProvider.name(), sqtrGeneAssociationIdsBefore, sqtrGeneAssociationIdsLoaded, "SQTR Gene Associations", bulkLoadFile.getMd5Sum()); - if (success) { - runCleanup(sqtrService, history, dataProvider.name(), sqtrIdsBefore, sqtrIdsLoaded, "SQTR", bulkLoadFile.getMd5Sum()); - } - history.finishLoad(); - + updateHistory(history); } catch (Exception e) { failLoad(bulkLoadFile, e); @@ -63,4 +74,68 @@ public void execLoad(BulkLoadFile bulkLoadFile) { } } + public APIResponse runLoadApi(String dataProviderName, List sqtrDTOs) { + List sqtrIdsLoaded = new ArrayList<>(); + List sqtrGeneAssociationIdsLoaded = new ArrayList<>(); + + BulkLoadFileHistory history = new BulkLoadFileHistory(sqtrDTOs.size()); + BackendBulkDataProvider dataProvider = BackendBulkDataProvider.valueOf(dataProviderName); + runLoad(history, dataProvider, sqtrDTOs, sqtrIdsLoaded, sqtrGeneAssociationIdsLoaded); + history.finishLoad(); + + return new LoadHistoryResponce(history); + } + + private void runLoad(BulkLoadFileHistory history, BackendBulkDataProvider dataProvider, List sqtrs, List sqtrIdsLoaded, List sqtrGeneAssociationIdsLoaded) { + ProcessDisplayHelper ph = new ProcessDisplayHelper(); + ph.addDisplayHandler(loadProcessDisplayService); + ph.startProcess("Sequence Targeting Reagent DTO Update for " + dataProvider.name(), sqtrs.size() * 2); + + loadSequenceTargetingReagents(history, sqtrs, sqtrIdsLoaded, dataProvider, ph); + loadSequenceTargetingReagentGeneAssociations(history, sqtrs, sqtrGeneAssociationIdsLoaded, dataProvider, ph); + + ph.finishProcess(); + + } + + private void loadSequenceTargetingReagents(BulkLoadFileHistory history, List sqtrs, List idsLoaded, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { + for (SequenceTargetingReagentFmsDTO dto : sqtrs) { + try { + SequenceTargetingReagent dbObject = sqtrService.upsert(dto, dataProvider); + history.incrementCompleted(); + if (idsLoaded != null) { + idsLoaded.add(dbObject.getId()); + } + } catch (ObjectUpdateException e) { + history.incrementFailed(); + addException(history, e.getData()); + } catch (Exception e) { + history.incrementFailed(); + addException(history, new ObjectUpdateExceptionData(dto, e.getMessage(), e.getStackTrace())); + } + updateHistory(history); + ph.progressProcess(); + } + } + + private void loadSequenceTargetingReagentGeneAssociations(BulkLoadFileHistory history, List sqtrs, List idsLoaded, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { + + for (SequenceTargetingReagentFmsDTO dto : sqtrs) { + try { + List associationIds = sqtrService.addGeneAssociations(dto, dataProvider); + history.incrementCompleted(); + if (idsLoaded != null) { + idsLoaded.addAll(associationIds); + } + } catch (ObjectUpdateException e) { + history.incrementFailed(); + addException(history, e.getData()); + } catch (Exception e) { + history.incrementFailed(); + addException(history, new ObjectUpdateExceptionData(dto, e.getMessage(), e.getStackTrace())); + } + updateHistory(history); + ph.progressProcess(); + } + } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java b/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java index f5bc01489..66bd201a1 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java @@ -1,10 +1,20 @@ package org.alliancegenome.curation_api.services; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.alliancegenome.curation_api.constants.EntityFieldConstants; import org.alliancegenome.curation_api.dao.SequenceTargetingReagentDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; import org.alliancegenome.curation_api.interfaces.crud.BaseUpsertServiceInterface; +import org.alliancegenome.curation_api.model.entities.Gene; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; +import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; import org.alliancegenome.curation_api.services.validation.dto.fms.SequenceTargetingReagentFmsDTOValidator; @@ -25,10 +35,70 @@ public class SequenceTargetingReagentService extends BaseEntityCrudService addGeneAssociations(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { + + List associations = sqtrDtoValidator.validateSQTRGeneAssociationFmsDTO(dto, dataProvider); + + for (SequenceTargetingReagentGeneAssociation association : associations) { + if (association != null) { + addAssociationToSQTR(association); + addAssociationToGene(association); + } + } + + return associations.stream().map(SequenceTargetingReagentGeneAssociation::getId).collect(Collectors.toList()); + } + + private void addAssociationToSQTR(SequenceTargetingReagentGeneAssociation association) { + SequenceTargetingReagent sqtr = association.getSequenceTargetingReagentAssociationSubject(); + List currentAssociations = sqtr.getSequenceTargetingReagentGeneAssociations(); + if (currentAssociations == null) { + currentAssociations = new ArrayList<>(); + sqtr.setSequenceTargetingReagentGeneAssociations(currentAssociations); + } + + List currentAssociationIds = new ArrayList<>(); + for (SequenceTargetingReagentGeneAssociation sqtrga : currentAssociations) { + currentAssociationIds.add(sqtrga.getId()); + } + + if (!currentAssociationIds.contains(association.getId())) { + currentAssociations.add(association); + } + } + + private void addAssociationToGene(SequenceTargetingReagentGeneAssociation association) { + Gene gene = association.getSequenceTargetingReagentGeneAssociationObject(); + List currentAssociations = gene.getSequenceTargetingReagentGeneAssociations(); + if (currentAssociations == null) { + currentAssociations = new ArrayList<>(); + gene.setSequenceTargetingReagentGeneAssociations(currentAssociations); + } + + List currentAssociationIds = new ArrayList<>(); + for (SequenceTargetingReagentGeneAssociation sqtrga : currentAssociations) { + currentAssociationIds.add(sqtrga.getId()); + } + + if (!currentAssociationIds.contains(association.getId())) { + currentAssociations.add(association); + } + + } + public List getIdsByDataProvider(String dataProvider) { + Map params = new HashMap<>(); + params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider); + List ids = sqtrDAO.findIdsByParams(params); + ids.removeIf(Objects::isNull); + return ids; } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java index 6cd17f9cd..a8e28b493 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java @@ -1,15 +1,24 @@ package org.alliancegenome.curation_api.services.validation.dto.fms; +import java.util.ArrayList; +import java.util.List; + import org.alliancegenome.curation_api.constants.ValidationConstants; import org.alliancegenome.curation_api.dao.SequenceTargetingReagentDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectValidationException; +import org.alliancegenome.curation_api.model.entities.Gene; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; +import org.alliancegenome.curation_api.model.entities.VocabularyTerm; +import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.model.entities.ontology.NCBITaxonTerm; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.response.SearchResponse; import org.alliancegenome.curation_api.services.DataProviderService; +import org.alliancegenome.curation_api.services.GeneService; +import org.alliancegenome.curation_api.services.SequenceTargetingReagentService; +import org.alliancegenome.curation_api.services.VocabularyTermService; import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -19,14 +28,19 @@ @RequestScoped public class SequenceTargetingReagentFmsDTOValidator { - @Inject - DataProviderService dataProviderService; + @Inject DataProviderService dataProviderService; + + @Inject GeneService geneService; - @Inject - SequenceTargetingReagentDAO sqtrDAO; + @Inject SequenceTargetingReagentDAO sqtrDAO; @Inject NcbiTaxonTermService ncbiTaxonTermService; + @Inject SequenceTargetingReagentService sqtrService; + + @Inject VocabularyTermService vocabularyTermService; + + public SequenceTargetingReagent validateSQTRFmsDTO(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider beDataProvider) throws ObjectValidationException { ObjectResponse sqtrResponse = new ObjectResponse<>(); @@ -87,4 +101,51 @@ public SequenceTargetingReagent validateSQTRFmsDTO(SequenceTargetingReagentFmsDT return sqtr; } + + public List validateSQTRGeneAssociationFmsDTO(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider beDataProvider) throws ObjectValidationException { + + List strGeneAssociations = new ArrayList<>(); + ObjectResponse sqtrResponse = new ObjectResponse<>(); + + SequenceTargetingReagent sqtr; + SearchResponse sqtrSearchResponse = sqtrDAO.findByField("modEntityId", dto.getPrimaryId()); + + if (sqtrSearchResponse == null || sqtrSearchResponse.getSingleResult() == null) { + sqtrResponse.addErrorMessage("modEntityId", ValidationConstants.INVALID_MESSAGE + " (" + dto.getPrimaryId() + ")"); + sqtr = new SequenceTargetingReagent(); + } else { + sqtr = sqtrSearchResponse.getSingleResult(); + } + + + VocabularyTerm relation; + SearchResponse relationSearchResponse = vocabularyTermService.findByField("name", "targets"); + if (relationSearchResponse == null || relationSearchResponse.getSingleResult() == null) { + sqtrResponse.addErrorMessage("relation", ValidationConstants.INVALID_MESSAGE + " (" + "targets" + ")"); + relation = new VocabularyTerm(); + } else { + relation = relationSearchResponse.getSingleResult(); + } + + for (String geneId : dto.getTargetGeneIds()) { + Gene gene = geneService.findByIdentifierString(geneId); + + if (gene == null) { + sqtrResponse.addErrorMessage("targetGeneIds", ValidationConstants.INVALID_MESSAGE + " (" + geneId + ")"); + } else { + SequenceTargetingReagentGeneAssociation strGeneAssociation = new SequenceTargetingReagentGeneAssociation(); + strGeneAssociation.setSequenceTargetingReagentAssociationSubject(sqtr); + strGeneAssociation.setRelation(relation); + strGeneAssociation.setSequenceTargetingReagentGeneAssociationObject(gene); + + strGeneAssociations.add(strGeneAssociation); + } + + } + if (sqtrResponse.hasErrors()) { + throw new ObjectValidationException(dto, sqtrResponse.errorMessagesString()); + } + + return strGeneAssociations; + } } From 452982b05cdf3f95e7e8d03a3a4295a1e11702d4 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Mon, 8 Jul 2024 10:25:39 -0500 Subject: [PATCH 26/82] SCRUM-4185 added service, validator, and dao for sqtrGeneAssociations --- ...nceTargetingReagentGeneAssociationDAO.java | 15 +++ .../SequenceTargetingReagentExecutor.java | 5 +- .../SequenceTargetingReagentService.java | 52 --------- ...argetingReagentGeneAssociationService.java | 105 ++++++++++++++++++ ...ReagentGeneAssociationFmsDTOValidator.java | 76 +++++++++++++ ...quenceTargetingReagentFmsDTOValidator.java | 46 -------- 6 files changed, 200 insertions(+), 99 deletions(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/associations/SequenceTargetingReagentGeneAssociationDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java diff --git a/src/main/java/org/alliancegenome/curation_api/dao/associations/SequenceTargetingReagentGeneAssociationDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/associations/SequenceTargetingReagentGeneAssociationDAO.java new file mode 100644 index 000000000..bc512d663 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/associations/SequenceTargetingReagentGeneAssociationDAO.java @@ -0,0 +1,15 @@ +package org.alliancegenome.curation_api.dao.associations; + +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; + +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class SequenceTargetingReagentGeneAssociationDAO extends BaseSQLDAO { + + protected SequenceTargetingReagentGeneAssociationDAO() { + super(SequenceTargetingReagentGeneAssociation.class); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java index 69e538733..708b12cfe 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java @@ -10,6 +10,7 @@ import org.alliancegenome.curation_api.exceptions.ObjectUpdateException.ObjectUpdateExceptionData; import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; +import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkFMSLoad; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFile; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; @@ -18,6 +19,7 @@ import org.alliancegenome.curation_api.response.APIResponse; import org.alliancegenome.curation_api.response.LoadHistoryResponce; import org.alliancegenome.curation_api.services.SequenceTargetingReagentService; +import org.alliancegenome.curation_api.services.associations.SequenceTargetingReagentGeneAssociationService; import org.alliancegenome.curation_api.util.ProcessDisplayHelper; import org.apache.commons.lang3.StringUtils; @@ -27,6 +29,7 @@ @ApplicationScoped public class SequenceTargetingReagentExecutor extends LoadFileExecutor { @Inject SequenceTargetingReagentService sqtrService; + @Inject SequenceTargetingReagentGeneAssociationService sqtrGeneAssociationService; public void execLoad(BulkLoadFile bulkLoadFile) { @@ -122,7 +125,7 @@ private void loadSequenceTargetingReagentGeneAssociations(BulkLoadFileHistory hi for (SequenceTargetingReagentFmsDTO dto : sqtrs) { try { - List associationIds = sqtrService.addGeneAssociations(dto, dataProvider); + List associationIds = sqtrGeneAssociationService.addGeneAssociations(dto, dataProvider); history.incrementCompleted(); if (idsLoaded != null) { idsLoaded.addAll(associationIds); diff --git a/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java b/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java index 66bd201a1..a11689115 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java @@ -42,58 +42,6 @@ public SequenceTargetingReagent upsert(SequenceTargetingReagentFmsDTO dto, Backe return sqtrDAO.persist(sqtr); } - @Transactional - public List addGeneAssociations(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { - - List associations = sqtrDtoValidator.validateSQTRGeneAssociationFmsDTO(dto, dataProvider); - - for (SequenceTargetingReagentGeneAssociation association : associations) { - if (association != null) { - addAssociationToSQTR(association); - addAssociationToGene(association); - } - } - - return associations.stream().map(SequenceTargetingReagentGeneAssociation::getId).collect(Collectors.toList()); - } - - private void addAssociationToSQTR(SequenceTargetingReagentGeneAssociation association) { - SequenceTargetingReagent sqtr = association.getSequenceTargetingReagentAssociationSubject(); - List currentAssociations = sqtr.getSequenceTargetingReagentGeneAssociations(); - if (currentAssociations == null) { - currentAssociations = new ArrayList<>(); - sqtr.setSequenceTargetingReagentGeneAssociations(currentAssociations); - } - - List currentAssociationIds = new ArrayList<>(); - for (SequenceTargetingReagentGeneAssociation sqtrga : currentAssociations) { - currentAssociationIds.add(sqtrga.getId()); - } - - if (!currentAssociationIds.contains(association.getId())) { - currentAssociations.add(association); - } - } - - private void addAssociationToGene(SequenceTargetingReagentGeneAssociation association) { - Gene gene = association.getSequenceTargetingReagentGeneAssociationObject(); - List currentAssociations = gene.getSequenceTargetingReagentGeneAssociations(); - if (currentAssociations == null) { - currentAssociations = new ArrayList<>(); - gene.setSequenceTargetingReagentGeneAssociations(currentAssociations); - } - - List currentAssociationIds = new ArrayList<>(); - for (SequenceTargetingReagentGeneAssociation sqtrga : currentAssociations) { - currentAssociationIds.add(sqtrga.getId()); - } - - if (!currentAssociationIds.contains(association.getId())) { - currentAssociations.add(association); - } - - } - public List getIdsByDataProvider(String dataProvider) { Map params = new HashMap<>(); params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider); diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java new file mode 100644 index 000000000..8a920fa87 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java @@ -0,0 +1,105 @@ +package org.alliancegenome.curation_api.services.associations; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.alliancegenome.curation_api.dao.associations.SequenceTargetingReagentGeneAssociationDAO; +import org.alliancegenome.curation_api.dao.associations.alleleAssociations.AlleleGeneAssociationDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; +import org.alliancegenome.curation_api.interfaces.crud.BaseUpsertServiceInterface; +import org.alliancegenome.curation_api.model.entities.Gene; +import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; +import org.alliancegenome.curation_api.model.entities.associations.alleleAssociations.AlleleGeneAssociation; +import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; +import org.alliancegenome.curation_api.model.ingest.dto.associations.alleleAssociations.AlleleGeneAssociationDTO; +import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; +import org.alliancegenome.curation_api.services.base.BaseAssociationDTOCrudService; +import org.alliancegenome.curation_api.services.validation.associations.SequenceTargetingReagentGeneAssociationFmsDTOValidator; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; + +@RequestScoped +public class SequenceTargetingReagentGeneAssociationService extends + BaseAssociationDTOCrudService { + @Inject + SequenceTargetingReagentGeneAssociationDAO sequenceTargetingReagentGeneAssociationDAO; + @Inject + SequenceTargetingReagentGeneAssociationFmsDTOValidator sequenceTargetingReagentGeneAssociationFmsDTOValidator; + + @Override + @PostConstruct + protected void init() { + setSQLDao(sequenceTargetingReagentGeneAssociationDAO); + } + + @Transactional + public SequenceTargetingReagentGeneAssociation upsert(SequenceTargetingReagentFmsDTO dto, + BackendBulkDataProvider dataProvider) throws ObjectUpdateException { + // TODO: fix this placeholder code + SequenceTargetingReagentGeneAssociation sequenceTargetingReagentGeneAssociation = new SequenceTargetingReagentGeneAssociation(); + return sequenceTargetingReagentGeneAssociation; + } + + // TODO: rename? + @Transactional + public List addGeneAssociations(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider dataProvider) + throws ObjectUpdateException { + + List associations = sequenceTargetingReagentGeneAssociationFmsDTOValidator + .validateSQTRGeneAssociationFmsDTO(dto, dataProvider); + + for (SequenceTargetingReagentGeneAssociation association : associations) { + if (association != null) { + addAssociationToSQTR(association); + addAssociationToGene(association); + } + } + + return associations.stream().map(SequenceTargetingReagentGeneAssociation::getId) + .collect(Collectors.toList()); + } + + private void addAssociationToSQTR(SequenceTargetingReagentGeneAssociation association) { + SequenceTargetingReagent sqtr = association.getSequenceTargetingReagentAssociationSubject(); + List currentAssociations = sqtr + .getSequenceTargetingReagentGeneAssociations(); + if (currentAssociations == null) { + currentAssociations = new ArrayList<>(); + sqtr.setSequenceTargetingReagentGeneAssociations(currentAssociations); + } + + List currentAssociationIds = new ArrayList<>(); + for (SequenceTargetingReagentGeneAssociation sqtrga : currentAssociations) { + currentAssociationIds.add(sqtrga.getId()); + } + + if (!currentAssociationIds.contains(association.getId())) { + currentAssociations.add(association); + } + } + + private void addAssociationToGene(SequenceTargetingReagentGeneAssociation association) { + Gene gene = association.getSequenceTargetingReagentGeneAssociationObject(); + List currentAssociations = gene + .getSequenceTargetingReagentGeneAssociations(); + if (currentAssociations == null) { + currentAssociations = new ArrayList<>(); + gene.setSequenceTargetingReagentGeneAssociations(currentAssociations); + } + + List currentAssociationIds = new ArrayList<>(); + for (SequenceTargetingReagentGeneAssociation sqtrga : currentAssociations) { + currentAssociationIds.add(sqtrga.getId()); + } + + if (!currentAssociationIds.contains(association.getId())) { + currentAssociations.add(association); + } + + } +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java new file mode 100644 index 000000000..74ff2f979 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java @@ -0,0 +1,76 @@ +package org.alliancegenome.curation_api.services.validation.associations; + +import java.util.ArrayList; +import java.util.List; + +import org.alliancegenome.curation_api.constants.ValidationConstants; +import org.alliancegenome.curation_api.dao.SequenceTargetingReagentDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.exceptions.ObjectValidationException; +import org.alliancegenome.curation_api.model.entities.Gene; +import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; +import org.alliancegenome.curation_api.model.entities.VocabularyTerm; +import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; +import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.services.GeneService; +import org.alliancegenome.curation_api.services.VocabularyTermService; + +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; + +@RequestScoped +public class SequenceTargetingReagentGeneAssociationFmsDTOValidator { + @Inject SequenceTargetingReagentDAO sqtrDAO; + @Inject VocabularyTermService vocabularyTermService; + @Inject GeneService geneService; + + public List validateSQTRGeneAssociationFmsDTO( SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider beDataProvider) throws ObjectValidationException { + List strGeneAssociations = new ArrayList<>(); + ObjectResponse sqtrResponse = new ObjectResponse<>(); + + SequenceTargetingReagent sqtr; + SearchResponse sqtrSearchResponse = sqtrDAO.findByField("modEntityId", + dto.getPrimaryId()); + + if (sqtrSearchResponse == null || sqtrSearchResponse.getSingleResult() == null) { + sqtrResponse.addErrorMessage("modEntityId", + ValidationConstants.INVALID_MESSAGE + " (" + dto.getPrimaryId() + ")"); + sqtr = new SequenceTargetingReagent(); + } else { + sqtr = sqtrSearchResponse.getSingleResult(); + } + + VocabularyTerm relation; + SearchResponse relationSearchResponse = vocabularyTermService.findByField("name", "targets"); + if (relationSearchResponse == null || relationSearchResponse.getSingleResult() == null) { + sqtrResponse.addErrorMessage("relation", ValidationConstants.INVALID_MESSAGE + " (" + "targets" + ")"); + relation = new VocabularyTerm(); + } else { + relation = relationSearchResponse.getSingleResult(); + } + + for (String geneId : dto.getTargetGeneIds()) { + Gene gene = geneService.findByIdentifierString(geneId); + + if (gene == null) { + sqtrResponse.addErrorMessage("targetGeneIds", + ValidationConstants.INVALID_MESSAGE + " (" + geneId + ")"); + } else { + SequenceTargetingReagentGeneAssociation strGeneAssociation = new SequenceTargetingReagentGeneAssociation(); + strGeneAssociation.setSequenceTargetingReagentAssociationSubject(sqtr); + strGeneAssociation.setRelation(relation); + strGeneAssociation.setSequenceTargetingReagentGeneAssociationObject(gene); + + strGeneAssociations.add(strGeneAssociation); + } + + } + if (sqtrResponse.hasErrors()) { + throw new ObjectValidationException(dto, sqtrResponse.errorMessagesString()); + } + + return strGeneAssociations; + } +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java index a8e28b493..37684191e 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java @@ -102,50 +102,4 @@ public SequenceTargetingReagent validateSQTRFmsDTO(SequenceTargetingReagentFmsDT return sqtr; } - public List validateSQTRGeneAssociationFmsDTO(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider beDataProvider) throws ObjectValidationException { - - List strGeneAssociations = new ArrayList<>(); - ObjectResponse sqtrResponse = new ObjectResponse<>(); - - SequenceTargetingReagent sqtr; - SearchResponse sqtrSearchResponse = sqtrDAO.findByField("modEntityId", dto.getPrimaryId()); - - if (sqtrSearchResponse == null || sqtrSearchResponse.getSingleResult() == null) { - sqtrResponse.addErrorMessage("modEntityId", ValidationConstants.INVALID_MESSAGE + " (" + dto.getPrimaryId() + ")"); - sqtr = new SequenceTargetingReagent(); - } else { - sqtr = sqtrSearchResponse.getSingleResult(); - } - - - VocabularyTerm relation; - SearchResponse relationSearchResponse = vocabularyTermService.findByField("name", "targets"); - if (relationSearchResponse == null || relationSearchResponse.getSingleResult() == null) { - sqtrResponse.addErrorMessage("relation", ValidationConstants.INVALID_MESSAGE + " (" + "targets" + ")"); - relation = new VocabularyTerm(); - } else { - relation = relationSearchResponse.getSingleResult(); - } - - for (String geneId : dto.getTargetGeneIds()) { - Gene gene = geneService.findByIdentifierString(geneId); - - if (gene == null) { - sqtrResponse.addErrorMessage("targetGeneIds", ValidationConstants.INVALID_MESSAGE + " (" + geneId + ")"); - } else { - SequenceTargetingReagentGeneAssociation strGeneAssociation = new SequenceTargetingReagentGeneAssociation(); - strGeneAssociation.setSequenceTargetingReagentAssociationSubject(sqtr); - strGeneAssociation.setRelation(relation); - strGeneAssociation.setSequenceTargetingReagentGeneAssociationObject(gene); - - strGeneAssociations.add(strGeneAssociation); - } - - } - if (sqtrResponse.hasErrors()) { - throw new ObjectValidationException(dto, sqtrResponse.errorMessagesString()); - } - - return strGeneAssociations; - } } From dcb3aac1856154c0d40b67a84705a861784956db Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Tue, 9 Jul 2024 11:54:29 -0500 Subject: [PATCH 27/82] SCRUM-4185 update executor to use sqtr gene association service --- .../SequenceTargetingReagentExecutor.java | 44 +++++++++++++------ ...argetingReagentGeneAssociationService.java | 34 +++++++------- ...ReagentGeneAssociationFmsDTOValidator.java | 34 +++++++------- ...quenceTargetingReagentFmsDTOValidator.java | 6 --- 4 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java index 708b12cfe..3c7b0b3d8 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java @@ -2,7 +2,9 @@ import java.io.FileInputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.zip.GZIPInputStream; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; @@ -28,8 +30,10 @@ @ApplicationScoped public class SequenceTargetingReagentExecutor extends LoadFileExecutor { - @Inject SequenceTargetingReagentService sqtrService; - @Inject SequenceTargetingReagentGeneAssociationService sqtrGeneAssociationService; + @Inject + SequenceTargetingReagentService sqtrService; + @Inject + SequenceTargetingReagentGeneAssociationService sqtrGeneAssociationService; public void execLoad(BulkLoadFile bulkLoadFile) { @@ -53,20 +57,20 @@ public void execLoad(BulkLoadFile bulkLoadFile) { BackendBulkDataProvider dataProvider = BackendBulkDataProvider.valueOf(fms.getFmsDataSubType()); - List sqtrIdsLoaded = new ArrayList<>(); - List sqtrIdsBefore = sqtrService.getIdsByDataProvider(dataProvider.name()); - List sqtrGeneAssociationIdsLoaded = new ArrayList<>(); - List sqtrGeneAssociationIdsBefore = sqtrService.getIdsByDataProvider(dataProvider.name()); + Map> idsAdded = new HashMap>(); + idsAdded.put("SQTR", new ArrayList()); + idsAdded.put("SQTRGeneAssociation", new ArrayList()); + Map> previousIds = getPreviouslyLoadedIds(dataProvider); bulkLoadFileDAO.merge(bulkLoadFile); - BulkLoadFileHistory history = new BulkLoadFileHistory(sqtrIngestFmsDTO.getData().size()); + BulkLoadFileHistory history = new BulkLoadFileHistory(sqtrIngestFmsDTO.getData().size() * 2); - runLoad(history, dataProvider, sqtrIngestFmsDTO.getData(), sqtrIdsLoaded, sqtrGeneAssociationIdsLoaded); + runLoad(history, dataProvider, sqtrIngestFmsDTO.getData(), idsAdded.get("SQTR"), idsAdded.get("SQTRGeneAssociation")); - runCleanup(sqtrService, history, dataProvider.name(), sqtrIdsBefore, sqtrIdsLoaded, "SQTR", bulkLoadFile.getMd5Sum()); - runCleanup(sqtrService, history, dataProvider.name(), sqtrGeneAssociationIdsBefore, sqtrGeneAssociationIdsLoaded, "SQTR Gene Associations", bulkLoadFile.getMd5Sum()); + runCleanup(sqtrService, history, dataProvider.name(), previousIds.get("SQTR"), idsAdded.get("SQTR"), "SQTR", bulkLoadFile.getMd5Sum()); + runCleanup(sqtrService, history, dataProvider.name(), previousIds.get("SQTRGeneAssociation"), idsAdded.get("SQTRGeneAssociation"), "SQTR Gene Associations", bulkLoadFile.getMd5Sum()); history.finishLoad(); @@ -77,11 +81,20 @@ public void execLoad(BulkLoadFile bulkLoadFile) { } } + private Map> getPreviouslyLoadedIds(BackendBulkDataProvider dataProvider) { + Map> previousIds = new HashMap<>(); + + previousIds.put("SQTR", sqtrService.getIdsByDataProvider(dataProvider.name())); + previousIds.put("SQTRGeneAssociation", sqtrGeneAssociationService.getIdsByDataProvider(dataProvider.name())); + + return previousIds; + } + public APIResponse runLoadApi(String dataProviderName, List sqtrDTOs) { List sqtrIdsLoaded = new ArrayList<>(); List sqtrGeneAssociationIdsLoaded = new ArrayList<>(); - BulkLoadFileHistory history = new BulkLoadFileHistory(sqtrDTOs.size()); + BulkLoadFileHistory history = new BulkLoadFileHistory(sqtrDTOs.size() * 2); BackendBulkDataProvider dataProvider = BackendBulkDataProvider.valueOf(dataProviderName); runLoad(history, dataProvider, sqtrDTOs, sqtrIdsLoaded, sqtrGeneAssociationIdsLoaded); history.finishLoad(); @@ -101,7 +114,8 @@ private void runLoad(BulkLoadFileHistory history, BackendBulkDataProvider dataPr } - private void loadSequenceTargetingReagents(BulkLoadFileHistory history, List sqtrs, List idsLoaded, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { + private void loadSequenceTargetingReagents(BulkLoadFileHistory history, List sqtrs, + List idsLoaded, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { for (SequenceTargetingReagentFmsDTO dto : sqtrs) { try { SequenceTargetingReagent dbObject = sqtrService.upsert(dto, dataProvider); @@ -121,11 +135,13 @@ private void loadSequenceTargetingReagents(BulkLoadFileHistory history, List sqtrs, List idsLoaded, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { + private void loadSequenceTargetingReagentGeneAssociations(BulkLoadFileHistory history, + List sqtrs, List idsLoaded, BackendBulkDataProvider dataProvider, + ProcessDisplayHelper ph) { for (SequenceTargetingReagentFmsDTO dto : sqtrs) { try { - List associationIds = sqtrGeneAssociationService.addGeneAssociations(dto, dataProvider); + List associationIds = sqtrGeneAssociationService.loadGeneAssociations(dto, dataProvider); history.incrementCompleted(); if (idsLoaded != null) { idsLoaded.addAll(associationIds); diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java index 8a920fa87..4c00833a2 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java @@ -1,9 +1,13 @@ package org.alliancegenome.curation_api.services.associations; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; +import org.alliancegenome.curation_api.constants.EntityFieldConstants; import org.alliancegenome.curation_api.dao.associations.SequenceTargetingReagentGeneAssociationDAO; import org.alliancegenome.curation_api.dao.associations.alleleAssociations.AlleleGeneAssociationDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; @@ -24,31 +28,15 @@ import jakarta.transaction.Transactional; @RequestScoped -public class SequenceTargetingReagentGeneAssociationService extends - BaseAssociationDTOCrudService { +public class SequenceTargetingReagentGeneAssociationService { + @Inject SequenceTargetingReagentGeneAssociationDAO sequenceTargetingReagentGeneAssociationDAO; @Inject SequenceTargetingReagentGeneAssociationFmsDTOValidator sequenceTargetingReagentGeneAssociationFmsDTOValidator; - @Override - @PostConstruct - protected void init() { - setSQLDao(sequenceTargetingReagentGeneAssociationDAO); - } - @Transactional - public SequenceTargetingReagentGeneAssociation upsert(SequenceTargetingReagentFmsDTO dto, - BackendBulkDataProvider dataProvider) throws ObjectUpdateException { - // TODO: fix this placeholder code - SequenceTargetingReagentGeneAssociation sequenceTargetingReagentGeneAssociation = new SequenceTargetingReagentGeneAssociation(); - return sequenceTargetingReagentGeneAssociation; - } - - // TODO: rename? - @Transactional - public List addGeneAssociations(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider dataProvider) - throws ObjectUpdateException { + public List loadGeneAssociations(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { List associations = sequenceTargetingReagentGeneAssociationFmsDTOValidator .validateSQTRGeneAssociationFmsDTO(dto, dataProvider); @@ -102,4 +90,12 @@ private void addAssociationToGene(SequenceTargetingReagentGeneAssociation associ } } + + public List getIdsByDataProvider(String dataProvider) { + Map params = new HashMap<>(); + params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider); + List ids = sequenceTargetingReagentGeneAssociationDAO.findIdsByParams(params); + ids.removeIf(Objects::isNull); + return ids; + } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java index 74ff2f979..1997b6f97 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java @@ -31,8 +31,7 @@ public List validateSQTRGeneAssociation ObjectResponse sqtrResponse = new ObjectResponse<>(); SequenceTargetingReagent sqtr; - SearchResponse sqtrSearchResponse = sqtrDAO.findByField("modEntityId", - dto.getPrimaryId()); + SearchResponse sqtrSearchResponse = sqtrDAO.findByField("modEntityId", dto.getPrimaryId()); if (sqtrSearchResponse == null || sqtrSearchResponse.getSingleResult() == null) { sqtrResponse.addErrorMessage("modEntityId", @@ -51,22 +50,25 @@ public List validateSQTRGeneAssociation relation = relationSearchResponse.getSingleResult(); } - for (String geneId : dto.getTargetGeneIds()) { - Gene gene = geneService.findByIdentifierString(geneId); - - if (gene == null) { - sqtrResponse.addErrorMessage("targetGeneIds", - ValidationConstants.INVALID_MESSAGE + " (" + geneId + ")"); - } else { - SequenceTargetingReagentGeneAssociation strGeneAssociation = new SequenceTargetingReagentGeneAssociation(); - strGeneAssociation.setSequenceTargetingReagentAssociationSubject(sqtr); - strGeneAssociation.setRelation(relation); - strGeneAssociation.setSequenceTargetingReagentGeneAssociationObject(gene); - - strGeneAssociations.add(strGeneAssociation); + if(dto.getTargetGeneIds() != null){ + for (String geneId : dto.getTargetGeneIds()) { + Gene gene = geneService.findByIdentifierString(geneId); + + if (gene == null) { + sqtrResponse.addErrorMessage("targetGeneIds", + ValidationConstants.INVALID_MESSAGE + " (" + geneId + ")"); + } else { + SequenceTargetingReagentGeneAssociation strGeneAssociation = new SequenceTargetingReagentGeneAssociation(); + strGeneAssociation.setSequenceTargetingReagentAssociationSubject(sqtr); + strGeneAssociation.setRelation(relation); + strGeneAssociation.setSequenceTargetingReagentGeneAssociationObject(gene); + + strGeneAssociations.add(strGeneAssociation); + } + } - } + if (sqtrResponse.hasErrors()) { throw new ObjectValidationException(dto, sqtrResponse.errorMessagesString()); } diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java index 37684191e..55cdec3ba 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/fms/SequenceTargetingReagentFmsDTOValidator.java @@ -1,16 +1,10 @@ package org.alliancegenome.curation_api.services.validation.dto.fms; -import java.util.ArrayList; -import java.util.List; - import org.alliancegenome.curation_api.constants.ValidationConstants; import org.alliancegenome.curation_api.dao.SequenceTargetingReagentDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectValidationException; -import org.alliancegenome.curation_api.model.entities.Gene; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; -import org.alliancegenome.curation_api.model.entities.VocabularyTerm; -import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.model.entities.ontology.NCBITaxonTerm; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; import org.alliancegenome.curation_api.response.ObjectResponse; From 644e2cb28e290835d1ab153d1f771801a457d387 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Tue, 9 Jul 2024 11:55:25 -0500 Subject: [PATCH 28/82] SCRUM-4185 update tests --- ...ceTargetingReagentBulkUploadFmsITCase.java | 41 +++++++++++++++---- .../curation_api/base/BaseITCase.java | 10 +++-- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentBulkUploadFmsITCase.java b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentBulkUploadFmsITCase.java index b3bade7ef..8939c04a8 100644 --- a/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentBulkUploadFmsITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentBulkUploadFmsITCase.java @@ -45,7 +45,7 @@ public void init() { @Order(1) public void sqtrBulkUploadCheckFields() throws Exception { - checkSuccessfulBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "AF_01_all_fields.json"); + checkSuccessfulBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "AF_01_all_fields.json", 2); RestAssured.given(). when(). @@ -67,16 +67,41 @@ public void sqtrBulkUploadCheckFields() throws Exception { @Order(2) public void sqtrBulkUploadMissingRequiredFields() throws Exception { - checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "MR_01_no_name.json"); - checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "MR_02_no_taxon.json"); + checkFailedBulkLoad( + sqtrBulkPostEndpoint, + sqtrTestFilePath + "MR_01_no_name.json", + 2, + 1, + 1 + ); + checkFailedBulkLoad( + sqtrBulkPostEndpoint, + sqtrTestFilePath + "MR_02_no_taxon.json", + 2, + 1, + 1 + ); } @Test @Order(3) public void sqtrBulkUploadEmptyRequiredFields() throws Exception { - checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "ER_01_empty_name.json"); - checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "ER_02_empty_taxon.json"); + checkFailedBulkLoad( + sqtrBulkPostEndpoint, + sqtrTestFilePath + "ER_01_empty_name.json", + 2, + 1, + 1 + ); + + checkFailedBulkLoad( + sqtrBulkPostEndpoint, + sqtrTestFilePath + "ER_02_empty_taxon.json", + 2, + 1, + 1 + ); } @@ -84,7 +109,7 @@ public void sqtrBulkUploadEmptyRequiredFields() throws Exception { @Order(4) public void sqtrBulkUploadUpdateMissingNonRequiredFields() throws Exception { - checkSuccessfulBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "UM_01_update_no_non_required_fields.json"); + checkSuccessfulBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "UM_01_update_no_non_required_fields.json", 2); RestAssured.given(). when(). @@ -104,7 +129,7 @@ public void sqtrBulkUploadUpdateMissingNonRequiredFields() throws Exception { @Order(5) public void sqtrBulkUploadUpdateEmptyNonRequiredFields() throws Exception { - checkSuccessfulBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "AF_01_all_fields.json"); + checkSuccessfulBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "AF_01_all_fields.json", 2); RestAssured.given(). when(). @@ -122,7 +147,7 @@ public void sqtrBulkUploadUpdateEmptyNonRequiredFields() throws Exception { body("results[0]" , hasKey("synonyms")). body("results[0]" , hasKey("secondaryIdentifiers")); - checkSuccessfulBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "UE_01_update_empty_non_required_fields.json"); + checkSuccessfulBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "UE_01_update_empty_non_required_fields.json", 2); RestAssured.given(). when(). diff --git a/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java b/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java index 1ef4c4cb1..42c239537 100644 --- a/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java @@ -97,6 +97,10 @@ public VocabularyTerm addVocabularyTermToSet(String setName, String termName, Vo } public void checkFailedBulkLoad(String endpoint, String filePath) throws Exception { + checkFailedBulkLoad(endpoint, filePath, 1, 1, 0); + } + + public void checkFailedBulkLoad(String endpoint, String filePath, int expectedTotalRecords, int expectedFailedRecords, int expectedCompletedRecords) throws Exception { String content = Files.readString(Path.of(filePath)); RestAssured.given(). @@ -106,9 +110,9 @@ public void checkFailedBulkLoad(String endpoint, String filePath) throws Excepti post(endpoint). then(). statusCode(200). - body("history.totalRecords", is(1)). - body("history.failedRecords", is(1)). - body("history.completedRecords", is(0)); + body("history.totalRecords", is(expectedTotalRecords)). + body("history.failedRecords", is(expectedFailedRecords)). + body("history.completedRecords", is(expectedCompletedRecords)); } public void checkSuccessfulBulkLoad(String endpoint, String filePath) throws Exception { From 2df4c73a4f2dd088215e8c4bbea6d7bf4ab9ed15 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Tue, 9 Jul 2024 12:04:56 -0500 Subject: [PATCH 29/82] SCRUM-4185 update formatting --- .../SequenceTargetingReagentExecutor.java | 1 - .../SequenceTargetingReagentService.java | 4 - ...argetingReagentGeneAssociationService.java | 6 -- ...ReagentGeneAssociationFmsDTOValidator.java | 98 ++++++++++--------- ...ceTargetingReagentBulkUploadFmsITCase.java | 34 +------ 5 files changed, 56 insertions(+), 87 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java index 3c7b0b3d8..9c96eec15 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java @@ -12,7 +12,6 @@ import org.alliancegenome.curation_api.exceptions.ObjectUpdateException.ObjectUpdateExceptionData; import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; -import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkFMSLoad; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFile; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; diff --git a/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java b/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java index a11689115..14d3fa63b 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/SequenceTargetingReagentService.java @@ -1,20 +1,16 @@ package org.alliancegenome.curation_api.services; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; import org.alliancegenome.curation_api.constants.EntityFieldConstants; import org.alliancegenome.curation_api.dao.SequenceTargetingReagentDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; import org.alliancegenome.curation_api.interfaces.crud.BaseUpsertServiceInterface; -import org.alliancegenome.curation_api.model.entities.Gene; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; -import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; import org.alliancegenome.curation_api.services.validation.dto.fms.SequenceTargetingReagentFmsDTOValidator; diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java index 4c00833a2..bf19881cf 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java @@ -9,20 +9,14 @@ import org.alliancegenome.curation_api.constants.EntityFieldConstants; import org.alliancegenome.curation_api.dao.associations.SequenceTargetingReagentGeneAssociationDAO; -import org.alliancegenome.curation_api.dao.associations.alleleAssociations.AlleleGeneAssociationDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; -import org.alliancegenome.curation_api.interfaces.crud.BaseUpsertServiceInterface; import org.alliancegenome.curation_api.model.entities.Gene; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; -import org.alliancegenome.curation_api.model.entities.associations.alleleAssociations.AlleleGeneAssociation; import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; -import org.alliancegenome.curation_api.model.ingest.dto.associations.alleleAssociations.AlleleGeneAssociationDTO; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; -import org.alliancegenome.curation_api.services.base.BaseAssociationDTOCrudService; import org.alliancegenome.curation_api.services.validation.associations.SequenceTargetingReagentGeneAssociationFmsDTOValidator; -import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; import jakarta.transaction.Transactional; diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java index 1997b6f97..ca24216f8 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/associations/SequenceTargetingReagentGeneAssociationFmsDTOValidator.java @@ -22,57 +22,61 @@ @RequestScoped public class SequenceTargetingReagentGeneAssociationFmsDTOValidator { - @Inject SequenceTargetingReagentDAO sqtrDAO; - @Inject VocabularyTermService vocabularyTermService; - @Inject GeneService geneService; + @Inject + SequenceTargetingReagentDAO sqtrDAO; + @Inject + VocabularyTermService vocabularyTermService; + @Inject + GeneService geneService; - public List validateSQTRGeneAssociationFmsDTO( SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider beDataProvider) throws ObjectValidationException { - List strGeneAssociations = new ArrayList<>(); - ObjectResponse sqtrResponse = new ObjectResponse<>(); + public List validateSQTRGeneAssociationFmsDTO(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider beDataProvider) throws ObjectValidationException { + List strGeneAssociations = new ArrayList<>(); + ObjectResponse sqtrResponse = new ObjectResponse<>(); - SequenceTargetingReagent sqtr; - SearchResponse sqtrSearchResponse = sqtrDAO.findByField("modEntityId", dto.getPrimaryId()); + SequenceTargetingReagent sqtr; + SearchResponse sqtrSearchResponse = sqtrDAO.findByField("modEntityId", + dto.getPrimaryId()); - if (sqtrSearchResponse == null || sqtrSearchResponse.getSingleResult() == null) { - sqtrResponse.addErrorMessage("modEntityId", - ValidationConstants.INVALID_MESSAGE + " (" + dto.getPrimaryId() + ")"); - sqtr = new SequenceTargetingReagent(); - } else { - sqtr = sqtrSearchResponse.getSingleResult(); - } + if (sqtrSearchResponse == null || sqtrSearchResponse.getSingleResult() == null) { + sqtrResponse.addErrorMessage("modEntityId", + ValidationConstants.INVALID_MESSAGE + " (" + dto.getPrimaryId() + ")"); + sqtr = new SequenceTargetingReagent(); + } else { + sqtr = sqtrSearchResponse.getSingleResult(); + } - VocabularyTerm relation; - SearchResponse relationSearchResponse = vocabularyTermService.findByField("name", "targets"); - if (relationSearchResponse == null || relationSearchResponse.getSingleResult() == null) { - sqtrResponse.addErrorMessage("relation", ValidationConstants.INVALID_MESSAGE + " (" + "targets" + ")"); - relation = new VocabularyTerm(); - } else { - relation = relationSearchResponse.getSingleResult(); - } + VocabularyTerm relation; + SearchResponse relationSearchResponse = vocabularyTermService.findByField("name", "targets"); + if (relationSearchResponse == null || relationSearchResponse.getSingleResult() == null) { + sqtrResponse.addErrorMessage("relation", ValidationConstants.INVALID_MESSAGE + " (" + "targets" + ")"); + relation = new VocabularyTerm(); + } else { + relation = relationSearchResponse.getSingleResult(); + } - if(dto.getTargetGeneIds() != null){ - for (String geneId : dto.getTargetGeneIds()) { - Gene gene = geneService.findByIdentifierString(geneId); - - if (gene == null) { - sqtrResponse.addErrorMessage("targetGeneIds", - ValidationConstants.INVALID_MESSAGE + " (" + geneId + ")"); - } else { - SequenceTargetingReagentGeneAssociation strGeneAssociation = new SequenceTargetingReagentGeneAssociation(); - strGeneAssociation.setSequenceTargetingReagentAssociationSubject(sqtr); - strGeneAssociation.setRelation(relation); - strGeneAssociation.setSequenceTargetingReagentGeneAssociationObject(gene); - - strGeneAssociations.add(strGeneAssociation); - } - - } - } - - if (sqtrResponse.hasErrors()) { - throw new ObjectValidationException(dto, sqtrResponse.errorMessagesString()); - } + if (dto.getTargetGeneIds() != null) { + for (String geneId : dto.getTargetGeneIds()) { + Gene gene = geneService.findByIdentifierString(geneId); - return strGeneAssociations; - } + if (gene == null) { + sqtrResponse.addErrorMessage("targetGeneIds", + ValidationConstants.INVALID_MESSAGE + " (" + geneId + ")"); + } else { + SequenceTargetingReagentGeneAssociation strGeneAssociation = new SequenceTargetingReagentGeneAssociation(); + strGeneAssociation.setSequenceTargetingReagentAssociationSubject(sqtr); + strGeneAssociation.setRelation(relation); + strGeneAssociation.setSequenceTargetingReagentGeneAssociationObject(gene); + + strGeneAssociations.add(strGeneAssociation); + } + + } + } + + if (sqtrResponse.hasErrors()) { + throw new ObjectValidationException(dto, sqtrResponse.errorMessagesString()); + } + + return strGeneAssociations; + } } diff --git a/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentBulkUploadFmsITCase.java b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentBulkUploadFmsITCase.java index 8939c04a8..03a2df0a4 100644 --- a/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentBulkUploadFmsITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentBulkUploadFmsITCase.java @@ -67,41 +67,17 @@ public void sqtrBulkUploadCheckFields() throws Exception { @Order(2) public void sqtrBulkUploadMissingRequiredFields() throws Exception { - checkFailedBulkLoad( - sqtrBulkPostEndpoint, - sqtrTestFilePath + "MR_01_no_name.json", - 2, - 1, - 1 - ); - checkFailedBulkLoad( - sqtrBulkPostEndpoint, - sqtrTestFilePath + "MR_02_no_taxon.json", - 2, - 1, - 1 - ); + checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "MR_01_no_name.json", 2, 1, 1); + checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "MR_02_no_taxon.json", 2, 1, 1); } @Test @Order(3) public void sqtrBulkUploadEmptyRequiredFields() throws Exception { - checkFailedBulkLoad( - sqtrBulkPostEndpoint, - sqtrTestFilePath + "ER_01_empty_name.json", - 2, - 1, - 1 - ); - - checkFailedBulkLoad( - sqtrBulkPostEndpoint, - sqtrTestFilePath + "ER_02_empty_taxon.json", - 2, - 1, - 1 - ); + checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "ER_01_empty_name.json", 2, 1, 1); + + checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrTestFilePath + "ER_02_empty_taxon.json", 2, 1, 1); } From 3b5b94afdaef0ed9c502c7dfd29c1050e2c0d02f Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Wed, 10 Jul 2024 13:44:54 +0100 Subject: [PATCH 30/82] Switch DPO for FBCV on dashboard --- src/main/cliapp/src/constants/Classes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/cliapp/src/constants/Classes.js b/src/main/cliapp/src/constants/Classes.js index af5b2a903..278e71e7e 100644 --- a/src/main/cliapp/src/constants/Classes.js +++ b/src/main/cliapp/src/constants/Classes.js @@ -54,7 +54,7 @@ export const CLASSES = Object.freeze({ WBPhenotypeTerm: { name: 'WBPheno', link: '/#/ontology/wbpheno', type: 'ontology' }, PATOTerm: { name: 'PATO', link: '/#/ontology/pato', type: 'ontology' }, HPTerm: { name: 'HP', link: '/#/ontology/hp', type: 'ontology' }, - DPOTerm: { name: 'DPO', link: '/#/ontology/dpo', type: 'ontology' }, + FBCVTerm: { name: 'FBCV', link: '/#/ontology/fbcv', type: 'ontology' }, MMOTerm: { name: 'MMO', link: '/#/ontology/mmo', type: 'ontology' }, APOTerm: { name: 'APO', link: '/#/ontology/apo', type: 'ontology' }, MITerm: { name: 'MI', link: '/#/ontology/mi', type: 'ontology' }, From 3c2f2f732c68e676551d2c115121b1a4348a5491 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Wed, 10 Jul 2024 10:10:02 -0500 Subject: [PATCH 31/82] SCRUM-4236 add CSS for rowEdit column min width --- .../GenericDataTable/GenericDataTable.js | 21 ++++++++++--------- .../GenericDataTable/styles.module.scss | 3 +++ 2 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 src/main/cliapp/src/components/GenericDataTable/styles.module.scss diff --git a/src/main/cliapp/src/components/GenericDataTable/GenericDataTable.js b/src/main/cliapp/src/components/GenericDataTable/GenericDataTable.js index d93c1b4db..db13153ed 100644 --- a/src/main/cliapp/src/components/GenericDataTable/GenericDataTable.js +++ b/src/main/cliapp/src/components/GenericDataTable/GenericDataTable.js @@ -16,6 +16,7 @@ import { EntityDetailsAction } from '../Actions/EntityDetailsAction'; import { filterColumns, orderColumns, getIdentifier } from '../../utils/utils'; import { useGenericDataTable } from './useGenericDataTable'; +import style from './styles.module.scss'; export const GenericDataTable = (props) => { const { tableName, @@ -160,8 +161,8 @@ export const GenericDataTable = (props) => { const rowEditorFilterNameHeader = (options) => { return ( -
- Filters +
+ Filters
); }; @@ -325,13 +326,13 @@ export const GenericDataTable = (props) => { )} {deletionEnabled && ( @@ -341,10 +342,10 @@ export const GenericDataTable = (props) => { body={(props) => deleteAction(props, isInEditMode)} filterElement={rowEditorFilterNameHeader} showFilterMenu={false} - className={`p-text-center p-0 min-w-3rem max-w-3rem ${isEditable ? 'visible' : 'hidden'}`} + className={`text-center p-0 max-w-3rem ${isEditable ? 'visible' : 'hidden'}`} bodyStyle={{ textAlign: 'center' }} frozen - headerClassName="surface-0 w-3rem sticky" + headerClassName="surface-0 max-w-3rem sticky" /> )} {duplicationEnabled && ( @@ -357,10 +358,10 @@ export const GenericDataTable = (props) => { )} showFilterMenu={false} - className={`p-text-center p-0 min-w-3rem max-w-3rem ${isEditable ? 'visible' : 'hidden'}`} + className={`text-center p-0 max-w-3rem ${isEditable ? 'visible' : 'hidden'}`} bodyStyle={{ textAlign: 'center' }} frozen - headerClassName="surface-0 w-3rem sticky" + headerClassName="surface-0 max-w-3rem sticky" /> )} {hasDetails && ( @@ -369,10 +370,10 @@ export const GenericDataTable = (props) => { editor={(props) => } body={(props) => } showFilterMenu={false} - className={`p-text-center p-0 min-w-3rem max-w-3rem ${isEditable ? 'visible' : 'hidden'}`} + className={`text-center p-0 max-w-3rem ${isEditable ? 'visible' : 'hidden'}`} bodyStyle={{ textAlign: 'center' }} frozen - headerClassName="surface-0 w-3rem sticky" + headerClassName="surface-0 max-w-3rem sticky" /> )} {columnList} diff --git a/src/main/cliapp/src/components/GenericDataTable/styles.module.scss b/src/main/cliapp/src/components/GenericDataTable/styles.module.scss new file mode 100644 index 000000000..7b574f220 --- /dev/null +++ b/src/main/cliapp/src/components/GenericDataTable/styles.module.scss @@ -0,0 +1,3 @@ +.rowEditorColumn{ + min-width : 6rem !important; +} \ No newline at end of file From 1cbdef8a7360434761fce18fc12dc12ed612c288 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Wed, 10 Jul 2024 14:30:15 -0500 Subject: [PATCH 32/82] SCRUM-4185 fix dataProvider loading error --- .../curation_api/constants/EntityFieldConstants.java | 1 + .../jobs/executors/SequenceTargetingReagentExecutor.java | 2 +- .../SequenceTargetingReagentGeneAssociationService.java | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java b/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java index a86abe168..4fe9f1347 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java @@ -14,6 +14,7 @@ private EntityFieldConstants() { public static final String PA_SUBJECT = "phenotypeAnnotationSubject"; public static final String PA_SUBJECT_TAXON = PA_SUBJECT + "." + TAXON; public static final String ALLELE_ASSOCIATION_SUBJECT_DATA_PROVIDER = "alleleAssociationSubject." + DATA_PROVIDER; + public static final String SQTR_ASSOCIATION_SUBJECT_DATA_PROVIDER = "sequenceTargetingReagentAssociationSubject." + DATA_PROVIDER; public static final String CONSTRUCT_ASSOCIATION_SUBJECT_DATA_PROVIDER = "constructAssociationSubject." + DATA_PROVIDER; public static final String SUBJECT_GENE_DATA_PROVIDER = "subjectGene." + DATA_PROVIDER; public static final String SUBJECT_GENE_TAXON = "subjectGene." + TAXON; diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java index 9c96eec15..fc16b5cab 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/SequenceTargetingReagentExecutor.java @@ -84,7 +84,7 @@ private Map> getPreviouslyLoadedIds(BackendBulkDataProvider d Map> previousIds = new HashMap<>(); previousIds.put("SQTR", sqtrService.getIdsByDataProvider(dataProvider.name())); - previousIds.put("SQTRGeneAssociation", sqtrGeneAssociationService.getIdsByDataProvider(dataProvider.name())); + previousIds.put("SQTRGeneAssociation", sqtrGeneAssociationService.getIdsByDataProvider(dataProvider)); return previousIds; } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java index bf19881cf..7cce13c41 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java @@ -85,11 +85,12 @@ private void addAssociationToGene(SequenceTargetingReagentGeneAssociation associ } - public List getIdsByDataProvider(String dataProvider) { + public List getIdsByDataProvider(BackendBulkDataProvider dataProvider) { Map params = new HashMap<>(); - params.put(EntityFieldConstants.DATA_PROVIDER, dataProvider); + params.put(EntityFieldConstants.SQTR_ASSOCIATION_SUBJECT_DATA_PROVIDER, dataProvider.sourceOrganization); List ids = sequenceTargetingReagentGeneAssociationDAO.findIdsByParams(params); ids.removeIf(Objects::isNull); return ids; } + } From db85c1e211391d43bf25868a00c74ba1fe4afdb3 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 11 Jul 2024 12:59:18 +0100 Subject: [PATCH 33/82] Entities, DAOs and migration --- .../dao/AssemblyComponentDAO.java | 51 +++++++ .../curation_api/dao/ChromosomeDAO.java | 32 +++++ ...SequenceGenomicLocationAssociationDAO.java | 15 +++ .../ExonGenomicLocationAssociationDAO.java | 15 +++ ...anscriptGenomicLocationAssociationDAO.java | 15 +++ .../bridges/BiologicalEntityTypeBridge.java | 5 + .../model/entities/AssemblyComponent.java | 70 ++++++++++ .../model/entities/BiologicalEntity.java | 4 + .../model/entities/Chromosome.java | 70 ++++++++++ .../model/entities/CodingSequence.java | 19 ++- .../curation_api/model/entities/Exon.java | 19 ++- .../model/entities/LocationAssociation.java | 41 ++++++ .../model/entities/Transcript.java | 19 ++- ...ingSequenceGenomicLocationAssociation.java | 59 +++++++++ .../ExonGenomicLocationAssociation.java | 59 +++++++++ .../TranscriptGenomicLocationAssociation.java | 59 +++++++++ .../v0.36.0.4__gff_association_tables.sql | 125 ++++++++++++++++++ 17 files changed, 674 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/AssemblyComponentDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/ChromosomeDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/associations/exonAssociations/ExonGenomicLocationAssociationDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/dao/associations/transcriptAssociations/TranscriptGenomicLocationAssociationDAO.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/Chromosome.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java create mode 100644 src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql diff --git a/src/main/java/org/alliancegenome/curation_api/dao/AssemblyComponentDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/AssemblyComponentDAO.java new file mode 100644 index 000000000..09b93576e --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/AssemblyComponentDAO.java @@ -0,0 +1,51 @@ +package org.alliancegenome.curation_api.dao; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alliancegenome.curation_api.dao.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociationDAO; +import org.alliancegenome.curation_api.dao.associations.exonAssociations.ExonGenomicLocationAssociationDAO; +import org.alliancegenome.curation_api.dao.associations.transcriptAssociations.TranscriptGenomicLocationAssociationDAO; +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; +import org.apache.commons.collections.CollectionUtils; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +@ApplicationScoped +public class AssemblyComponentDAO extends BaseSQLDAO { + + @Inject CodingSequenceGenomicLocationAssociationDAO cdsGenomicLocationAssociationDAO; + @Inject ExonGenomicLocationAssociationDAO exonGenomicLocationAssociationDAO; + @Inject TranscriptGenomicLocationAssociationDAO transcriptGenomicLocationAssociationDAO; + + protected AssemblyComponentDAO() { + super(AssemblyComponent.class); + } + + public Boolean hasReferencingGenomicLocationAssociations(Long acId) { + + Map transcriptParams = new HashMap<>(); + transcriptParams.put("transcriptGenomicLocationAssociationObject.id", acId); + List results = transcriptGenomicLocationAssociationDAO.findIdsByParams(transcriptParams); + if (CollectionUtils.isNotEmpty(results)) { + return true; + } + + Map exonParams = new HashMap<>(); + exonParams.put("exonGenomicLocationAssociationObject.id", acId); + results = exonGenomicLocationAssociationDAO.findIdsByParams(exonParams); + if (CollectionUtils.isNotEmpty(results)) { + return true; + } + + Map cdsParams = new HashMap<>(); + cdsParams.put("codingSequenceGenomicLocationAssociationObject.id", acId); + results = cdsGenomicLocationAssociationDAO.findIdsByParams(cdsParams); + + return CollectionUtils.isNotEmpty(results); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/dao/ChromosomeDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/ChromosomeDAO.java new file mode 100644 index 000000000..3f27acf70 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/ChromosomeDAO.java @@ -0,0 +1,32 @@ +package org.alliancegenome.curation_api.dao; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.Chromosome; +import org.apache.commons.collections.CollectionUtils; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +@ApplicationScoped +public class ChromosomeDAO extends BaseSQLDAO { + + @Inject AssemblyComponentDAO assemblyComponentDAO; + + protected ChromosomeDAO() { + super(Chromosome.class); + } + + public Boolean hasReferencingAssemblyComponents(Long chromosomeId) { + + Map params = new HashMap<>(); + params.put("mapsToChromosome.id", chromosomeId); + List results = assemblyComponentDAO.findIdsByParams(params); + + return CollectionUtils.isNotEmpty(results); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/dao/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationDAO.java new file mode 100644 index 000000000..e80741712 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationDAO.java @@ -0,0 +1,15 @@ +package org.alliancegenome.curation_api.dao.associations.codingSequenceAssociations; + +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; + +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class CodingSequenceGenomicLocationAssociationDAO extends BaseSQLDAO { + + protected CodingSequenceGenomicLocationAssociationDAO() { + super(CodingSequenceGenomicLocationAssociation.class); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/dao/associations/exonAssociations/ExonGenomicLocationAssociationDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/associations/exonAssociations/ExonGenomicLocationAssociationDAO.java new file mode 100644 index 000000000..aac6d220d --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/associations/exonAssociations/ExonGenomicLocationAssociationDAO.java @@ -0,0 +1,15 @@ +package org.alliancegenome.curation_api.dao.associations.exonAssociations; + +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; + +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class ExonGenomicLocationAssociationDAO extends BaseSQLDAO { + + protected ExonGenomicLocationAssociationDAO() { + super(ExonGenomicLocationAssociation.class); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/dao/associations/transcriptAssociations/TranscriptGenomicLocationAssociationDAO.java b/src/main/java/org/alliancegenome/curation_api/dao/associations/transcriptAssociations/TranscriptGenomicLocationAssociationDAO.java new file mode 100644 index 000000000..b55d7939a --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/dao/associations/transcriptAssociations/TranscriptGenomicLocationAssociationDAO.java @@ -0,0 +1,15 @@ +package org.alliancegenome.curation_api.dao.associations.transcriptAssociations; + +import org.alliancegenome.curation_api.dao.base.BaseSQLDAO; +import org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations.TranscriptGenomicLocationAssociation; + +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class TranscriptGenomicLocationAssociationDAO extends BaseSQLDAO { + + protected TranscriptGenomicLocationAssociationDAO() { + super(TranscriptGenomicLocationAssociation.class); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/bridges/BiologicalEntityTypeBridge.java b/src/main/java/org/alliancegenome/curation_api/model/bridges/BiologicalEntityTypeBridge.java index efa253b36..b6eb59cf7 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/bridges/BiologicalEntityTypeBridge.java +++ b/src/main/java/org/alliancegenome/curation_api/model/bridges/BiologicalEntityTypeBridge.java @@ -2,6 +2,7 @@ import org.alliancegenome.curation_api.model.entities.AffectedGenomicModel; import org.alliancegenome.curation_api.model.entities.Allele; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; import org.alliancegenome.curation_api.model.entities.BiologicalEntity; import org.alliancegenome.curation_api.model.entities.CodingSequence; import org.alliancegenome.curation_api.model.entities.Exon; @@ -93,6 +94,10 @@ public void write(DocumentElement target, BiologicalEntity bridgedElement, TypeB CodingSequence cds = (CodingSequence) bridgedElement; name = cds.getName(); symbol = null; + } else if (bridgedElement instanceof AssemblyComponent) { + AssemblyComponent ac = (AssemblyComponent) bridgedElement; + name = ac.getName(); + symbol = null; } else { name = null; symbol = null; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java b/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java new file mode 100644 index 000000000..fa6ca8506 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java @@ -0,0 +1,70 @@ +package org.alliancegenome.curation_api.model.entities; + +import java.util.List; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; +import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; +import org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations.TranscriptGenomicLocationAssociation; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Indexed +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@Schema(name = "AssemblyComponent", description = "POJO that represents the AssemblyComponent") +@AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) +@Table( + indexes = { + @Index(name = "assemblycomponent_genomeassembly_index", columnList = "genomeassembly_id") + } +) +public class AssemblyComponent extends GenomicEntity { + + @JsonView({ View.FieldsOnly.class }) + private String name; + + @IndexedEmbedded(includePaths = {"name", "name_keyword", "curie", "curie_keyword", "modEntityId", "modEntityId_keyword", "modInternalId", "modInternalId_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + private GenomeAssembly genomeAssembly; + + @IndexedEmbedded(includePaths = {"name", "name_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + private Chromosome mapsToChromosome; + + @OneToMany(mappedBy = "transcriptGenomicLocationAssociationObject", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonView({ View.FieldsAndLists.class }) + private List transcriptGenomicLocationAssociations; + + @OneToMany(mappedBy = "exonGenomicLocationAssociationObject", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonView({ View.FieldsAndLists.class }) + private List exonGenomicLocationAssociations; + + @OneToMany(mappedBy = "codingSequenceGenomicLocationAssociationObject", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonView({ View.FieldsAndLists.class }) + private List codingSequenceGenomicLocationAssociations; + +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/BiologicalEntity.java b/src/main/java/org/alliancegenome/curation_api/model/entities/BiologicalEntity.java index de9e627f9..fa56b9f46 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/BiologicalEntity.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/BiologicalEntity.java @@ -32,7 +32,11 @@ @JsonSubTypes({ @JsonSubTypes.Type(value = AffectedGenomicModel.class, name = "AffectedGenomicModel"), @JsonSubTypes.Type(value = Allele.class, name = "Allele"), + @JsonSubTypes.Type(value = AssemblyComponent.class, name = "AssemblyComponent"), + @JsonSubTypes.Type(value = CodingSequence.class, name = "CodingSequence"), + @JsonSubTypes.Type(value = Exon.class, name = "Exon"), @JsonSubTypes.Type(value = Gene.class, name = "Gene"), + @JsonSubTypes.Type(value = Transcript.class, name = "Transcript"), @JsonSubTypes.Type(value = Variant.class, name = "Variant"), @JsonSubTypes.Type(value = SequenceTargetingReagent.class, name = "SequenceTargetingReagent") }) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/Chromosome.java b/src/main/java/org/alliancegenome/curation_api/model/entities/Chromosome.java new file mode 100644 index 000000000..721165d9f --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/Chromosome.java @@ -0,0 +1,70 @@ +package org.alliancegenome.curation_api.model.entities; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.base.AuditedObject; +import org.alliancegenome.curation_api.model.entities.ontology.NCBITaxonTerm; +import org.alliancegenome.curation_api.view.View; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Entity +@Data +@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true) +@ToString(callSuper = true) +@AGRCurationSchemaVersion(min = "2.0.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { AuditedObject.class }) +@Table( + indexes = { + @Index(name = "chromosome_taxon_index", columnList = "taxon_id"), + @Index(name = "chromosome_name_index", columnList = "name"), + @Index(name = "chromosome_dataprovider_index", columnList = "dataprovider_id"), + @Index(name = "chromosome_createdby_index", columnList = "createdby_id"), + @Index(name = "chromosome_updatedby_index", columnList = "updatedby_id") + }, + uniqueConstraints = { + @UniqueConstraint(name = "chromosome_name_taxon_uk", columnNames = {"name", "taxon_id"}) + } +) +public class Chromosome extends AuditedObject { + + @IndexedEmbedded(includePaths = {"name", "curie", "name_keyword", "curie_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToOne + @JsonView({ View.FieldsOnly.class, View.ForPublic.class }) + private NCBITaxonTerm taxon; + + @IndexedEmbedded(includePaths = { + "sourceOrganization.abbreviation", "sourceOrganization.fullName", "sourceOrganization.shortName", "crossReference.displayName", "crossReference.referencedCurie", + "sourceOrganization.abbreviation_keyword", "sourceOrganization.fullName_keyword", "sourceOrganization.shortName_keyword", "crossReference.displayName_keyword", "crossReference.referencedCurie_keyword" + }) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToOne + @Fetch(FetchMode.SELECT) + @JsonView({ View.FieldsOnly.class }) + private DataProvider dataProvider; + + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @JsonView({ View.FieldsOnly.class }) + private String name; + +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java b/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java index efde35219..f72677f3b 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/CodingSequence.java @@ -1,7 +1,10 @@ package org.alliancegenome.curation_api.model.entities; +import java.util.List; + import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.media.Schema; @@ -17,9 +20,11 @@ import com.fasterxml.jackson.annotation.JsonView; +import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; import jakarta.persistence.Index; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; @@ -29,7 +34,7 @@ @Entity @Data @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) -@ToString(callSuper = true) +@ToString(exclude = "codingSequenceGenomicLocationAssociations", callSuper = true) @Schema(name = "CodingSequence", description = "POJO that represents the CodingSequence (CDS)") @AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) @Table(indexes = {@Index(name = "codingsequence_uniqueid_index", columnList = "uniqueid")}) @@ -50,4 +55,16 @@ public class CodingSequence extends GenomicEntity { @JsonView({ View.FieldsOnly.class }) private SOTerm cdsType; + @IndexedEmbedded( + includePaths = { + "codingSequenceGenomicLocationAssociationObject.curie", "codingSequenceGenomicLocationAssociationObject.curie_keyword", + "codingSequenceGenomicLocationAssociationObject.modEntityId", "codingSequenceGenomicLocationAssociationObject.modEntityId_keyword", + "codingSequenceGenomicLocationAssociationObject.modInternalId", "codingSequenceGenomicLocationAssociationObject.modInternalId_keyword", + "start", "end" + } + ) + @OneToMany(mappedBy = "codingSequenceAssociationSubject", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonView({ View.FieldsAndLists.class }) + private List codingSequenceGenomicLocationAssociations; + } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java b/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java index b3120d196..8a55175ba 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/Exon.java @@ -1,7 +1,10 @@ package org.alliancegenome.curation_api.model.entities; +import java.util.List; + import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.media.Schema; @@ -17,9 +20,11 @@ import com.fasterxml.jackson.annotation.JsonView; +import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; import jakarta.persistence.Index; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; @@ -29,7 +34,7 @@ @Entity @Data @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) -@ToString(callSuper = true) +@ToString(exclude = "exonGenomicLocationAssociations", callSuper = true) @Schema(name = "Exon", description = "POJO that represents the Exon") @AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) @Table(indexes = {@Index(name = "exon_uniqueid_index", columnList = "uniqueid")}) @@ -50,4 +55,16 @@ public class Exon extends GenomicEntity { @JsonView({ View.FieldsOnly.class }) private SOTerm exonType; + @IndexedEmbedded( + includePaths = { + "exonGenomicLocationAssociationObject.curie", "exonGenomicLocationAssociationObject.curie_keyword", + "exonGenomicLocationAssociationObject.modEntityId", "exonGenomicLocationAssociationObject.modEntityId_keyword", + "exonGenomicLocationAssociationObject.modInternalId", "exonGenomicLocationAssociationObject.modInternalId_keyword", + "start", "end" + } + ) + @OneToMany(mappedBy = "exonAssociationSubject", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonView({ View.FieldsAndLists.class }) + private List exonGenomicLocationAssociations; + } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java new file mode 100644 index 000000000..7378fd39a --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java @@ -0,0 +1,41 @@ +package org.alliancegenome.curation_api.model.entities; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.search.engine.backend.types.Projectable; +import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.ManyToOne; +import jakarta.persistence.MappedSuperclass; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@MappedSuperclass +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@Schema(name = "locationAssociation", description = "POJO that represents a location association") +@AGRCurationSchemaVersion(min = "2.0.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { EvidenceAssociation.class }) +public abstract class LocationAssociation extends EvidenceAssociation { + + @IndexedEmbedded(includePaths = { "name", "name_keyword" }) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + private VocabularyTerm relation; + + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + private Integer start; + + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + private Integer end; + +} + diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java b/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java index 403322155..8c8f5efe2 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/Transcript.java @@ -1,7 +1,10 @@ package org.alliancegenome.curation_api.model.entities; +import java.util.List; + import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations.TranscriptGenomicLocationAssociation; import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.media.Schema; @@ -12,8 +15,10 @@ import com.fasterxml.jackson.annotation.JsonView; +import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -22,7 +27,7 @@ @Entity @Data @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) -@ToString(callSuper = true) +@ToString(exclude = "transcriptGenomicLocationAssociations", callSuper = true) @Schema(name = "Transcript", description = "POJO that represents the Transcript") @AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) public class Transcript extends GenomicEntity { @@ -36,4 +41,16 @@ public class Transcript extends GenomicEntity { @JsonView({ View.FieldsOnly.class }) private SOTerm transcriptType; + @IndexedEmbedded( + includePaths = { + "transcriptGenomicLocationAssociationObject.curie", "transcriptGenomicLocationAssociationObject.curie_keyword", + "transcriptGenomicLocationAssociationObject.modEntityId", "transcriptGenomicLocationAssociationObject.modEntityId_keyword", + "transcriptGenomicLocationAssociationObject.modInternalId", "transcriptGenomicLocationAssociationObject.modInternalId_keyword", + "start", "end" + } + ) + @OneToMany(mappedBy = "transcriptAssociationSubject", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonView({ View.FieldsAndLists.class }) + private List transcriptGenomicLocationAssociations; + } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java new file mode 100644 index 000000000..15b75ce87 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java @@ -0,0 +1,59 @@ +package org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; +import org.alliancegenome.curation_api.model.entities.CodingSequence; +import org.alliancegenome.curation_api.model.entities.LocationAssociation; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { LocationAssociation.class }) +@Schema(name = "CodingSequenceGenomicLocationAssociation", description = "POJO representing an association between a CDS and a genomic location") +@Table( + indexes = { + @Index(name = "codingsequencelocationassociation_relation_index", columnList = "relation_id"), + @Index(name = "codingsequencelocationassociation_subject_index", columnList = "codingsequenceassociationsubject_id"), + @Index(name = "codingsequencelocationassociation_object_index", columnList = "codingsequencegenomiclocationassociationobject_id") + } +) +public class CodingSequenceGenomicLocationAssociation extends LocationAssociation { + + @IndexedEmbedded(includePaths = { + "curie", "curie_keyword", "modEntityId", "modEntityId_keyword", + "modInternalId", "modInternalId_keyword", "name", "name_keyword" + }) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + @JsonIgnoreProperties("codingSequenceGenomicLocationAssociations") + @Fetch(FetchMode.JOIN) + private CodingSequence codingSequenceAssociationSubject; + + @IndexedEmbedded(includePaths = { + "curie", "curie_keyword", "modEntityId", "modEntityId_keyword", + "modInternalId", "modInternalId_keyword", "name", "name_keyword" + }) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + @JsonIgnoreProperties("codingSequenceGenomicLocationAssociations") + @Fetch(FetchMode.JOIN) + private AssemblyComponent codingSequenceGenomicLocationAssociationObject; +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java new file mode 100644 index 000000000..35a11b125 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java @@ -0,0 +1,59 @@ +package org.alliancegenome.curation_api.model.entities.associations.exonAssociations; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; +import org.alliancegenome.curation_api.model.entities.Exon; +import org.alliancegenome.curation_api.model.entities.LocationAssociation; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { LocationAssociation.class }) +@Schema(name = "ExonGenomicLocationAssociation", description = "POJO representing an association between an exon and a genomic location") +@Table( + indexes = { + @Index(name = "exonlocationassociation_relation_index", columnList = "relation_id"), + @Index(name = "exonlocationassociation_subject_index", columnList = "exonassociationsubject_id"), + @Index(name = "exonlocationassociation_object_index", columnList = "exongenomiclocationassociationobject_id") + } +) +public class ExonGenomicLocationAssociation extends LocationAssociation { + + @IndexedEmbedded(includePaths = { + "curie", "curie_keyword", "modEntityId", "modEntityId_keyword", + "modInternalId", "modInternalId_keyword", "name", "name_keyword" + }) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + @JsonIgnoreProperties("exonGenomicLocationAssociations") + @Fetch(FetchMode.JOIN) + private Exon exonAssociationSubject; + + @IndexedEmbedded(includePaths = { + "curie", "curie_keyword", "modEntityId", "modEntityId_keyword", + "modInternalId", "modInternalId_keyword", "name", "name_keyword" + }) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + @JsonIgnoreProperties("exonGenomicLocationAssociations") + @Fetch(FetchMode.JOIN) + private AssemblyComponent exonGenomicLocationAssociationObject; +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java new file mode 100644 index 000000000..1f7488541 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java @@ -0,0 +1,59 @@ +package org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations; + +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; +import org.alliancegenome.curation_api.model.entities.LocationAssociation; +import org.alliancegenome.curation_api.model.entities.Transcript; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { LocationAssociation.class }) +@Schema(name = "TranscriptGenomicLocationAssociation", description = "POJO representing an association between a transcript and a genomic location") +@Table( + indexes = { + @Index(name = "transcriptlocationassociation_relation_index", columnList = "relation_id"), + @Index(name = "transcriptlocationassociation_subject_index", columnList = "transcriptassociationsubject_id"), + @Index(name = "transcriptlocationassociation_object_index", columnList = "transcriptgenomiclocationassociationobject_id") + } +) +public class TranscriptGenomicLocationAssociation extends LocationAssociation { + + @IndexedEmbedded(includePaths = { + "curie", "curie_keyword", "modEntityId", "modEntityId_keyword", + "modInternalId", "modInternalId_keyword", "name", "name_keyword" + }) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + @JsonIgnoreProperties("transcriptGenomicLocationAssociations") + @Fetch(FetchMode.JOIN) + private Transcript transcriptAssociationSubject; + + @IndexedEmbedded(includePaths = { + "curie", "curie_keyword", "modEntityId", "modEntityId_keyword", + "modInternalId", "modInternalId_keyword", "name", "name_keyword" + }) + @ManyToOne + @JsonView({ View.FieldsOnly.class }) + @JsonIgnoreProperties("transcriptGenomicLocationAssociations") + @Fetch(FetchMode.JOIN) + private AssemblyComponent transcriptGenomicLocationAssociationObject; +} diff --git a/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql b/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql new file mode 100644 index 000000000..198b89d94 --- /dev/null +++ b/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql @@ -0,0 +1,125 @@ +CREATE SEQUENCE public.chromosome_seq START WITH 1 INCREMENT BY 50 NO MINVALUE NO MAXVALUE CACHE 1; + +CREATE TABLE chromosome ( + id bigint CONSTRAINT chromosome_pkey PRIMARY KEY, + dataprovider_id bigint, + taxon_id bigint, + name varchar(255), + datecreated timestamp without time zone, + dateupdated timestamp without time zone, + dbdatecreated timestamp without time zone, + dbdateupdated timestamp without time zone, + internal boolean DEFAULT false, + obsolete boolean DEFAULT false, + createdby_id bigint, + updatedby_id bigint +); + +ALTER TABLE chromosome ADD CONSTRAINT chromosome_dataprovider_id_fk + FOREIGN KEY (dataprovider_id) REFERENCES dataprovider (id); +ALTER TABLE chromosome ADD CONSTRAINT chromosome_taxon_id_fk + FOREIGN KEY (taxon_id) REFERENCES ontologyterm (id); +ALTER TABLE chromosome ADD CONSTRAINT chromosome_createdby_id_fk + FOREIGN KEY (createdby_id) REFERENCES person (id); +ALTER TABLE chromosome ADD CONSTRAINT chromosome_updatedby_id_fk + FOREIGN KEY (updatedby_id) REFERENCES person (id); + +ALTER TABLE chromosome ADD CONSTRAINT chromosome_name_taxon_uk UNIQUE (name, taxon_id); + +CREATE INDEX chromosome_name_index ON chromosome USING btree (name); +CREATE INDEX chromosome_dataprovider_index ON chromosome USING btree (dataprovider_id); +CREATE INDEX chromosome_taxon_index ON chromosome USING btree (taxon_id); +CREATE INDEX chromosome_createdby_index ON chromosome USING btree (createdby_id); +CREATE INDEX chromosome_updatedby_index ON chromosome USING btree (updatedby_id); + + +CREATE TABLE assemblycomponent ( + id bigint CONSTRAINT assemblycomponent_pkey PRIMARY KEY, + genomeassembly_id bigint, + mapstochromosome_id bigint, + name varchar(255) +); + +ALTER TABLE assemblycomponent ADD CONSTRAINT assemblycomponent_id_fk + FOREIGN KEY (id) REFERENCES genomicentity(id); +ALTER TABLE assemblycomponent ADD CONSTRAINT assemblycomponent_genomeassembly_id_fk + FOREIGN KEY (genomeassembly_id) REFERENCES genomeassembly(id); +ALTER TABLE assemblycomponent ADD CONSTRAINT assemblycomponent_mapstochromosome_id_fk + FOREIGN KEY (mapstochromosome_id) REFERENCES chromosome(id); + +CREATE INDEX assemblycomponent_genomeassembly_index ON assemblycomponent USING btree (genomeassembly_id); + +CREATE TABLE codingsequencegenomiclocationassociation ( + id bigint CONSTRAINT codingsequencegenomiclocationassociation_pkey PRIMARY KEY, + "start" integer, + "end" integer, + relation_id bigint, + codingsequenceassociationsubject_id bigint, + codingsequencegenomiclocationassociationobject_id bigint +); + +ALTER TABLE codingsequencegenomiclocationassociation ADD CONSTRAINT codingsequencegenomiclocationassociation_id_fk + FOREIGN KEY (id) REFERENCES evidenceassociation(id); +ALTER TABLE codingsequencegenomiclocationassociation ADD CONSTRAINT codingsequencegenomiclocationassociation_relation_id_fk + FOREIGN KEY (relation_id) REFERENCES vocabularyterm(id); +ALTER TABLE codingsequencegenomiclocationassociation ADD CONSTRAINT codingsequencegenomiclocationassociation_cdsasubject_id_fk + FOREIGN KEY (codingsequenceassociationsubject_id) REFERENCES codingsequence(id); +ALTER TABLE codingsequencegenomiclocationassociation ADD CONSTRAINT codingsequencegenomiclocationassociation_cdsglaobject_id_fk + FOREIGN KEY (codingsequencegenomiclocationassociationobject_id) REFERENCES assemblycomponent(id); + +CREATE INDEX codingsequencelocationassociation_relation_index ON codingsequencegenomiclocationassociation + USING btree (relation_id); +CREATE INDEX codingsequencelocationassociation_subject_index ON codingsequencegenomiclocationassociation + USING btree (codingsequenceassociationsubject_id); +CREATE INDEX codingsequencelocationassociation_object_index ON codingsequencegenomiclocationassociation + USING btree (codingsequencegenomiclocationassociationobject_id); + +CREATE TABLE exongenomiclocationassociation ( + id bigint CONSTRAINT exongenomiclocationassociation_pkey PRIMARY KEY, + "start" integer, + "end" integer, + relation_id bigint, + exonassociationsubject_id bigint, + exongenomiclocationassociationobject_id bigint +); + +ALTER TABLE exongenomiclocationassociation ADD CONSTRAINT exongenomiclocationassociation_id_fk + FOREIGN KEY (id) REFERENCES evidenceassociation(id); +ALTER TABLE exongenomiclocationassociation ADD CONSTRAINT exongenomiclocationassociation_relation_id_fk + FOREIGN KEY (relation_id) REFERENCES vocabularyterm(id); +ALTER TABLE exongenomiclocationassociation ADD CONSTRAINT exongenomiclocationassociation_easubject_id_fk + FOREIGN KEY (exonassociationsubject_id) REFERENCES exon(id); +ALTER TABLE exongenomiclocationassociation ADD CONSTRAINT exongenomiclocationassociation_eglaobject_id_fk + FOREIGN KEY (exongenomiclocationassociationobject_id) REFERENCES assemblycomponent(id); + +CREATE INDEX exonlocationassociation_relation_index ON exongenomiclocationassociation + USING btree (relation_id); +CREATE INDEX exonlocationassociation_subject_index ON exongenomiclocationassociation + USING btree (exonassociationsubject_id); +CREATE INDEX exonlocationassociation_object_index ON exongenomiclocationassociation + USING btree (exongenomiclocationassociationobject_id); + +CREATE TABLE transcriptgenomiclocationassociation ( + id bigint CONSTRAINT transcriptgenomiclocationassociation_pkey PRIMARY KEY, + "start" integer, + "end" integer, + relation_id bigint, + transcriptassociationsubject_id bigint, + transcriptgenomiclocationassociationobject_id bigint +); + +ALTER TABLE transcriptgenomiclocationassociation ADD CONSTRAINT transcriptgenomiclocationassociation_id_fk + FOREIGN KEY (id) REFERENCES evidenceassociation(id); +ALTER TABLE transcriptgenomiclocationassociation ADD CONSTRAINT transcriptgenomiclocationassociation_relation_id_fk + FOREIGN KEY (relation_id) REFERENCES vocabularyterm(id); +ALTER TABLE transcriptgenomiclocationassociation ADD CONSTRAINT transcriptgenomiclocationassociation_tasubject_id_fk + FOREIGN KEY (transcriptassociationsubject_id) REFERENCES transcript(id); +ALTER TABLE transcriptgenomiclocationassociation ADD CONSTRAINT transcriptgenomiclocationassociation_tglaobject_id_fk + FOREIGN KEY (transcriptgenomiclocationassociationobject_id) REFERENCES assemblycomponent(id); + +CREATE INDEX transcriptlocationassociation_relation_index ON transcriptgenomiclocationassociation + USING btree (relation_id); +CREATE INDEX transcriptlocationassociation_subject_index ON transcriptgenomiclocationassociation + USING btree (transcriptassociationsubject_id); +CREATE INDEX transcriptlocationassociation_object_index ON transcriptgenomiclocationassociation + USING btree (transcriptgenomiclocationassociationobject_id); \ No newline at end of file From bf735fc133f86282960f9cd272550d90d7e76a75 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 11 Jul 2024 15:43:22 +0100 Subject: [PATCH 34/82] Association services --- .../constants/EntityFieldConstants.java | 3 + .../jobs/executors/Gff3Executor.java | 26 ++++- .../curation_api/services/Gff3Service.java | 31 +++++- ...enceGenomicLocationAssociationService.java | 101 ++++++++++++++++++ ...ExonGenomicLocationAssociationService.java | 101 ++++++++++++++++++ ...riptGenomicLocationAssociationService.java | 101 ++++++++++++++++++ .../validation/dto/Gff3DtoValidator.java | 22 ++++ 7 files changed, 378 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java diff --git a/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java b/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java index a86abe168..a79114e6f 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java @@ -14,7 +14,10 @@ private EntityFieldConstants() { public static final String PA_SUBJECT = "phenotypeAnnotationSubject"; public static final String PA_SUBJECT_TAXON = PA_SUBJECT + "." + TAXON; public static final String ALLELE_ASSOCIATION_SUBJECT_DATA_PROVIDER = "alleleAssociationSubject." + DATA_PROVIDER; + public static final String CODING_SEQUENCE_ASSOCIATION_SUBJECT_DATA_PROVIDER = "codingSequenceAssociationSubject." + DATA_PROVIDER; public static final String CONSTRUCT_ASSOCIATION_SUBJECT_DATA_PROVIDER = "constructAssociationSubject." + DATA_PROVIDER; + public static final String EXON_ASSOCIATION_SUBJECT_DATA_PROVIDER = "exonAssociationSubject." + DATA_PROVIDER; + public static final String TRANSCRIPT_ASSOCIATION_SUBJECT_DATA_PROVIDER = "transcriptAssociationSubject." + DATA_PROVIDER; public static final String SUBJECT_GENE_DATA_PROVIDER = "subjectGene." + DATA_PROVIDER; public static final String SUBJECT_GENE_TAXON = "subjectGene." + TAXON; public static final String EA_SUBJECT_TAXON = "expressionAnnotationSubject.taxon.curie"; diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java index 34705544d..abf01caf2 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java @@ -22,8 +22,10 @@ import org.alliancegenome.curation_api.services.ExonService; import org.alliancegenome.curation_api.services.Gff3Service; import org.alliancegenome.curation_api.services.TranscriptService; +import org.alliancegenome.curation_api.services.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociationService; +import org.alliancegenome.curation_api.services.associations.exonAssociations.ExonGenomicLocationAssociationService; +import org.alliancegenome.curation_api.services.associations.transcriptAssociations.TranscriptGenomicLocationAssociationService; import org.alliancegenome.curation_api.util.ProcessDisplayHelper; -import org.apache.commons.lang3.ObjectUtils; import com.fasterxml.jackson.databind.MappingIterator; import com.fasterxml.jackson.dataformat.csv.CsvMapper; @@ -40,6 +42,9 @@ public class Gff3Executor extends LoadFileExecutor { @Inject ExonService exonService; @Inject CodingSequenceService cdsService; @Inject TranscriptService transcriptService; + @Inject ExonGenomicLocationAssociationService exonLocationService; + @Inject CodingSequenceGenomicLocationAssociationService cdsLocationService; + @Inject TranscriptGenomicLocationAssociationService transcriptLocationService; public void execLoad(BulkLoadFile bulkLoadFile) { try { @@ -66,6 +71,9 @@ public void execLoad(BulkLoadFile bulkLoadFile) { idsAdded.put("Transcript", new ArrayList()); idsAdded.put("Exon", new ArrayList()); idsAdded.put("CodingSequence", new ArrayList()); + idsAdded.put("TranscriptGenomicLocationAssociation", new ArrayList()); + idsAdded.put("ExonGenomicLocationAssociation", new ArrayList()); + idsAdded.put("CodingSequenceGenomicLocationAssociation", new ArrayList()); Map> previousIds = getPreviouslyLoadedIds(dataProvider); @@ -75,6 +83,9 @@ public void execLoad(BulkLoadFile bulkLoadFile) { runCleanup(transcriptService, history, dataProvider.name(), previousIds.get("Transcript"), idsAdded.get("Transcript"), "GFF transcript", bulkLoadFile.getMd5Sum()); runCleanup(exonService, history, dataProvider.name(), previousIds.get("Exon"), idsAdded.get("Exon"), "GFF exon", bulkLoadFile.getMd5Sum()); runCleanup(cdsService, history, dataProvider.name(), previousIds.get("CodingSequence"), idsAdded.get("CodingSequence"), "GFF coding sequence", bulkLoadFile.getMd5Sum()); + runCleanup(transcriptLocationService, history, dataProvider.name(), previousIds.get("TranscriptGenomicLocationAssociation"), idsAdded.get("TranscriptGenomicLocationAssociation"), "GFF transcript genomic location association", bulkLoadFile.getMd5Sum()); + runCleanup(exonLocationService, history, dataProvider.name(), previousIds.get("ExonGenomicLocationAssociation"), idsAdded.get("ExonGenomicLocationAssociation"), "GFF exon genomic location association", bulkLoadFile.getMd5Sum()); + runCleanup(cdsLocationService, history, dataProvider.name(), previousIds.get("CodingSequenceGenomicLocationAssociation"), idsAdded.get("CodingSequenceGenomicLocationAssociation"), "GFF coding sequence genomic location association", bulkLoadFile.getMd5Sum()); history.finishLoad(); finalSaveHistory(history); @@ -90,6 +101,10 @@ private Map> getPreviouslyLoadedIds(BackendBulkDataProvider d previousIds.put("Transcript", transcriptService.getIdsByDataProvider(dataProvider)); previousIds.put("Exon", exonService.getIdsByDataProvider(dataProvider)); previousIds.put("CodingSequence", cdsService.getIdsByDataProvider(dataProvider)); + previousIds.put("TranscriptGenomicLocationAssociation", transcriptLocationService.getIdsByDataProvider(dataProvider)); + previousIds.put("ExonGenomicLocationAssociation", exonLocationService.getIdsByDataProvider(dataProvider)); + previousIds.put("CodingSequenceGenomicLocationAssociation", cdsLocationService.getIdsByDataProvider(dataProvider)); + return previousIds; } @@ -108,9 +123,7 @@ private Map> runLoad(BulkLoadFileHistory history, List()); idsAdded.put("Exon", new ArrayList()); idsAdded.put("CodingSequence", new ArrayList()); + idsAdded.put("TranscriptGenomicLocationAssociation", new ArrayList()); + idsAdded.put("ExonGenomicLocationAssociation", new ArrayList()); + idsAdded.put("CodingSequenceGenomicLocationAssociation", new ArrayList()); BulkLoadFileHistory history = new BulkLoadFileHistory((gffData.size() * 2) + 1); BackendBulkDataProvider dataProvider = BackendBulkDataProvider.valueOf(dataProviderName); runLoad(history, null, gffData, idsAdded, dataProvider, assemblyName); @@ -171,7 +187,7 @@ private Map> loadAssociations(BulkLoadFileHistory history, Li BackendBulkDataProvider dataProvider, GenomeAssembly assembly, ProcessDisplayHelper ph) { for (Gff3DTO gff3Entry : gffData) { try { - idsAdded = gff3Service.loadAssociation(history, gff3Entry, idsAdded, dataProvider, assembly); + idsAdded = gff3Service.loadAssociations(history, gff3Entry, idsAdded, dataProvider, assembly); history.incrementCompleted(); } catch (ObjectUpdateException e) { history.incrementFailed(); diff --git a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java index 3910b5045..07eaa030e 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java +++ b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java @@ -15,11 +15,15 @@ import org.alliancegenome.curation_api.model.entities.Exon; import org.alliancegenome.curation_api.model.entities.GenomeAssembly; import org.alliancegenome.curation_api.model.entities.Transcript; +import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; +import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; +import org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations.TranscriptGenomicLocationAssociation; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; import org.alliancegenome.curation_api.response.SearchResponse; import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; import org.alliancegenome.curation_api.services.validation.dto.Gff3DtoValidator; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import jakarta.enterprise.context.RequestScoped; @@ -88,8 +92,31 @@ public Map> loadEntity(BulkLoadFileHistory history, Gff3DTO g return idsAdded; } - public Map> loadAssociation(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider, GenomeAssembly assembly) throws ObjectUpdateException { - // TODO: implement association loading + public Map> loadAssociations(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider, GenomeAssembly assembly) throws ObjectUpdateException { + if (ObjectUtils.isEmpty(assembly)) { + throw new ObjectValidationException(gffEntry, "Cannot load associations without assembly"); + } + + if (StringUtils.equals(gffEntry.getType(), "exon") || StringUtils.equals(gffEntry.getType(), "noncoding_exon")) { + ExonGenomicLocationAssociation exonLocation = gff3DtoValidator.validateExonLocation(gffEntry, assembly, dataProvider); + if (exonLocation != null) { + idsAdded.get("ExonGenomicLocationAssociation").add(exonLocation.getId()); + } + } else if (StringUtils.equals(gffEntry.getType(), "CDS")) { + CodingSequenceGenomicLocationAssociation cdsLocation = gff3DtoValidator.validateCdsLocation(gffEntry, assembly, dataProvider); + if (cdsLocation != null) { + idsAdded.get("CodingSequenceGenomicLocationAssociation").add(cdsLocation.getId()); + } + } else if (Gff3Constants.TRANSCRIPT_TYPES.contains(gffEntry.getType())) { + if (StringUtils.equals(gffEntry.getType(), "lnc_RNA")) { + gffEntry.setType("lncRNA"); + } + TranscriptGenomicLocationAssociation transcriptLocation = gff3DtoValidator.validateTranscriptLocation(gffEntry, assembly, dataProvider); + if (transcriptLocation != null) { + idsAdded.get("TranscriptGenomicLocationAssociation").add(transcriptLocation.getId()); + } + } + return idsAdded; } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java new file mode 100644 index 000000000..b611e5549 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java @@ -0,0 +1,101 @@ +package org.alliancegenome.curation_api.services.associations.codingSequenceAssociations; + +import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.alliancegenome.curation_api.constants.EntityFieldConstants; +import org.alliancegenome.curation_api.dao.PersonDAO; +import org.alliancegenome.curation_api.dao.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociationDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.exceptions.ApiErrorException; +import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.services.PersonService; +import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; +import lombok.extern.jbosslog.JBossLog; + +@JBossLog +@RequestScoped +public class CodingSequenceGenomicLocationAssociationService extends BaseEntityCrudService { + + @Inject CodingSequenceGenomicLocationAssociationDAO codingSequenceGenomicLocationAssociationDAO; + @Inject PersonDAO personDAO; + @Inject PersonService personService; + + @Override + @PostConstruct + protected void init() { + setSQLDao(codingSequenceGenomicLocationAssociationDAO); + } + + + public List getIdsByDataProvider(BackendBulkDataProvider dataProvider) { + Map params = new HashMap<>(); + params.put(EntityFieldConstants.CODING_SEQUENCE_ASSOCIATION_SUBJECT_DATA_PROVIDER, dataProvider.sourceOrganization); + List associationIds = codingSequenceGenomicLocationAssociationDAO.findIdsByParams(params); + associationIds.removeIf(Objects::isNull); + + return associationIds; + } + + @Override + @Transactional + public CodingSequenceGenomicLocationAssociation deprecateOrDelete(Long id, Boolean throwApiError, String loadDescription, Boolean deprecate) { + CodingSequenceGenomicLocationAssociation association = codingSequenceGenomicLocationAssociationDAO.find(id); + + if (association == null) { + String errorMessage = "Could not find CodingSequenceGenomicLocationAssociation with id: " + id; + if (throwApiError) { + ObjectResponse response = new ObjectResponse<>(); + response.addErrorMessage("id", errorMessage); + throw new ApiErrorException(response); + } + log.error(errorMessage); + return null; + } + if (deprecate) { + if (!association.getObsolete()) { + association.setObsolete(true); + if (authenticatedPerson.getId() != null) { + association.setUpdatedBy(personDAO.find(authenticatedPerson.getId())); + } else { + association.setUpdatedBy(personService.fetchByUniqueIdOrCreate(loadDescription)); + } + association.setDateUpdated(OffsetDateTime.now()); + return codingSequenceGenomicLocationAssociationDAO.persist(association); + } + return association; + } + + codingSequenceGenomicLocationAssociationDAO.remove(association.getId()); + + return null; + } + + public ObjectResponse getLocationAssociation(Long codingSequenceId, Long assemblyComponentId) { + CodingSequenceGenomicLocationAssociation association = null; + + Map params = new HashMap<>(); + params.put("codingSequenceAssociationSubject.id", codingSequenceId); + params.put("codingSequenceGenomicLocationAssociationObject.id", assemblyComponentId); + + SearchResponse resp = codingSequenceGenomicLocationAssociationDAO.findByParams(params); + if (resp != null && resp.getSingleResult() != null) { + association = resp.getSingleResult(); + } + + ObjectResponse response = new ObjectResponse<>(); + response.setEntity(association); + + return response; + } +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java new file mode 100644 index 000000000..c2c767616 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java @@ -0,0 +1,101 @@ +package org.alliancegenome.curation_api.services.associations.exonAssociations; + +import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.alliancegenome.curation_api.constants.EntityFieldConstants; +import org.alliancegenome.curation_api.dao.PersonDAO; +import org.alliancegenome.curation_api.dao.associations.exonAssociations.ExonGenomicLocationAssociationDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.exceptions.ApiErrorException; +import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.services.PersonService; +import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; +import lombok.extern.jbosslog.JBossLog; + +@JBossLog +@RequestScoped +public class ExonGenomicLocationAssociationService extends BaseEntityCrudService { + + @Inject ExonGenomicLocationAssociationDAO exonGenomicLocationAssociationDAO; + @Inject PersonDAO personDAO; + @Inject PersonService personService; + + @Override + @PostConstruct + protected void init() { + setSQLDao(exonGenomicLocationAssociationDAO); + } + + + public List getIdsByDataProvider(BackendBulkDataProvider dataProvider) { + Map params = new HashMap<>(); + params.put(EntityFieldConstants.EXON_ASSOCIATION_SUBJECT_DATA_PROVIDER, dataProvider.sourceOrganization); + List associationIds = exonGenomicLocationAssociationDAO.findIdsByParams(params); + associationIds.removeIf(Objects::isNull); + + return associationIds; + } + + @Override + @Transactional + public ExonGenomicLocationAssociation deprecateOrDelete(Long id, Boolean throwApiError, String loadDescription, Boolean deprecate) { + ExonGenomicLocationAssociation association = exonGenomicLocationAssociationDAO.find(id); + + if (association == null) { + String errorMessage = "Could not find ExonGenomicLocationAssociation with id: " + id; + if (throwApiError) { + ObjectResponse response = new ObjectResponse<>(); + response.addErrorMessage("id", errorMessage); + throw new ApiErrorException(response); + } + log.error(errorMessage); + return null; + } + if (deprecate) { + if (!association.getObsolete()) { + association.setObsolete(true); + if (authenticatedPerson.getId() != null) { + association.setUpdatedBy(personDAO.find(authenticatedPerson.getId())); + } else { + association.setUpdatedBy(personService.fetchByUniqueIdOrCreate(loadDescription)); + } + association.setDateUpdated(OffsetDateTime.now()); + return exonGenomicLocationAssociationDAO.persist(association); + } + return association; + } + + exonGenomicLocationAssociationDAO.remove(association.getId()); + + return null; + } + + public ObjectResponse getLocationAssociation(Long exonId, Long assemblyComponentId) { + ExonGenomicLocationAssociation association = null; + + Map params = new HashMap<>(); + params.put("exonAssociationSubject.id", exonId); + params.put("exonGenomicLocationAssociationObject.id", assemblyComponentId); + + SearchResponse resp = exonGenomicLocationAssociationDAO.findByParams(params); + if (resp != null && resp.getSingleResult() != null) { + association = resp.getSingleResult(); + } + + ObjectResponse response = new ObjectResponse<>(); + response.setEntity(association); + + return response; + } +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java new file mode 100644 index 000000000..893a425c1 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java @@ -0,0 +1,101 @@ +package org.alliancegenome.curation_api.services.associations.transcriptAssociations; + +import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.alliancegenome.curation_api.constants.EntityFieldConstants; +import org.alliancegenome.curation_api.dao.PersonDAO; +import org.alliancegenome.curation_api.dao.associations.transcriptAssociations.TranscriptGenomicLocationAssociationDAO; +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.exceptions.ApiErrorException; +import org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations.TranscriptGenomicLocationAssociation; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.services.PersonService; +import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; +import lombok.extern.jbosslog.JBossLog; + +@JBossLog +@RequestScoped +public class TranscriptGenomicLocationAssociationService extends BaseEntityCrudService { + + @Inject TranscriptGenomicLocationAssociationDAO transcriptGenomicLocationAssociationDAO; + @Inject PersonDAO personDAO; + @Inject PersonService personService; + + @Override + @PostConstruct + protected void init() { + setSQLDao(transcriptGenomicLocationAssociationDAO); + } + + + public List getIdsByDataProvider(BackendBulkDataProvider dataProvider) { + Map params = new HashMap<>(); + params.put(EntityFieldConstants.TRANSCRIPT_ASSOCIATION_SUBJECT_DATA_PROVIDER, dataProvider.sourceOrganization); + List associationIds = transcriptGenomicLocationAssociationDAO.findIdsByParams(params); + associationIds.removeIf(Objects::isNull); + + return associationIds; + } + + @Override + @Transactional + public TranscriptGenomicLocationAssociation deprecateOrDelete(Long id, Boolean throwApiError, String loadDescription, Boolean deprecate) { + TranscriptGenomicLocationAssociation association = transcriptGenomicLocationAssociationDAO.find(id); + + if (association == null) { + String errorMessage = "Could not find TranscriptGenomicLocationAssociation with id: " + id; + if (throwApiError) { + ObjectResponse response = new ObjectResponse<>(); + response.addErrorMessage("id", errorMessage); + throw new ApiErrorException(response); + } + log.error(errorMessage); + return null; + } + if (deprecate) { + if (!association.getObsolete()) { + association.setObsolete(true); + if (authenticatedPerson.getId() != null) { + association.setUpdatedBy(personDAO.find(authenticatedPerson.getId())); + } else { + association.setUpdatedBy(personService.fetchByUniqueIdOrCreate(loadDescription)); + } + association.setDateUpdated(OffsetDateTime.now()); + return transcriptGenomicLocationAssociationDAO.persist(association); + } + return association; + } + + transcriptGenomicLocationAssociationDAO.remove(association.getId()); + + return null; + } + + public ObjectResponse getLocationAssociation(Long transcriptId, Long assemblyComponentId) { + TranscriptGenomicLocationAssociation association = null; + + Map params = new HashMap<>(); + params.put("transcriptAssociationSubject.id", transcriptId); + params.put("transcriptGenomicLocationAssociationObject.id", assemblyComponentId); + + SearchResponse resp = transcriptGenomicLocationAssociationDAO.findByParams(params); + if (resp != null && resp.getSingleResult() != null) { + association = resp.getSingleResult(); + } + + ObjectResponse response = new ObjectResponse<>(); + response.setEntity(association); + + return response; + } +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java index 1e31a1c27..3d0e51665 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -13,8 +13,12 @@ import org.alliancegenome.curation_api.exceptions.ObjectValidationException; import org.alliancegenome.curation_api.model.entities.CodingSequence; import org.alliancegenome.curation_api.model.entities.Exon; +import org.alliancegenome.curation_api.model.entities.GenomeAssembly; import org.alliancegenome.curation_api.model.entities.GenomicEntity; import org.alliancegenome.curation_api.model.entities.Transcript; +import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; +import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; +import org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations.TranscriptGenomicLocationAssociation; import org.alliancegenome.curation_api.model.entities.ontology.SOTerm; import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; import org.alliancegenome.curation_api.response.ObjectResponse; @@ -170,4 +174,22 @@ private Map getAttributes(Gff3DTO dto, BackendBulkDataProvider d return attributes; } + public CodingSequenceGenomicLocationAssociation validateCdsSequenceLocation(Gff3DTO gffEntry, GenomeAssembly assembly, + BackendBulkDataProvider dataProvider) { + // TODO Auto-generated method stub + return null; + } + + public ExonGenomicLocationAssociation validateExonLocation(Gff3DTO gffEntry, GenomeAssembly assembly, + BackendBulkDataProvider dataProvider) { + // TODO Auto-generated method stub + return null; + } + + public TranscriptGenomicLocationAssociation validateTranscriptLocation(Gff3DTO gffEntry, GenomeAssembly assembly, + BackendBulkDataProvider dataProvider) { + // TODO Auto-generated method stub + return null; + } + } From cb6ed28110ae6f5eae19edf7054bef3f5996e58e Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Thu, 11 Jul 2024 10:17:41 -0500 Subject: [PATCH 35/82] SCRUM-4259 fix construct table error --- .../ConstructGenomicEntityAssociation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/constructAssociations/ConstructGenomicEntityAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/constructAssociations/ConstructGenomicEntityAssociation.java index 352218bbb..20373fcfd 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/constructAssociations/ConstructGenomicEntityAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/constructAssociations/ConstructGenomicEntityAssociation.java @@ -66,7 +66,7 @@ public class ConstructGenomicEntityAssociation extends EvidenceAssociation { @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @OneToOne @JsonView({ View.FieldsOnly.class }) - @JsonIgnoreProperties({"alleleGeneAssociations", "constructGenomicEntityAssociations"}) + @JsonIgnoreProperties({"alleleGeneAssociations", "constructGenomicEntityAssociations", "sequenceTargetingReagentGeneAssociations"}) private GenomicEntity constructGenomicEntityAssociationObject; @IndexedEmbedded(includePaths = {"freeText", "noteType.name", "references.curie", From 437c5ffb5424c4d50db5d55e46d508986070e47a Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 11 Jul 2024 16:48:42 +0100 Subject: [PATCH 36/82] Prevent serialisation of associations --- .../SequenceTargetingReagentGeneAssociation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/sequenceTargetingReagentAssociations/SequenceTargetingReagentGeneAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/sequenceTargetingReagentAssociations/SequenceTargetingReagentGeneAssociation.java index 61769cdde..836ed15cc 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/sequenceTargetingReagentAssociations/SequenceTargetingReagentGeneAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/sequenceTargetingReagentAssociations/SequenceTargetingReagentGeneAssociation.java @@ -44,6 +44,7 @@ public class SequenceTargetingReagentGeneAssociation extends EvidenceAssociation { @IndexedEmbedded(includePaths = {"name", "synonyms", "secondaryIdentifiers"}) + @JsonIgnoreProperties("sequenceTargetingReagentGeneAssociations") @ManyToOne @JsonView({ View.FieldsOnly.class }) @Fetch(FetchMode.JOIN) @@ -62,6 +63,6 @@ public class SequenceTargetingReagentGeneAssociation extends EvidenceAssociation @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @ManyToOne @JsonView({ View.FieldsOnly.class }) - @JsonIgnoreProperties({ "alleleGeneAssociations", "constructGenomicEntityAssociations" }) + @JsonIgnoreProperties({ "alleleGeneAssociations", "constructGenomicEntityAssociations", "sequenceTargetingReagentGeneAssociations" }) private Gene sequenceTargetingReagentGeneAssociationObject; } From 46e383f744c5d3c4652f06d391d7ec144f26697d Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 11 Jul 2024 17:23:02 +0100 Subject: [PATCH 37/82] Add prefix to ID attribute --- .../services/validation/dto/Gff3DtoValidator.java | 11 +++++++++++ .../curation_api/Gff3BulkUploadITCase.java | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java index 1e31a1c27..d4516f702 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -167,6 +167,17 @@ private Map getAttributes(Gff3DTO dto, BackendBulkDataProvider d } } + for (String key : List.of("ID", "Parent")) { + if (attributes.containsKey(key)) { + String id = attributes.get(key); + String[] idParts = id.split(":"); + if (idParts.length == 1) { + id = dataProvider.name() + ':' + idParts[0]; + } + attributes.put(key, id); + } + } + return attributes; } diff --git a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java index ec9e06414..247fc8f4a 100644 --- a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java @@ -41,9 +41,9 @@ public void init() { private final String transcriptGetEndpoint = "/api/transcript/"; private final String exonGetEndpoint = "/api/exon/"; private final String cdsGetEndpoint = "/api/cds/"; - private final String transcriptId = "Y74C9A.2a.1"; - private final String exonUniqueId = "Y74C9A.2a_exon|Y74C9A.2a.1|I|1|100|+"; - private final String cdsUniqueId = "Y74C9A.2a|Y74C9A.2a.1|I|10|100|+"; + private final String transcriptId = "WB:Y74C9A.2a.1"; + private final String exonUniqueId = "WB:Y74C9A.2a_exon|WB:Y74C9A.2a.1|I|1|100|+"; + private final String cdsUniqueId = "WB:Y74C9A.2a|WB:Y74C9A.2a.1|I|10|100|+"; private void loadRequiredEntities() throws Exception { createSoTerm("SO:0000234", "mRNA", false); From af9a2bf00b9b3d73971a087f8a818efcb616c18f Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Thu, 11 Jul 2024 09:01:21 -0500 Subject: [PATCH 38/82] SCRUM-4187 update SQTR endpoints to exclude gene associations --- ...SequenceTargetingReagentCrudInterface.java | 21 +++++++++++++++++++ .../entities/SequenceTargetingReagent.java | 8 +++---- .../curation_api/view/View.java | 6 ++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java index 274e4415d..29571072c 100644 --- a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java @@ -1,19 +1,26 @@ package org.alliancegenome.curation_api.interfaces.crud; +import java.util.HashMap; + import org.alliancegenome.curation_api.interfaces.base.BaseIdCrudInterface; +import org.alliancegenome.curation_api.model.entities.Allele; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentIngestFmsDTO; import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.response.SearchResponse; import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; import org.eclipse.microprofile.openapi.annotations.tags.Tag; import com.fasterxml.jackson.annotation.JsonView; import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DefaultValue; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; @Path("/sqtr") @@ -26,4 +33,18 @@ public interface SequenceTargetingReagentCrudInterface extends BaseIdCrudInterfa @Path("/bulk/{dataProvider}/sqtrfile") @JsonView(View.FieldsAndLists.class) APIResponse updateSequenceTargetingReagent(@PathParam("dataProvider") String dataProvider, SequenceTargetingReagentIngestFmsDTO sqtrData); + + @Override + @POST + @Path("/find") + @Tag(name = "Relational Database Browsing Endpoints") + @JsonView(View.SequenceTargetingReagentView.class) + SearchResponse find(@DefaultValue("0") @QueryParam("page") Integer page, @DefaultValue("10") @QueryParam("limit") Integer limit, @RequestBody HashMap params); + + @Override + @POST + @Path("/search") + @Tag(name = "Elastic Search Browsing Endpoints") + @JsonView({ View.SequenceTargetingReagentView.class }) + SearchResponse search(@DefaultValue("0") @QueryParam("page") Integer page, @DefaultValue("10") @QueryParam("limit") Integer limit, @RequestBody HashMap params); } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/SequenceTargetingReagent.java b/src/main/java/org/alliancegenome/curation_api/model/entities/SequenceTargetingReagent.java index 8ab8aadbb..6fb8a4510 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/SequenceTargetingReagent.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/SequenceTargetingReagent.java @@ -53,24 +53,24 @@ public class SequenceTargetingReagent extends GenomicEntity { @Index(name = "sequencetargetingreagent_reference_sqtr_index", columnList = "sequencetargetingreagent_id"), @Index(name = "sequencetargetingreagent_reference_references_index", columnList = "references_id") }) - @JsonView({ View.FieldsAndLists.class }) + @JsonView({ View.FieldsAndLists.class, View.SequenceTargetingReagentView.class }) private List references; @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") @KeywordField(name = "synonyms_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") @ElementCollection @JoinTable(indexes = @Index(name = "sequencetargetingreagent_synonyms_sequencetargetingreagent_index", columnList = "sequencetargetingreagent_id")) - @JsonView({ View.FieldsAndLists.class }) + @JsonView({ View.FieldsAndLists.class, View.SequenceTargetingReagentView.class }) private List synonyms; @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") @KeywordField(name = "secondaryIdentifiers_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") @ElementCollection @JoinTable(indexes = @Index(name = "sequencetargetingreagent_secondaryIdentifiers_sequencetargetingreagent_index", columnList = "sequencetargetingreagent_id")) - @JsonView({ View.FieldsAndLists.class }) + @JsonView({ View.FieldsAndLists.class, View.SequenceTargetingReagentView.class }) private List secondaryIdentifiers; @OneToMany(mappedBy = "sequenceTargetingReagentAssociationSubject", cascade = CascadeType.ALL, orphanRemoval = true) - @JsonView({ View.FieldsAndLists.class }) + @JsonView({ View.FieldsAndLists.class, View.SequenceTargetingReagentDetailView.class }) private List sequenceTargetingReagentGeneAssociations; } diff --git a/src/main/java/org/alliancegenome/curation_api/view/View.java b/src/main/java/org/alliancegenome/curation_api/view/View.java index 03c1ea2ab..24dc2fbc4 100644 --- a/src/main/java/org/alliancegenome/curation_api/view/View.java +++ b/src/main/java/org/alliancegenome/curation_api/view/View.java @@ -73,6 +73,12 @@ public static class AlleleView extends FieldsOnly { public static class AlleleDetailView extends AlleleView { } + public static class SequenceTargetingReagentView extends FieldsOnly { + } + + public static class SequenceTargetingReagentDetailView extends SequenceTargetingReagentView { + } + public static class AlleleUpdate extends AlleleView { } From 4d6196de8f8f5d4f9c78b7cccd032e3791c5f675 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Thu, 11 Jul 2024 11:35:15 -0500 Subject: [PATCH 39/82] SCRUM-4187 add SQTR Gene Association controller and interface --- ...gReagentGeneAssociationCrudController.java | 35 +++++++++++++++++++ ...SequenceTargetingReagentCrudInterface.java | 1 - ...ngReagentGeneAssociationCrudInterface.java | 26 ++++++++++++++ ...argetingReagentGeneAssociationService.java | 10 +++++- 4 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java create mode 100644 src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java diff --git a/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java b/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java new file mode 100644 index 000000000..4b4cdaee3 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java @@ -0,0 +1,35 @@ +package org.alliancegenome.curation_api.controllers.crud.associations; + +import java.util.List; + +import org.alliancegenome.curation_api.controllers.base.BaseEntityCrudController; +import org.alliancegenome.curation_api.dao.associations.SequenceTargetingReagentGeneAssociationDAO; +import org.alliancegenome.curation_api.dao.associations.alleleAssociations.AlleleGeneAssociationDAO; +import org.alliancegenome.curation_api.interfaces.crud.associations.SequenceTargetingReagentGeneAssociationCrudInterface; +import org.alliancegenome.curation_api.interfaces.crud.associations.alleleAssociations.AlleleGeneAssociationCrudInterface; +import org.alliancegenome.curation_api.jobs.executors.SequenceTargetingReagentExecutor; +import org.alliancegenome.curation_api.jobs.executors.associations.alleleAssociations.AlleleGeneAssociationExecutor; +import org.alliancegenome.curation_api.model.entities.associations.alleleAssociations.AlleleGeneAssociation; +import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; +import org.alliancegenome.curation_api.model.ingest.dto.associations.alleleAssociations.AlleleGeneAssociationDTO; +import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.services.associations.SequenceTargetingReagentGeneAssociationService; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; + +@RequestScoped +public class SequenceTargetingReagentGeneAssociationCrudController extends + BaseEntityCrudController implements SequenceTargetingReagentGeneAssociationCrudInterface { + + @Inject SequenceTargetingReagentExecutor sqtrExecutor; + @Inject SequenceTargetingReagentGeneAssociationService sequenceTargetingReagentGeneAssociationService; + + @Override + @PostConstruct + protected void init() { + setService(sequenceTargetingReagentGeneAssociationService); + } +} diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java index 29571072c..db9f22b12 100644 --- a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java @@ -3,7 +3,6 @@ import java.util.HashMap; import org.alliancegenome.curation_api.interfaces.base.BaseIdCrudInterface; -import org.alliancegenome.curation_api.model.entities.Allele; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentIngestFmsDTO; import org.alliancegenome.curation_api.response.APIResponse; diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java new file mode 100644 index 000000000..da0c3a7bf --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java @@ -0,0 +1,26 @@ +package org.alliancegenome.curation_api.interfaces.crud.associations; + +import org.alliancegenome.curation_api.interfaces.base.BaseIdCrudInterface; +import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.MediaType; + +@Path("/sqtrgeneassociation") +@Tag(name = "CRUD - SQTR Gene Associations") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface SequenceTargetingReagentGeneAssociationCrudInterface extends BaseIdCrudInterface { + + +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java index 7cce13c41..b8843e966 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java @@ -15,20 +15,28 @@ import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; +import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; import org.alliancegenome.curation_api.services.validation.associations.SequenceTargetingReagentGeneAssociationFmsDTOValidator; +import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; import jakarta.transaction.Transactional; @RequestScoped -public class SequenceTargetingReagentGeneAssociationService { +public class SequenceTargetingReagentGeneAssociationService extends BaseEntityCrudService{ @Inject SequenceTargetingReagentGeneAssociationDAO sequenceTargetingReagentGeneAssociationDAO; @Inject SequenceTargetingReagentGeneAssociationFmsDTOValidator sequenceTargetingReagentGeneAssociationFmsDTOValidator; + @Override + @PostConstruct + protected void init() { + setSQLDao(sequenceTargetingReagentGeneAssociationDAO); + } + @Transactional public List loadGeneAssociations(SequenceTargetingReagentFmsDTO dto, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { From 6079543388fd3f556ef3add278ff2fa1acc44467 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Thu, 11 Jul 2024 13:00:04 -0500 Subject: [PATCH 40/82] SCRUM-4187 update whitespace --- ...TargetingReagentGeneAssociationCrudController.java | 9 --------- ...eTargetingReagentGeneAssociationCrudInterface.java | 11 +---------- ...equenceTargetingReagentGeneAssociationService.java | 2 +- 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java b/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java index 4b4cdaee3..9823f666f 100644 --- a/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java +++ b/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java @@ -1,19 +1,10 @@ package org.alliancegenome.curation_api.controllers.crud.associations; -import java.util.List; - import org.alliancegenome.curation_api.controllers.base.BaseEntityCrudController; import org.alliancegenome.curation_api.dao.associations.SequenceTargetingReagentGeneAssociationDAO; -import org.alliancegenome.curation_api.dao.associations.alleleAssociations.AlleleGeneAssociationDAO; import org.alliancegenome.curation_api.interfaces.crud.associations.SequenceTargetingReagentGeneAssociationCrudInterface; -import org.alliancegenome.curation_api.interfaces.crud.associations.alleleAssociations.AlleleGeneAssociationCrudInterface; import org.alliancegenome.curation_api.jobs.executors.SequenceTargetingReagentExecutor; -import org.alliancegenome.curation_api.jobs.executors.associations.alleleAssociations.AlleleGeneAssociationExecutor; -import org.alliancegenome.curation_api.model.entities.associations.alleleAssociations.AlleleGeneAssociation; import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; -import org.alliancegenome.curation_api.model.ingest.dto.associations.alleleAssociations.AlleleGeneAssociationDTO; -import org.alliancegenome.curation_api.response.APIResponse; -import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.services.associations.SequenceTargetingReagentGeneAssociationService; import jakarta.annotation.PostConstruct; diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java index da0c3a7bf..918543e49 100644 --- a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java @@ -2,25 +2,16 @@ import org.alliancegenome.curation_api.interfaces.base.BaseIdCrudInterface; import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; -import org.alliancegenome.curation_api.response.ObjectResponse; -import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.tags.Tag; -import com.fasterxml.jackson.annotation.JsonView; import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; -import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; @Path("/sqtrgeneassociation") @Tag(name = "CRUD - SQTR Gene Associations") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public interface SequenceTargetingReagentGeneAssociationCrudInterface extends BaseIdCrudInterface { - - -} +public interface SequenceTargetingReagentGeneAssociationCrudInterface extends BaseIdCrudInterface { } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java index b8843e966..5e9e002dd 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java @@ -24,7 +24,7 @@ import jakarta.transaction.Transactional; @RequestScoped -public class SequenceTargetingReagentGeneAssociationService extends BaseEntityCrudService{ +public class SequenceTargetingReagentGeneAssociationService extends BaseEntityCrudService { @Inject SequenceTargetingReagentGeneAssociationDAO sequenceTargetingReagentGeneAssociationDAO; From 0270da3669a662c3a2086e40c93b10b8b279ff35 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Thu, 11 Jul 2024 22:30:19 -0500 Subject: [PATCH 41/82] Adding HTPexpressiondataset entities --- .../cliapp/src/service/DataLoadService.js | 1 + .../enums/BackendBulkLoadType.java | 3 +- ...ThroughputExpressionDatasetAnnotation.java | 60 ++++++++++ ...6.0.4__highthroughputexpressiondataset.sql | 103 ++++++++++++++++++ 4 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java create mode 100644 src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql diff --git a/src/main/cliapp/src/service/DataLoadService.js b/src/main/cliapp/src/service/DataLoadService.js index 5e5b729fc..c361e810e 100644 --- a/src/main/cliapp/src/service/DataLoadService.js +++ b/src/main/cliapp/src/service/DataLoadService.js @@ -81,6 +81,7 @@ export class DataLoadService extends BaseAuthService { const bulkLoadTypes = { BulkFMSLoad: [ 'GFF', + 'HTP EXPRESSION DATASET ANNOTATION', 'INTERACTION-GEN', 'INTERACTION-MOL', 'MOLECULE', diff --git a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java index 9172530be..119aef824 100644 --- a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java +++ b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java @@ -23,7 +23,8 @@ public enum BackendBulkLoadType { INTERACTION_GEN("tsv"), PARALOGY("json"), SEQUENCE_TARGETING_REAGENT("json"), - EXPRESSION("json"); + EXPRESSION("json"), + HTP_EXPRESSION_DATASET_ANNOTATION("json"); public String fileExtension; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java new file mode 100644 index 000000000..f16dbd1a8 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -0,0 +1,60 @@ +package org.alliancegenome.curation_api.model.entities; + +import java.util.List; + +import org.alliancegenome.curation_api.model.entities.base.SubmittedObject; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Indexed +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@Schema(name = "HighThroughputExpressionDatasetAnnotation", description = "POJO that represents the HighThroughputExpressionDatasetAnnotation") +public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject{ + + @JsonView({ View.FieldsOnly.class }) + private String name; + + @IndexedEmbedded(includePaths = {"curie", "primaryCrossReferenceCurie", "crossReferences.referencedCurie", "curie_keyword", "primaryCrossReferenceCurie_keyword", "crossReferences.referencedCurie_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToMany + @Fetch(FetchMode.JOIN) + @JoinTable(indexes = { + @Index(name = "htpdatasetannotation_reference_htpdataset_index", columnList = "highthroughputexpressiondatasetannotation_id"), + @Index(name = "htpdatasetannotation_reference_references_index", columnList = "references_id") + }) + @JsonView({ View.FieldsAndLists.class }) + private List references; + + @JsonView({ View.FieldsOnly.class }) + private String realtedNote; + + @JsonView({ View.FieldsOnly.class }) + private Integer numberOfChannels; + + @IndexedEmbedded(includePaths = {"name", "name_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToMany + @JsonView({ View.FieldsAndLists.class }) + @JoinTable(name = "htpexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "highthroughputexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) + List categoryTags; + +} diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql new file mode 100644 index 000000000..605d58caa --- /dev/null +++ b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql @@ -0,0 +1,103 @@ +-- To create bulk loads + +INSERT INTO bulkloadgroup (id, name) VALUES (nextval('bulkloadgroup_seq'), 'HTP Expression Dataset Annotation Bulk Loads'); + +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'ZFIN HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'MGI HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'RGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'SGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; + +INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) +SELECT id, '0 0 22 ? * SUN-THU', false FROM bulkload WHERE backendbulkloadtype = 'HTP_EXPRESSION_DATASET_ANNOTATION'; + +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB' FROM bulkload WHERE name = 'FB HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'MGI' FROM bulkload WHERE name = 'MGI HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'RGD' FROM bulkload WHERE name = 'RGD HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'SGD' FROM bulkload WHERE name = 'SGD HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB' FROM bulkload WHERE name = 'WB HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'ZFIN' FROM bulkload WHERE name = 'ZFIN HTP Expression Dataset Annotation Load'; + + +--Adding 3 extra vocabulary terms for HTPTags + +INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'epigenome', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; +INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional genomics and proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; +INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'karyotyping', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; + +-- Adding highthroughputexpressiondatasetannotation + +CREATE SEQUENCE highthroughputexpressiondatasetannotation_seq START WITH 1 INCREMENT BY 50 NO MINVALUE NO MAXVALUE CACHE 1; + +CREATE TABLE highthroughputexpressiondatasetannotation ( + id bigint NOT NULL, + datecreated timestamp(6) with time zone, + dateupdated timestamp(6) with time zone, + dbdatecreated timestamp(6) with time zone, + dbdateupdated timestamp(6) with time zone, + internal boolean DEFAULT false NOT NULL, + obsolete boolean DEFAULT false NOT NULL, + curie character varying(255), + modentityid character varying(255), + modinternalid character varying(255), + name character varying(255), + numberofchannels integer, + realtednote character varying(255), + createdby_id bigint, + updatedby_id bigint, + dataprovider_id bigint +); + +CREATE TABLE highthroughputexpressiondatasetannotation_categorytags ( + highthroughputexpressiondatasetannotation_id bigint NOT NULL, + categorytags_id bigint NOT NULL + ); + +CREATE TABLE highthroughputexpressiondatasetannotation_reference ( + highthroughputexpressiondatasetannotation_id bigint NOT NULL, + references_id bigint NOT NULL + ); + +ALTER TABLE highthroughputexpressiondatasetannotation ADD CONSTRAINT highthroughputexpressiondatasetannotation_pkey PRIMARY KEY (id); + +CREATE INDEX htpdatasetannotation_reference_htpdataset_index ON highthroughputexpressiondatasetannotation_reference USING btree (highthroughputexpressiondatasetannotation_id); + +CREATE INDEX htpdatasetannotation_reference_references_index ON highthroughputexpressiondatasetannotation_reference USING btree (references_id); + +CREATE INDEX htpdatasetannotation_categorytags_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (categorytags_id); + +CREATE INDEX htpdatasetannotation_htpdatasetid_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (highthroughputexpressiondatasetannotation_id); + +ALTER TABLE highthroughputexpressiondatasetannotation_categorytags + ADD CONSTRAINT highthroughputexpressiondatasetannotation_categorytags_highthroughputexpressiondatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); + +ALTER TABLE highthroughputexpressiondatasetannotation + ADD CONSTRAINT highthroughputexpressiondatasetannotation_dataprovider_id_fk FOREIGN KEY (dataprovider_id) REFERENCES dataprovider(id); + +ALTER TABLE highthroughputexpressiondatasetannotation_categorytags + ADD CONSTRAINT htpdatasetannotation_categorytags_categorytags_id_fk FOREIGN KEY (categorytags_id) REFERENCES vocabularyterm(id); + +ALTER TABLE highthroughputexpressiondatasetannotation_reference + ADD CONSTRAINT htpdatasetannotation_reference_htpdatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); + +ALTER TABLE highthroughputexpressiondatasetannotation_reference + ADD CONSTRAINT htpdatasetannotation_reference_references_id_fk FOREIGN KEY (references_id) REFERENCES reference(id); + +ALTER TABLE highthroughputexpressiondatasetannotation + ADD CONSTRAINT htpdatasetannotation_updatedby_id_fk FOREIGN KEY (updatedby_id) REFERENCES person(id); + +ALTER TABLE highthroughputexpressiondatasetannotation + ADD CONSTRAINT htpdatasetannotation_createdby_id_fk FOREIGN KEY (createdby_id) REFERENCES person(id); \ No newline at end of file From 5908c6c43a1bd93589bc4618c0466fe446b302e9 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Thu, 11 Jul 2024 22:39:46 -0500 Subject: [PATCH 42/82] Formatting --- ...ThroughputExpressionDatasetAnnotation.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java index f16dbd1a8..fd40d6e52 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -28,12 +28,12 @@ @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) @ToString(callSuper = true) @Schema(name = "HighThroughputExpressionDatasetAnnotation", description = "POJO that represents the HighThroughputExpressionDatasetAnnotation") -public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject{ +public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @JsonView({ View.FieldsOnly.class }) - private String name; + private String name; - @IndexedEmbedded(includePaths = {"curie", "primaryCrossReferenceCurie", "crossReferences.referencedCurie", "curie_keyword", "primaryCrossReferenceCurie_keyword", "crossReferences.referencedCurie_keyword"}) + @IndexedEmbedded(includePaths = {"curie", "primaryCrossReferenceCurie", "crossReferences.referencedCurie", "curie_keyword", "primaryCrossReferenceCurie_keyword", "crossReferences.referencedCurie_keyword"}) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @ManyToMany @Fetch(FetchMode.JOIN) @@ -44,17 +44,17 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject{ @JsonView({ View.FieldsAndLists.class }) private List references; - @JsonView({ View.FieldsOnly.class }) - private String realtedNote; + @JsonView({ View.FieldsOnly.class }) + private String realtedNote; - @JsonView({ View.FieldsOnly.class }) - private Integer numberOfChannels; + @JsonView({ View.FieldsOnly.class }) + private Integer numberOfChannels; - @IndexedEmbedded(includePaths = {"name", "name_keyword"}) + @IndexedEmbedded(includePaths = {"name", "name_keyword"}) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) - @ManyToMany - @JsonView({ View.FieldsAndLists.class }) + @ManyToMany + @JsonView({ View.FieldsAndLists.class }) @JoinTable(name = "htpexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "highthroughputexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) - List categoryTags; + List categoryTags; } From 4c4772b74d251f00bb877d4e519fbe0860135403 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Fri, 12 Jul 2024 10:24:18 +0100 Subject: [PATCH 43/82] More GFF association loading code --- .../constants/EntityFieldConstants.java | 38 +++- .../curation_api/constants/Gff3Constants.java | 4 +- .../jobs/executors/LoadFileExecutor.java | 3 +- .../model/entities/AssemblyComponent.java | 2 +- .../model/entities/LocationAssociation.java | 3 + ...ingSequenceGenomicLocationAssociation.java | 19 +- .../ExonGenomicLocationAssociation.java | 12 ++ .../TranscriptGenomicLocationAssociation.java | 17 ++ .../services/AssemblyComponentService.java | 81 +++++++++ .../curation_api/services/Gff3Service.java | 46 ++++- ...enceGenomicLocationAssociationService.java | 34 ++++ ...ExonGenomicLocationAssociationService.java | 34 ++++ ...riptGenomicLocationAssociationService.java | 34 ++++ .../helpers/gff3/Gff3AttributesHelper.java | 44 +++++ .../validation/dto/Gff3DtoValidator.java | 163 +++++++++++++----- .../v0.36.0.4__gff_association_tables.sql | 5 + .../curation_api/Gff3BulkUploadITCase.java | 9 +- .../fms/08_gff_data/GFF01_transcript.json | 4 +- .../bulk/fms/08_gff_data/GFF03_CDS.json | 1 + 19 files changed, 495 insertions(+), 58 deletions(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/services/AssemblyComponentService.java create mode 100644 src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3AttributesHelper.java diff --git a/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java b/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java index a79114e6f..ce370dae3 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/EntityFieldConstants.java @@ -6,19 +6,39 @@ private EntityFieldConstants() { // Hidden from view, as it is a utility class } + public static final String ASSEMBLY = "genomeAssembly.modEntityId"; public static final String TAXON = "taxon.curie"; - public static final String DATA_PROVIDER = "dataProvider.sourceOrganization.abbreviation"; - public static final String SECONDARY_DATA_PROVIDER = "secondaryDataProvider.sourceOrganization.abbreviation"; + public static final String SOURCE_ORGANIZATION = "sourceOrganization.abbreviation"; + public static final String DATA_PROVIDER = "dataProvider." + SOURCE_ORGANIZATION; + public static final String SECONDARY_DATA_PROVIDER = "secondaryDataProvider." + SOURCE_ORGANIZATION; + public static final String DA_SUBJECT = "diseaseAnnotationSubject"; - public static final String DA_SUBJECT_TAXON = DA_SUBJECT + "." + TAXON; + public static final String EA_SUBJECT = "expressionAnnotationSubject"; public static final String PA_SUBJECT = "phenotypeAnnotationSubject"; + public static final String ALLELE_ASSOCIATION_SUBJECT = "alleleAssociationSubject"; + public static final String CODING_SEQUENCE_ASSOCIATION_SUBJECT = "codingSequenceAssociationSubject"; + public static final String CONSTRUCT_ASSOCIATION_SUBJECT = "constructAssociationSubject"; + public static final String EXON_ASSOCIATION_SUBJECT = "exonAssociationSubject"; + public static final String TRANSCRIPT_ASSOCIATION_SUBJECT = "transcriptAssociationSubject"; + + public static final String DA_SUBJECT_TAXON = DA_SUBJECT + "." + TAXON; + public static final String EA_SUBJECT_TAXON = EA_SUBJECT + "." + TAXON; public static final String PA_SUBJECT_TAXON = PA_SUBJECT + "." + TAXON; - public static final String ALLELE_ASSOCIATION_SUBJECT_DATA_PROVIDER = "alleleAssociationSubject." + DATA_PROVIDER; - public static final String CODING_SEQUENCE_ASSOCIATION_SUBJECT_DATA_PROVIDER = "codingSequenceAssociationSubject." + DATA_PROVIDER; - public static final String CONSTRUCT_ASSOCIATION_SUBJECT_DATA_PROVIDER = "constructAssociationSubject." + DATA_PROVIDER; - public static final String EXON_ASSOCIATION_SUBJECT_DATA_PROVIDER = "exonAssociationSubject." + DATA_PROVIDER; - public static final String TRANSCRIPT_ASSOCIATION_SUBJECT_DATA_PROVIDER = "transcriptAssociationSubject." + DATA_PROVIDER; + + public static final String ALLELE_ASSOCIATION_SUBJECT_DATA_PROVIDER = ALLELE_ASSOCIATION_SUBJECT + "." + DATA_PROVIDER; + public static final String CODING_SEQUENCE_ASSOCIATION_SUBJECT_DATA_PROVIDER = CODING_SEQUENCE_ASSOCIATION_SUBJECT + "." + DATA_PROVIDER; + public static final String CONSTRUCT_ASSOCIATION_SUBJECT_DATA_PROVIDER = CONSTRUCT_ASSOCIATION_SUBJECT + "." + DATA_PROVIDER; + public static final String EXON_ASSOCIATION_SUBJECT_DATA_PROVIDER = EXON_ASSOCIATION_SUBJECT + "." + DATA_PROVIDER; + public static final String TRANSCRIPT_ASSOCIATION_SUBJECT_DATA_PROVIDER = TRANSCRIPT_ASSOCIATION_SUBJECT + "." + DATA_PROVIDER; + + public static final String GENOMIC_LOCATION_ASSOCIATION_OBJECT = "GenomicLocationAssociationObject"; + public static final String CODING_SEQUENCE_GENOMIC_LOCATION_ASSOCIATION_OBJECT = "codingSequence" + GENOMIC_LOCATION_ASSOCIATION_OBJECT + ".name"; + public static final String EXON_GENOMIC_LOCATION_ASSOCIATION_OBJECT = "exon" + GENOMIC_LOCATION_ASSOCIATION_OBJECT + ".name"; + public static final String TRANSCRIPT_GENOMIC_LOCATION_ASSOCIATION_OBJECT = "transcript" + GENOMIC_LOCATION_ASSOCIATION_OBJECT + ".name"; + public static final String CODING_SEQUENCE_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY = "codingSequence" + GENOMIC_LOCATION_ASSOCIATION_OBJECT + "." + ASSEMBLY; + public static final String EXON_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY = "exon" + GENOMIC_LOCATION_ASSOCIATION_OBJECT + "." + ASSEMBLY; + public static final String TRANSCRIPT_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY = "transcript" + GENOMIC_LOCATION_ASSOCIATION_OBJECT + "." + ASSEMBLY; + public static final String SUBJECT_GENE_DATA_PROVIDER = "subjectGene." + DATA_PROVIDER; public static final String SUBJECT_GENE_TAXON = "subjectGene." + TAXON; - public static final String EA_SUBJECT_TAXON = "expressionAnnotationSubject.taxon.curie"; } diff --git a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java index 55b9ed3c2..1c7a78891 100644 --- a/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java +++ b/src/main/java/org/alliancegenome/curation_api/constants/Gff3Constants.java @@ -7,10 +7,12 @@ private Gff3Constants() { // Hidden from view, as it is a utility class throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); } + public static final List TRANSCRIPT_TYPES = List.of( "mRNA", "ncRNA", "piRNA", "lincRNA", "miRNA", "pre_miRNA", "snoRNA", "lncRNA", "tRNA", "snRNA", "rRNA", "antisense_RNA", "C_gene_segment", "V_gene_segment", "pseudogene_attribute", "snoRNA_gene", "pseudogenic_transcript", "lnc_RNA" ); - + + public static final List STRANDS = List.of("+", "-"); } \ No newline at end of file diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/LoadFileExecutor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/LoadFileExecutor.java index 951e380b4..827693c81 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/LoadFileExecutor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/LoadFileExecutor.java @@ -259,7 +259,8 @@ protected boolean runLoad(BaseUpser List idsToRemove = ListUtils.subtract(annotationIdsBefore, distinctAfter); Log.debug("runLoad: Remove: " + dataProviderName + " " + idsToRemove.size()); - history.setTotalDeleteRecords((long) idsToRemove.size()); + long existingDeletes = history.getTotalDeleteRecords() == null ? 0 : history.getTotalDeleteRecords(); + history.setTotalDeleteRecords((long) idsToRemove.size() + existingDeletes); ProcessDisplayHelper ph = new ProcessDisplayHelper(10000); ph.startProcess("Deletion/deprecation of entities linked to unloaded " + dataProviderName, idsToRemove.size()); diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java b/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java index fa6ca8506..018cc8c9e 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java @@ -30,7 +30,7 @@ @Entity @Data @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) -@ToString(callSuper = true) +@ToString(exclude = {"transcriptGenomicLocationAssociations", "exonGenomicLocationAssociations", "codingSequenceGenomicLocationAssociations"}, callSuper = true) @Schema(name = "AssemblyComponent", description = "POJO that represents the AssemblyComponent") @AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) @Table( diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java index 7378fd39a..8749bfcd4 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java @@ -13,6 +13,7 @@ import com.fasterxml.jackson.annotation.JsonView; +import jakarta.persistence.Column; import jakarta.persistence.ManyToOne; import jakarta.persistence.MappedSuperclass; import lombok.Data; @@ -32,9 +33,11 @@ public abstract class LocationAssociation extends EvidenceAssociation { private VocabularyTerm relation; @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @Column(name="`start`") private Integer start; @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @Column(name="`end`") private Integer end; } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java index 15b75ce87..d431aad3a 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java @@ -9,11 +9,19 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Projectable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonView; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Index; import jakarta.persistence.ManyToOne; @@ -55,5 +63,14 @@ public class CodingSequenceGenomicLocationAssociation extends LocationAssociatio @JsonView({ View.FieldsOnly.class }) @JsonIgnoreProperties("codingSequenceGenomicLocationAssociations") @Fetch(FetchMode.JOIN) - private AssemblyComponent codingSequenceGenomicLocationAssociationObject; + private AssemblyComponent codingSequenceGenomicLocationAssociationObject; + + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + private Integer phase; + + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "phenotypeAnnotationObject_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @JsonView({ View.FieldsOnly.class }) + @Column(length = 1) + private String strand; } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java index 35a11b125..112da96c6 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java @@ -9,11 +9,17 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonView; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Index; import jakarta.persistence.ManyToOne; @@ -56,4 +62,10 @@ public class ExonGenomicLocationAssociation extends LocationAssociation { @JsonIgnoreProperties("exonGenomicLocationAssociations") @Fetch(FetchMode.JOIN) private AssemblyComponent exonGenomicLocationAssociationObject; + + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "phenotypeAnnotationObject_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @JsonView({ View.FieldsOnly.class }) + @Column(length = 1) + private String strand; } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java index 1f7488541..91f1e4a79 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java @@ -9,11 +9,19 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Projectable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonView; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Index; import jakarta.persistence.ManyToOne; @@ -56,4 +64,13 @@ public class TranscriptGenomicLocationAssociation extends LocationAssociation { @JsonIgnoreProperties("transcriptGenomicLocationAssociations") @Fetch(FetchMode.JOIN) private AssemblyComponent transcriptGenomicLocationAssociationObject; + + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + private Integer phase; + + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "phenotypeAnnotationObject_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @JsonView({ View.FieldsOnly.class }) + @Column(length = 1) + private String strand; } diff --git a/src/main/java/org/alliancegenome/curation_api/services/AssemblyComponentService.java b/src/main/java/org/alliancegenome/curation_api/services/AssemblyComponentService.java new file mode 100644 index 000000000..49aeca977 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/AssemblyComponentService.java @@ -0,0 +1,81 @@ +package org.alliancegenome.curation_api.services; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.alliancegenome.curation_api.constants.EntityFieldConstants; +import org.alliancegenome.curation_api.dao.AssemblyComponentDAO; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; +import org.alliancegenome.curation_api.model.entities.GenomeAssembly; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; +import org.alliancegenome.curation_api.services.helpers.UniqueIdGeneratorHelper; +import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; + +import io.quarkus.logging.Log; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; + +@RequestScoped +public class AssemblyComponentService extends BaseEntityCrudService { + + @Inject AssemblyComponentDAO assemblyComponentDAO; + @Inject NcbiTaxonTermService ncbiTaxonTermService; + @Inject DataProviderService dataProviderService; + + Date assemblyComponentRequest; + HashMap assemblyComponentCacheMap = new HashMap<>(); + + @Override + @PostConstruct + protected void init() { + setSQLDao(assemblyComponentDAO); + } + + @Transactional + public AssemblyComponent fetchOrCreate(String name, GenomeAssembly assembly, String taxonCurie, String dataProviderAbbreviation) { + AssemblyComponent assemblyComponent = null; + if (assemblyComponentRequest != null) { + UniqueIdGeneratorHelper uniqueIdGen = new UniqueIdGeneratorHelper(); + uniqueIdGen.add(name); + uniqueIdGen.add(assembly.getModEntityId()); + uniqueIdGen.add(taxonCurie); + uniqueIdGen.add(dataProviderAbbreviation); + String uniqueId = uniqueIdGen.getUniqueId(); + if (assemblyComponentCacheMap.containsKey(uniqueId)) { + assemblyComponent = assemblyComponentCacheMap.get(uniqueId); + } else { + Log.debug("AssemblyComponent not cached, caching name|assembly: (" + uniqueId + ")"); + assemblyComponent = findAssemblyComponentOrCreateDB(name, assembly, taxonCurie, dataProviderAbbreviation); + assemblyComponentCacheMap.put(uniqueId, assemblyComponent); + } + } else { + assemblyComponent = findAssemblyComponentOrCreateDB(name, assembly, taxonCurie, dataProviderAbbreviation); + assemblyComponentRequest = new Date(); + } + return assemblyComponent; + } + + private AssemblyComponent findAssemblyComponentOrCreateDB(String name, GenomeAssembly assembly, String taxonCurie, String dataProviderAbbreviation) { + Map params = new HashMap<>(); + params.put("name", name); + params.put(EntityFieldConstants.ASSEMBLY, assembly.getModEntityId()); + params.put(EntityFieldConstants.TAXON, taxonCurie); + params.put(EntityFieldConstants.DATA_PROVIDER, dataProviderAbbreviation); + SearchResponse assemblyComponentResponse = assemblyComponentDAO.findByParams(params); + if (assemblyComponentResponse != null && assemblyComponentResponse.getResults().size() > 0) { + return assemblyComponentResponse.getSingleResult(); + } + AssemblyComponent assemblyComponent = new AssemblyComponent(); + assemblyComponent.setName(name); + assemblyComponent.setGenomeAssembly(assembly); + assemblyComponent.setTaxon(ncbiTaxonTermService.getByCurie(taxonCurie).getEntity()); + assemblyComponent.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProviderAbbreviation)); + + return assemblyComponentDAO.persist(assemblyComponent); + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java index 07eaa030e..4e3afe373 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java +++ b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java @@ -7,7 +7,10 @@ import org.alliancegenome.curation_api.constants.EntityFieldConstants; import org.alliancegenome.curation_api.constants.Gff3Constants; import org.alliancegenome.curation_api.constants.ValidationConstants; +import org.alliancegenome.curation_api.dao.CodingSequenceDAO; +import org.alliancegenome.curation_api.dao.ExonDAO; import org.alliancegenome.curation_api.dao.GenomeAssemblyDAO; +import org.alliancegenome.curation_api.dao.TranscriptDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; import org.alliancegenome.curation_api.exceptions.ObjectValidationException; @@ -21,6 +24,11 @@ import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.services.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociationService; +import org.alliancegenome.curation_api.services.associations.exonAssociations.ExonGenomicLocationAssociationService; +import org.alliancegenome.curation_api.services.associations.transcriptAssociations.TranscriptGenomicLocationAssociationService; +import org.alliancegenome.curation_api.services.helpers.gff3.Gff3AttributesHelper; +import org.alliancegenome.curation_api.services.helpers.gff3.Gff3UniqueIdHelper; import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; import org.alliancegenome.curation_api.services.validation.dto.Gff3DtoValidator; import org.apache.commons.lang3.ObjectUtils; @@ -34,6 +42,12 @@ public class Gff3Service { @Inject GenomeAssemblyDAO genomeAssemblyDAO; + @Inject ExonDAO exonDAO; + @Inject CodingSequenceDAO cdsDAO; + @Inject TranscriptDAO transcriptDAO; + @Inject ExonGenomicLocationAssociationService exonLocationService; + @Inject CodingSequenceGenomicLocationAssociationService cdsLocationService; + @Inject TranscriptGenomicLocationAssociationService transcriptLocationService; @Inject DataProviderService dataProviderService; @Inject NcbiTaxonTermService ncbiTaxonTermService; @Inject Gff3DtoValidator gff3DtoValidator; @@ -92,28 +106,54 @@ public Map> loadEntity(BulkLoadFileHistory history, Gff3DTO g return idsAdded; } + @Transactional public Map> loadAssociations(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider, GenomeAssembly assembly) throws ObjectUpdateException { if (ObjectUtils.isEmpty(assembly)) { throw new ObjectValidationException(gffEntry, "Cannot load associations without assembly"); } + Map attributes = Gff3AttributesHelper.getAttributes(gffEntry, dataProvider); if (StringUtils.equals(gffEntry.getType(), "exon") || StringUtils.equals(gffEntry.getType(), "noncoding_exon")) { - ExonGenomicLocationAssociation exonLocation = gff3DtoValidator.validateExonLocation(gffEntry, assembly, dataProvider); + String uniqueId = Gff3UniqueIdHelper.getExonOrCodingSequenceUniqueId(gffEntry, attributes, dataProvider); + SearchResponse response = exonDAO.findByField("uniqueId", uniqueId); + if (response == null || response.getSingleResult() == null) { + throw new ObjectValidationException(gffEntry, "uniqueId - " + ValidationConstants.INVALID_MESSAGE + " (" + uniqueId + ")"); + } + Exon exon = response.getSingleResult(); + + ExonGenomicLocationAssociation exonLocation = gff3DtoValidator.validateExonLocation(gffEntry, exon, assembly, dataProvider); if (exonLocation != null) { idsAdded.get("ExonGenomicLocationAssociation").add(exonLocation.getId()); + exonLocationService.addAssociationToSubjectAndObject(exonLocation); } } else if (StringUtils.equals(gffEntry.getType(), "CDS")) { - CodingSequenceGenomicLocationAssociation cdsLocation = gff3DtoValidator.validateCdsLocation(gffEntry, assembly, dataProvider); + String uniqueId = Gff3UniqueIdHelper.getExonOrCodingSequenceUniqueId(gffEntry, attributes, dataProvider); + SearchResponse response = cdsDAO.findByField("uniqueId", uniqueId); + if (response == null || response.getSingleResult() == null) { + throw new ObjectValidationException(gffEntry, "uniqueId - " + ValidationConstants.INVALID_MESSAGE + " (" + uniqueId + ")"); + } + CodingSequence cds = response.getSingleResult(); + CodingSequenceGenomicLocationAssociation cdsLocation = gff3DtoValidator.validateCdsLocation(gffEntry, cds, assembly, dataProvider); if (cdsLocation != null) { idsAdded.get("CodingSequenceGenomicLocationAssociation").add(cdsLocation.getId()); + cdsLocationService.addAssociationToSubjectAndObject(cdsLocation); } } else if (Gff3Constants.TRANSCRIPT_TYPES.contains(gffEntry.getType())) { if (StringUtils.equals(gffEntry.getType(), "lnc_RNA")) { gffEntry.setType("lncRNA"); } - TranscriptGenomicLocationAssociation transcriptLocation = gff3DtoValidator.validateTranscriptLocation(gffEntry, assembly, dataProvider); + if (!attributes.containsKey("ID")) { + throw new ObjectValidationException(gffEntry, "attributes - ID - " + ValidationConstants.REQUIRED_MESSAGE); + } + SearchResponse response = transcriptDAO.findByField("modInternalId", attributes.get("ID")); + if (response == null || response.getSingleResult() == null) { + throw new ObjectValidationException(gffEntry, "attributes - ID - " + ValidationConstants.INVALID_MESSAGE + " (" + attributes.get("ID") + ")"); + } + Transcript transcript = response.getSingleResult(); + TranscriptGenomicLocationAssociation transcriptLocation = gff3DtoValidator.validateTranscriptLocation(gffEntry, transcript, assembly, dataProvider); if (transcriptLocation != null) { idsAdded.get("TranscriptGenomicLocationAssociation").add(transcriptLocation.getId()); + transcriptLocationService.addAssociationToSubjectAndObject(transcriptLocation); } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java index b611e5549..4eb4ac33d 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java @@ -1,16 +1,20 @@ package org.alliancegenome.curation_api.services.associations.codingSequenceAssociations; import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import org.alliancegenome.curation_api.constants.EntityFieldConstants; import org.alliancegenome.curation_api.dao.PersonDAO; import org.alliancegenome.curation_api.dao.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociationDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ApiErrorException; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; +import org.alliancegenome.curation_api.model.entities.CodingSequence; import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.response.SearchResponse; @@ -98,4 +102,34 @@ public ObjectResponse getLocationAssoc return response; } + + public void addAssociationToSubjectAndObject(CodingSequenceGenomicLocationAssociation association) { + CodingSequence cds = association.getCodingSequenceAssociationSubject(); + + List currentSubjectAssociations = cds.getCodingSequenceGenomicLocationAssociations(); + if (currentSubjectAssociations == null) { + currentSubjectAssociations = new ArrayList<>(); + } + + List currentSubjectAssociationIds = currentSubjectAssociations.stream() + .map(CodingSequenceGenomicLocationAssociation::getId).collect(Collectors.toList()); + + if (!currentSubjectAssociationIds.contains(association.getId())) { + currentSubjectAssociations.add(association); + } + + AssemblyComponent assemblyComponent = association.getCodingSequenceGenomicLocationAssociationObject(); + + List currentObjectAssociations = assemblyComponent.getCodingSequenceGenomicLocationAssociations(); + if (currentObjectAssociations == null) { + currentObjectAssociations = new ArrayList<>(); + } + + List currentObjectAssociationIds = currentObjectAssociations.stream() + .map(CodingSequenceGenomicLocationAssociation::getId).collect(Collectors.toList()); + + if (!currentObjectAssociationIds.contains(association.getId())) { + currentObjectAssociations.add(association); + } + } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java index c2c767616..c41861926 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java @@ -1,16 +1,20 @@ package org.alliancegenome.curation_api.services.associations.exonAssociations; import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import org.alliancegenome.curation_api.constants.EntityFieldConstants; import org.alliancegenome.curation_api.dao.PersonDAO; import org.alliancegenome.curation_api.dao.associations.exonAssociations.ExonGenomicLocationAssociationDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ApiErrorException; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; +import org.alliancegenome.curation_api.model.entities.Exon; import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.response.SearchResponse; @@ -98,4 +102,34 @@ public ObjectResponse getLocationAssociation(Lon return response; } + + public void addAssociationToSubjectAndObject(ExonGenomicLocationAssociation association) { + Exon exon = association.getExonAssociationSubject(); + + List currentSubjectAssociations = exon.getExonGenomicLocationAssociations(); + if (currentSubjectAssociations == null) { + currentSubjectAssociations = new ArrayList<>(); + } + + List currentSubjectAssociationIds = currentSubjectAssociations.stream() + .map(ExonGenomicLocationAssociation::getId).collect(Collectors.toList()); + + if (!currentSubjectAssociationIds.contains(association.getId())) { + currentSubjectAssociations.add(association); + } + + AssemblyComponent assemblyComponent = association.getExonGenomicLocationAssociationObject(); + + List currentObjectAssociations = assemblyComponent.getExonGenomicLocationAssociations(); + if (currentObjectAssociations == null) { + currentObjectAssociations = new ArrayList<>(); + } + + List currentObjectAssociationIds = currentObjectAssociations.stream() + .map(ExonGenomicLocationAssociation::getId).collect(Collectors.toList()); + + if (!currentObjectAssociationIds.contains(association.getId())) { + currentObjectAssociations.add(association); + } + } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java index 893a425c1..d4f06e2fe 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java @@ -1,16 +1,20 @@ package org.alliancegenome.curation_api.services.associations.transcriptAssociations; import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import org.alliancegenome.curation_api.constants.EntityFieldConstants; import org.alliancegenome.curation_api.dao.PersonDAO; import org.alliancegenome.curation_api.dao.associations.transcriptAssociations.TranscriptGenomicLocationAssociationDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ApiErrorException; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; +import org.alliancegenome.curation_api.model.entities.Transcript; import org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations.TranscriptGenomicLocationAssociation; import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.response.SearchResponse; @@ -98,4 +102,34 @@ public ObjectResponse getLocationAssociati return response; } + + public void addAssociationToSubjectAndObject(TranscriptGenomicLocationAssociation association) { + Transcript transcript = association.getTranscriptAssociationSubject(); + + List currentSubjectAssociations = transcript.getTranscriptGenomicLocationAssociations(); + if (currentSubjectAssociations == null) { + currentSubjectAssociations = new ArrayList<>(); + } + + List currentSubjectAssociationIds = currentSubjectAssociations.stream() + .map(TranscriptGenomicLocationAssociation::getId).collect(Collectors.toList()); + + if (!currentSubjectAssociationIds.contains(association.getId())) { + currentSubjectAssociations.add(association); + } + + AssemblyComponent assemblyComponent = association.getTranscriptGenomicLocationAssociationObject(); + + List currentObjectAssociations = assemblyComponent.getTranscriptGenomicLocationAssociations(); + if (currentObjectAssociations == null) { + currentObjectAssociations = new ArrayList<>(); + } + + List currentObjectAssociationIds = currentObjectAssociations.stream() + .map(TranscriptGenomicLocationAssociation::getId).collect(Collectors.toList()); + + if (!currentObjectAssociationIds.contains(association.getId())) { + currentObjectAssociations.add(association); + } + } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3AttributesHelper.java b/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3AttributesHelper.java new file mode 100644 index 000000000..32e430424 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3AttributesHelper.java @@ -0,0 +1,44 @@ +package org.alliancegenome.curation_api.services.helpers.gff3; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; +import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import jakarta.enterprise.context.RequestScoped; + +@RequestScoped +public class Gff3AttributesHelper { + + public static Map getAttributes(Gff3DTO dto, BackendBulkDataProvider dataProvider) { + Map attributes = new HashMap(); + if (CollectionUtils.isNotEmpty(dto.getAttributes())) { + for (String keyValue : dto.getAttributes()) { + String[] parts = keyValue.split("="); + if (parts.length == 2) { + attributes.put(parts[0], parts[1]); + } + } + } + + if (StringUtils.equals(dataProvider.sourceOrganization, "WB")) { + for (String key : List.of("ID", "Parent")) { + if (attributes.containsKey(key)) { + String id = attributes.get(key); + String[] idParts = id.split(":"); + if (idParts.length > 1) { + id = idParts[1]; + } + attributes.put(key, id); + } + } + } + + return attributes; + } + +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java index 3d0e51665..e7f4126ae 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -1,20 +1,26 @@ package org.alliancegenome.curation_api.services.validation.dto; import java.util.HashMap; -import java.util.List; import java.util.Map; +import org.alliancegenome.curation_api.constants.EntityFieldConstants; +import org.alliancegenome.curation_api.constants.Gff3Constants; import org.alliancegenome.curation_api.constants.ValidationConstants; import org.alliancegenome.curation_api.dao.CodingSequenceDAO; import org.alliancegenome.curation_api.dao.ExonDAO; import org.alliancegenome.curation_api.dao.TranscriptDAO; +import org.alliancegenome.curation_api.dao.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociationDAO; +import org.alliancegenome.curation_api.dao.associations.exonAssociations.ExonGenomicLocationAssociationDAO; +import org.alliancegenome.curation_api.dao.associations.transcriptAssociations.TranscriptGenomicLocationAssociationDAO; import org.alliancegenome.curation_api.dao.ontology.SoTermDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ObjectValidationException; +import org.alliancegenome.curation_api.model.entities.AssemblyComponent; import org.alliancegenome.curation_api.model.entities.CodingSequence; import org.alliancegenome.curation_api.model.entities.Exon; import org.alliancegenome.curation_api.model.entities.GenomeAssembly; import org.alliancegenome.curation_api.model.entities.GenomicEntity; +import org.alliancegenome.curation_api.model.entities.LocationAssociation; import org.alliancegenome.curation_api.model.entities.Transcript; import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; @@ -23,10 +29,12 @@ import org.alliancegenome.curation_api.model.ingest.dto.fms.Gff3DTO; import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.services.AssemblyComponentService; import org.alliancegenome.curation_api.services.DataProviderService; +import org.alliancegenome.curation_api.services.Gff3Service; +import org.alliancegenome.curation_api.services.helpers.gff3.Gff3AttributesHelper; import org.alliancegenome.curation_api.services.helpers.gff3.Gff3UniqueIdHelper; import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import jakarta.enterprise.context.RequestScoped; @@ -39,16 +47,21 @@ public class Gff3DtoValidator { @Inject ExonDAO exonDAO; @Inject TranscriptDAO transcriptDAO; @Inject CodingSequenceDAO codingSequenceDAO; + @Inject ExonGenomicLocationAssociationDAO exonLocationDAO; + @Inject TranscriptGenomicLocationAssociationDAO transcriptLocationDAO; + @Inject CodingSequenceGenomicLocationAssociationDAO cdsLocationDAO; + @Inject AssemblyComponentService assemblyComponentService; @Inject DataProviderService dataProviderService; @Inject NcbiTaxonTermService ncbiTaxonTermService; @Inject SoTermDAO soTermDAO; + @Inject Gff3Service gff3Service; @Transactional public Exon validateExonEntry(Gff3DTO dto, BackendBulkDataProvider dataProvider) throws ObjectValidationException { Exon exon = null; - Map attributes = getAttributes(dto, dataProvider); + Map attributes = Gff3AttributesHelper.getAttributes(dto, dataProvider); String uniqueId = Gff3UniqueIdHelper.getExonOrCodingSequenceUniqueId(dto, attributes, dataProvider); SearchResponse searchResponse = exonDAO.findByField("uniqueId", uniqueId); if (searchResponse != null && searchResponse.getSingleResult() != null) { @@ -76,7 +89,7 @@ public CodingSequence validateCdsEntry(Gff3DTO dto, BackendBulkDataProvider data CodingSequence cds = null; - Map attributes = getAttributes(dto, dataProvider); + Map attributes = Gff3AttributesHelper.getAttributes(dto, dataProvider); String uniqueId = Gff3UniqueIdHelper.getExonOrCodingSequenceUniqueId(dto, attributes, dataProvider); SearchResponse searchResponse = codingSequenceDAO.findByField("uniqueId", uniqueId); if (searchResponse != null && searchResponse.getSingleResult() != null) { @@ -104,7 +117,7 @@ public Transcript validateTranscriptEntry(Gff3DTO dto, BackendBulkDataProvider d Transcript transcript = null; - Map attributes = getAttributes(dto, dataProvider); + Map attributes = Gff3AttributesHelper.getAttributes(dto, dataProvider); if (attributes.containsKey("ID")) { SearchResponse searchResponse = transcriptDAO.findByField("modInternalId", attributes.get("ID")); if (searchResponse != null && searchResponse.getSingleResult() != null) { @@ -146,50 +159,120 @@ private ObjectResponse validateGffEntity(E entity, return geResponse; } - - private Map getAttributes(Gff3DTO dto, BackendBulkDataProvider dataProvider) { - Map attributes = new HashMap(); - if (CollectionUtils.isNotEmpty(dto.getAttributes())) { - for (String keyValue : dto.getAttributes()) { - String[] parts = keyValue.split("="); - if (parts.length == 2) { - attributes.put(parts[0], parts[1]); - } - } - } - if (StringUtils.equals(dataProvider.sourceOrganization, "WB")) { - for (String key : List.of("ID", "Parent")) { - if (attributes.containsKey(key)) { - String id = attributes.get(key); - String[] idParts = id.split(":"); - if (idParts.length > 1) { - id = idParts[1]; - } - attributes.put(key, id); - } + @Transactional + public CodingSequenceGenomicLocationAssociation validateCdsLocation(Gff3DTO gffEntry, CodingSequence cds, GenomeAssembly assembly, BackendBulkDataProvider dataProvider) throws ObjectValidationException { + AssemblyComponent assemblyComponent = null; + CodingSequenceGenomicLocationAssociation locationAssociation = new CodingSequenceGenomicLocationAssociation(); + if (StringUtils.isNotBlank(gffEntry.getSeqId())) { + assemblyComponent = assemblyComponentService.fetchOrCreate(gffEntry.getSeqId(), assembly, dataProvider.canonicalTaxonCurie, dataProvider.sourceOrganization); + Map params = new HashMap<>(); + params.put(EntityFieldConstants.CODING_SEQUENCE_ASSOCIATION_SUBJECT + ".id", cds.getId()); + params.put(EntityFieldConstants.CODING_SEQUENCE_GENOMIC_LOCATION_ASSOCIATION_OBJECT, assemblyComponent.getName()); + params.put(EntityFieldConstants.CODING_SEQUENCE_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY, assembly.getModEntityId()); + SearchResponse locationSearchResponse = cdsLocationDAO.findByParams(params); + if (locationSearchResponse != null && locationSearchResponse.getSingleResult() != null) { + locationAssociation = locationSearchResponse.getSingleResult(); } + locationAssociation.setCodingSequenceGenomicLocationAssociationObject(assemblyComponent); } + locationAssociation.setCodingSequenceAssociationSubject(cds); + locationAssociation.setStrand(gffEntry.getStrand()); + locationAssociation.setPhase(gffEntry.getPhase()); - return attributes; + ObjectResponse locationResponse = validateLocationAssociation(locationAssociation, gffEntry, assemblyComponent); + if (locationResponse.hasErrors()) { + throw new ObjectValidationException(gffEntry, locationResponse.errorMessagesString()); + } + + return cdsLocationDAO.persist(locationResponse.getEntity()); } - public CodingSequenceGenomicLocationAssociation validateCdsSequenceLocation(Gff3DTO gffEntry, GenomeAssembly assembly, - BackendBulkDataProvider dataProvider) { - // TODO Auto-generated method stub - return null; + @Transactional + public ExonGenomicLocationAssociation validateExonLocation(Gff3DTO gffEntry, Exon exon, GenomeAssembly assembly, BackendBulkDataProvider dataProvider) throws ObjectValidationException { + AssemblyComponent assemblyComponent = null; + ExonGenomicLocationAssociation locationAssociation = new ExonGenomicLocationAssociation(); + if (StringUtils.isNotBlank(gffEntry.getSeqId())) { + assemblyComponent = assemblyComponentService.fetchOrCreate(gffEntry.getSeqId(), assembly, dataProvider.canonicalTaxonCurie, dataProvider.sourceOrganization); + Map params = new HashMap<>(); + params.put(EntityFieldConstants.EXON_ASSOCIATION_SUBJECT + ".id", exon.getId()); + params.put(EntityFieldConstants.EXON_GENOMIC_LOCATION_ASSOCIATION_OBJECT, assemblyComponent.getName()); + params.put(EntityFieldConstants.EXON_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY, assembly.getModEntityId()); + SearchResponse locationSearchResponse = exonLocationDAO.findByParams(params); + if (locationSearchResponse != null && locationSearchResponse.getSingleResult() != null) { + locationAssociation = locationSearchResponse.getSingleResult(); + } + locationAssociation.setExonGenomicLocationAssociationObject(assemblyComponent); + } + locationAssociation.setExonAssociationSubject(exon); + locationAssociation.setStrand(gffEntry.getStrand()); + + ObjectResponse locationResponse = validateLocationAssociation(locationAssociation, gffEntry, assemblyComponent); + if (locationResponse.hasErrors()) { + throw new ObjectValidationException(gffEntry, locationResponse.errorMessagesString()); + } + + return exonLocationDAO.persist(locationResponse.getEntity()); } - public ExonGenomicLocationAssociation validateExonLocation(Gff3DTO gffEntry, GenomeAssembly assembly, - BackendBulkDataProvider dataProvider) { - // TODO Auto-generated method stub - return null; + @Transactional + public TranscriptGenomicLocationAssociation validateTranscriptLocation(Gff3DTO gffEntry, Transcript transcript, GenomeAssembly assembly, BackendBulkDataProvider dataProvider) throws ObjectValidationException { + AssemblyComponent assemblyComponent = null; + TranscriptGenomicLocationAssociation locationAssociation = new TranscriptGenomicLocationAssociation(); + if (StringUtils.isNotBlank(gffEntry.getSeqId())) { + assemblyComponent = assemblyComponentService.fetchOrCreate(gffEntry.getSeqId(), assembly, dataProvider.canonicalTaxonCurie, dataProvider.sourceOrganization); + Map params = new HashMap<>(); + params.put(EntityFieldConstants.TRANSCRIPT_ASSOCIATION_SUBJECT + ".id", transcript.getId()); + params.put(EntityFieldConstants.TRANSCRIPT_GENOMIC_LOCATION_ASSOCIATION_OBJECT, assemblyComponent.getName()); + params.put(EntityFieldConstants.TRANSCRIPT_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY, assembly.getModEntityId()); + SearchResponse locationSearchResponse = transcriptLocationDAO.findByParams(params); + if (locationSearchResponse != null && locationSearchResponse.getSingleResult() != null) { + locationAssociation = locationSearchResponse.getSingleResult(); + } + locationAssociation.setTranscriptGenomicLocationAssociationObject(assemblyComponent); + } + locationAssociation.setTranscriptAssociationSubject(transcript); + locationAssociation.setStrand(gffEntry.getStrand()); + locationAssociation.setPhase(gffEntry.getPhase()); + + ObjectResponse locationResponse = validateLocationAssociation(locationAssociation, gffEntry, assemblyComponent); + if (locationResponse.hasErrors()) { + throw new ObjectValidationException(gffEntry, locationResponse.errorMessagesString()); + } + + return transcriptLocationDAO.persist(locationResponse.getEntity()); } - - public TranscriptGenomicLocationAssociation validateTranscriptLocation(Gff3DTO gffEntry, GenomeAssembly assembly, - BackendBulkDataProvider dataProvider) { - // TODO Auto-generated method stub - return null; + + private ObjectResponse validateLocationAssociation(E association, Gff3DTO dto, AssemblyComponent assemblyComponent) { + ObjectResponse associationResponse = new ObjectResponse(); + + if (assemblyComponent == null) { + associationResponse.addErrorMessage("SeqId", ValidationConstants.REQUIRED_MESSAGE); + } + + if (dto.getStart() == null) { + associationResponse.addErrorMessage("Start", ValidationConstants.REQUIRED_MESSAGE); + } + association.setStart(dto.getStart()); + + if (dto.getEnd() == null) { + associationResponse.addErrorMessage("End", ValidationConstants.REQUIRED_MESSAGE); + } + association.setEnd(dto.getEnd()); + + if (StringUtils.isBlank(dto.getStrand())) { + associationResponse.addErrorMessage("Strand", ValidationConstants.REQUIRED_MESSAGE); + } else if (!Gff3Constants.STRANDS.contains(dto.getStrand())) { + associationResponse.addErrorMessage("Strand", ValidationConstants.INVALID_MESSAGE + " (" + dto.getStrand() + ")"); + } + + if (dto.getPhase() != null && (dto.getPhase() > 2 || dto.getPhase() < 0)) { + associationResponse.addErrorMessage("Phase", ValidationConstants.INVALID_MESSAGE + " (" + dto.getPhase() + ")"); + } + + associationResponse.setEntity(association); + + return associationResponse; } } diff --git a/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql b/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql index 198b89d94..27c13e338 100644 --- a/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql +++ b/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql @@ -53,6 +53,8 @@ CREATE TABLE codingsequencegenomiclocationassociation ( id bigint CONSTRAINT codingsequencegenomiclocationassociation_pkey PRIMARY KEY, "start" integer, "end" integer, + phase integer, + strand varchar(1), relation_id bigint, codingsequenceassociationsubject_id bigint, codingsequencegenomiclocationassociationobject_id bigint @@ -78,6 +80,7 @@ CREATE TABLE exongenomiclocationassociation ( id bigint CONSTRAINT exongenomiclocationassociation_pkey PRIMARY KEY, "start" integer, "end" integer, + strand varchar(1), relation_id bigint, exonassociationsubject_id bigint, exongenomiclocationassociationobject_id bigint @@ -103,6 +106,8 @@ CREATE TABLE transcriptgenomiclocationassociation ( id bigint CONSTRAINT transcriptgenomiclocationassociation_pkey PRIMARY KEY, "start" integer, "end" integer, + phase integer, + strand varchar(1), relation_id bigint, transcriptassociationsubject_id bigint, transcriptgenomiclocationassociationobject_id bigint diff --git a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java index ec9e06414..5b2e3e896 100644 --- a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java @@ -1,6 +1,7 @@ package org.alliancegenome.curation_api; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.hasSize; import org.alliancegenome.curation_api.base.BaseITCase; import org.alliancegenome.curation_api.resources.TestContainerResource; @@ -66,7 +67,13 @@ public void gff3DataBulkUploadTranscriptEntity() throws Exception { body("entity.modInternalId", is(transcriptId)). body("entity.taxon.curie", is("NCBITaxon:6239")). body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")). - body("entity.transcriptType.curie", is("SO:0000234")); + body("entity.transcriptType.curie", is("SO:0000234")). + body("entity.transcriptGenomicLocationAssociations", hasSize(1)). + body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.name", is("I")). + body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.taxonCurie", is("NCBITaxon:6239")). + body("entity.transcriptGenomicLocationAssociations[0].start", is(1)). + body("entity.transcriptGenomicLocationAssociations[0].end", is(100)). + body("entity.transcriptGenomicLocationAssociations[0].strand", is("+")); } diff --git a/src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json b/src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json index bd1d4ecfc..ef30adafe 100644 --- a/src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json +++ b/src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json @@ -6,9 +6,11 @@ "start": 1, "end": 1000, "strand": "+", + "phase": 0, "attributes": [ "ID=Transcript:Y74C9A.2a.1", - "Parent=Gene:WBGene00022276" + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" ] } ] diff --git a/src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json b/src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json index 75fbd719f..bacb150fa 100644 --- a/src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json +++ b/src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json @@ -6,6 +6,7 @@ "start": 10, "end": 100, "strand": "+", + "phase": 1, "attributes": [ "ID=CDS:Y74C9A.2a", "Parent=Transcript:Y74C9A.2a.1" From c8f0463a6d9f140e23a04db27c7d1e55f1744823 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Fri, 12 Jul 2024 11:50:57 -0500 Subject: [PATCH 44/82] Note class used instead of string for related note --- .../cliapp/src/service/DataLoadService.js | 2 +- ...ThroughputExpressionDatasetAnnotation.java | 19 +++++++++++++++++-- ...6.0.4__highthroughputexpressiondataset.sql | 7 +++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/cliapp/src/service/DataLoadService.js b/src/main/cliapp/src/service/DataLoadService.js index c361e810e..8eaf6fb4a 100644 --- a/src/main/cliapp/src/service/DataLoadService.js +++ b/src/main/cliapp/src/service/DataLoadService.js @@ -81,7 +81,7 @@ export class DataLoadService extends BaseAuthService { const bulkLoadTypes = { BulkFMSLoad: [ 'GFF', - 'HTP EXPRESSION DATASET ANNOTATION', + 'HTP_EXPRESSION_DATASET_ANNOTATION', 'INTERACTION-GEN', 'INTERACTION-MOL', 'MOLECULE', diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java index fd40d6e52..7af5d1721 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -7,17 +7,26 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Projectable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonView; +import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; import jakarta.persistence.Index; import jakarta.persistence.JoinTable; import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToOne; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -31,6 +40,8 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @JsonView({ View.FieldsOnly.class }) + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") private String name; @IndexedEmbedded(includePaths = {"curie", "primaryCrossReferenceCurie", "crossReferences.referencedCurie", "curie_keyword", "primaryCrossReferenceCurie_keyword", "crossReferences.referencedCurie_keyword"}) @@ -44,17 +55,21 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @JsonView({ View.FieldsAndLists.class }) private List references; + @IndexedEmbedded(includePaths = { "freeText", "noteType.name", "references.curie", "references.primaryCrossReferenceCurie", "freeText_keyword", "noteType.name_keyword", "references.curie_keyword", "references.primaryCrossReferenceCurie_keyword" }) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JsonView({ View.FieldsOnly.class }) - private String realtedNote; + private Note relatedNote; @JsonView({ View.FieldsOnly.class }) + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) private Integer numberOfChannels; @IndexedEmbedded(includePaths = {"name", "name_keyword"}) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @ManyToMany @JsonView({ View.FieldsAndLists.class }) - @JoinTable(name = "htpexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "highthroughputexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) + @JoinTable(name = "highthroughputexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "highthroughputexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) List categoryTags; } diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql index 605d58caa..62108110c 100644 --- a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql +++ b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql @@ -16,7 +16,7 @@ INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) -SELECT id, '0 0 22 ? * SUN-THU', false FROM bulkload WHERE backendbulkloadtype = 'HTP_EXPRESSION_DATASET_ANNOTATION'; +SELECT id, '0 0 22 ? * SUN-THU', true FROM bulkload WHERE backendbulkloadtype = 'HTP_EXPRESSION_DATASET_ANNOTATION'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB' FROM bulkload WHERE name = 'FB HTP Expression Dataset Annotation Load'; @@ -55,7 +55,7 @@ CREATE TABLE highthroughputexpressiondatasetannotation ( modinternalid character varying(255), name character varying(255), numberofchannels integer, - realtednote character varying(255), + relatednote_id bigint, createdby_id bigint, updatedby_id bigint, dataprovider_id bigint @@ -81,6 +81,9 @@ CREATE INDEX htpdatasetannotation_categorytags_index ON highthroughputexpression CREATE INDEX htpdatasetannotation_htpdatasetid_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (highthroughputexpressiondatasetannotation_id); +ALTER TABLE highthroughputexpressiondatasetannotation + ADD CONSTRAINT highthroughputexpressiondatasetannotation_relatednote_id_fk FOREIGN KEY (relatednote_id) REFERENCES note (id); + ALTER TABLE highthroughputexpressiondatasetannotation_categorytags ADD CONSTRAINT highthroughputexpressiondatasetannotation_categorytags_highthroughputexpressiondatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); From c53bc8b107af3668cf6dfd12b8777918b974f252 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Fri, 12 Jul 2024 11:53:20 -0500 Subject: [PATCH 45/82] formatting --- .../entities/HighThroughputExpressionDatasetAnnotation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java index 7af5d1721..9e3431fb3 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -62,7 +62,7 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { private Note relatedNote; @JsonView({ View.FieldsOnly.class }) - @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) private Integer numberOfChannels; @IndexedEmbedded(includePaths = {"name", "name_keyword"}) From ca69d9df39489cf7038d1debe7fc0983ba26a9a9 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Sun, 14 Jul 2024 08:26:19 +0100 Subject: [PATCH 46/82] Fix lazy initialization error --- ...BaseReadIdentifierControllerInterface.java | 2 +- .../jobs/executors/Gff3Executor.java | 17 +++--- .../model/entities/GenomeAssembly.java | 2 +- .../model/entities/LocationAssociation.java | 2 + ...ingSequenceGenomicLocationAssociation.java | 7 ++- .../ConstructGenomicEntityAssociation.java | 9 ++- .../ExonGenomicLocationAssociation.java | 6 +- .../TranscriptGenomicLocationAssociation.java | 7 ++- .../model/entities/ontology/OntologyTerm.java | 2 + .../services/AssemblyComponentService.java | 19 +++--- .../services/GenomeAssemblyService.java | 23 +++++++ .../curation_api/services/Gff3Service.java | 32 +++++----- .../ontology/NcbiTaxonTermService.java | 4 +- .../ExperimentalConditionValidator.java | 2 +- .../validation/dto/Gff3DtoValidator.java | 19 +++--- .../curation_api/Gff3BulkUploadITCase.java | 61 +++++++++++++++++-- .../fms/08_gff_data/ER_01_empty_seq_id.json | 16 +++++ .../fms/08_gff_data/ER_02_empty_strand.json | 16 +++++ ...transcript.json => GFF_01_transcript.json} | 0 .../{GFF02_exon.json => GFF_02_exon.json} | 0 .../{GFF03_CDS.json => GFF_03_CDS.json} | 0 .../fms/08_gff_data/IV_01_invalid_strand.json | 16 +++++ .../fms/08_gff_data/IV_02_invalid_phase.json | 16 +++++ .../bulk/fms/08_gff_data/MR_01_no_seq_id.json | 15 +++++ .../bulk/fms/08_gff_data/MR_02_no_start.json | 15 +++++ .../bulk/fms/08_gff_data/MR_03_no_end.json | 15 +++++ .../bulk/fms/08_gff_data/MR_04_no_strand.json | 15 +++++ .../08_gff_data/UD_01_update_transcript.json | 16 +++++ 28 files changed, 293 insertions(+), 61 deletions(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/services/GenomeAssemblyService.java create mode 100644 src/test/resources/bulk/fms/08_gff_data/ER_01_empty_seq_id.json create mode 100644 src/test/resources/bulk/fms/08_gff_data/ER_02_empty_strand.json rename src/test/resources/bulk/fms/08_gff_data/{GFF01_transcript.json => GFF_01_transcript.json} (100%) rename src/test/resources/bulk/fms/08_gff_data/{GFF02_exon.json => GFF_02_exon.json} (100%) rename src/test/resources/bulk/fms/08_gff_data/{GFF03_CDS.json => GFF_03_CDS.json} (100%) create mode 100644 src/test/resources/bulk/fms/08_gff_data/IV_01_invalid_strand.json create mode 100644 src/test/resources/bulk/fms/08_gff_data/IV_02_invalid_phase.json create mode 100644 src/test/resources/bulk/fms/08_gff_data/MR_01_no_seq_id.json create mode 100644 src/test/resources/bulk/fms/08_gff_data/MR_02_no_start.json create mode 100644 src/test/resources/bulk/fms/08_gff_data/MR_03_no_end.json create mode 100644 src/test/resources/bulk/fms/08_gff_data/MR_04_no_strand.json create mode 100644 src/test/resources/bulk/fms/08_gff_data/UD_01_update_transcript.json diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/base/crud/BaseReadIdentifierControllerInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/base/crud/BaseReadIdentifierControllerInterface.java index 5bea803ed..ebac335b7 100644 --- a/src/main/java/org/alliancegenome/curation_api/interfaces/base/crud/BaseReadIdentifierControllerInterface.java +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/base/crud/BaseReadIdentifierControllerInterface.java @@ -24,7 +24,7 @@ public interface BaseReadIdentifierControllerInterface @GET @Path("/{identifierString}") - @JsonView(View.FieldsOnly.class) + @JsonView(View.FieldsAndLists.class) @APIResponses( @APIResponse( description = "Get the Entity by Identifier String", diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java index abf01caf2..aa7fa7938 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java @@ -11,7 +11,6 @@ import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; import org.alliancegenome.curation_api.exceptions.ObjectUpdateException.ObjectUpdateExceptionData; import org.alliancegenome.curation_api.jobs.util.CsvSchemaBuilder; -import org.alliancegenome.curation_api.model.entities.GenomeAssembly; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkFMSLoad; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFile; import org.alliancegenome.curation_api.model.entities.bulkloads.BulkLoadFileHistory; @@ -115,15 +114,15 @@ private Map> runLoad(BulkLoadFileHistory history, List> runLoad(BulkLoadFileHistory history, List gffHeaderData, List gffData, - Map> idsAdded, BackendBulkDataProvider dataProvider, String assemblyName) { + Map> idsAdded, BackendBulkDataProvider dataProvider, String assemblyId) { ProcessDisplayHelper ph = new ProcessDisplayHelper(); ph.addDisplayHandler(loadProcessDisplayService); ph.startProcess("GFF update for " + dataProvider.name(), (gffData.size() * 2) + 1); - GenomeAssembly assembly = loadGenomeAssembly(assemblyName, history, gffHeaderData, dataProvider, ph); + loadGenomeAssembly(assemblyId, history, gffHeaderData, dataProvider, ph); idsAdded = loadEntities(history, gffData, idsAdded, dataProvider, ph); - idsAdded = loadAssociations(history, gffData, idsAdded, dataProvider, assembly, ph); + idsAdded = loadAssociations(history, gffData, idsAdded, dataProvider, assemblyId, ph); return idsAdded; } @@ -144,10 +143,9 @@ public APIResponse runLoadApi(String dataProviderName, String assemblyName, List return new LoadHistoryResponce(history); } - private GenomeAssembly loadGenomeAssembly(String assemblyName, BulkLoadFileHistory history, List gffHeaderData, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { - GenomeAssembly assembly = null; + private void loadGenomeAssembly(String assemblyName, BulkLoadFileHistory history, List gffHeaderData, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { try { - assembly = gff3Service.loadGenomeAssembly(assemblyName, gffHeaderData, dataProvider); + gff3Service.loadGenomeAssembly(assemblyName, gffHeaderData, dataProvider); history.incrementCompleted(); } catch (ObjectUpdateException e) { history.incrementFailed(); @@ -159,7 +157,6 @@ private GenomeAssembly loadGenomeAssembly(String assemblyName, BulkLoadFileHisto } updateHistory(history); ph.progressProcess(); - return assembly; } private Map> loadEntities(BulkLoadFileHistory history, List gffData, Map> idsAdded, @@ -184,10 +181,10 @@ private Map> loadEntities(BulkLoadFileHistory history, List> loadAssociations(BulkLoadFileHistory history, List gffData, Map> idsAdded, - BackendBulkDataProvider dataProvider, GenomeAssembly assembly, ProcessDisplayHelper ph) { + BackendBulkDataProvider dataProvider, String assemblyId, ProcessDisplayHelper ph) { for (Gff3DTO gff3Entry : gffData) { try { - idsAdded = gff3Service.loadAssociations(history, gff3Entry, idsAdded, dataProvider, assembly); + idsAdded = gff3Service.loadAssociations(history, gff3Entry, idsAdded, dataProvider, assemblyId); history.incrementCompleted(); } catch (ObjectUpdateException e) { history.incrementFailed(); diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java b/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java index 715057abb..deff41f04 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/GenomeAssembly.java @@ -39,13 +39,13 @@ public class GenomeAssembly extends BiologicalEntity { @Index(columnList = "genomeassembly_id", name = "genomeassembly_crossreference_genomeassembly_index"), @Index(columnList = "crossreferences_id", name = "genomeassembly_crossreference_crossreference_index") }) - @EqualsAndHashCode.Include @JsonView({ View.FieldsAndLists.class }) private List crossReferences; @IndexedEmbedded(includePaths = {"name", "name_keyword", "curie", "curie_keyword", "modEntityId", "modEntityId_keyword", "modInternalId", "modInternalId_keyword"}) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @ManyToOne + @EqualsAndHashCode.Include @JsonView({ View.FieldsOnly.class }) private AffectedGenomicModel specimenGenomicModel; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java index 8749bfcd4..20eade1bc 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java @@ -34,10 +34,12 @@ public abstract class LocationAssociation extends EvidenceAssociation { @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) @Column(name="`start`") + @JsonView({ View.FieldsOnly.class }) private Integer start; @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) @Column(name="`end`") + @JsonView({ View.FieldsOnly.class }) private Integer end; } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java index d431aad3a..1dc03bec4 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java @@ -61,11 +61,16 @@ public class CodingSequenceGenomicLocationAssociation extends LocationAssociatio }) @ManyToOne @JsonView({ View.FieldsOnly.class }) - @JsonIgnoreProperties("codingSequenceGenomicLocationAssociations") + @JsonIgnoreProperties({ + "codingSequenceGenomicLocationAssociations", + "exonGenomicLocationAssociations", + "transcriptGenomicLocationAssociations" + }) @Fetch(FetchMode.JOIN) private AssemblyComponent codingSequenceGenomicLocationAssociationObject; @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @JsonView({ View.FieldsOnly.class }) private Integer phase; @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/constructAssociations/ConstructGenomicEntityAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/constructAssociations/ConstructGenomicEntityAssociation.java index 20373fcfd..5ed1f0721 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/constructAssociations/ConstructGenomicEntityAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/constructAssociations/ConstructGenomicEntityAssociation.java @@ -66,12 +66,15 @@ public class ConstructGenomicEntityAssociation extends EvidenceAssociation { @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @OneToOne @JsonView({ View.FieldsOnly.class }) - @JsonIgnoreProperties({"alleleGeneAssociations", "constructGenomicEntityAssociations", "sequenceTargetingReagentGeneAssociations"}) + @JsonIgnoreProperties({ + "alleleGeneAssociations", "constructGenomicEntityAssociations", "sequenceTargetingReagentGeneAssociations", + "transcriptGenomicLocationAssociations", "exonGenomicLocationAssociations", "codingSequenceGenomicLocationAssociations" + }) private GenomicEntity constructGenomicEntityAssociationObject; @IndexedEmbedded(includePaths = {"freeText", "noteType.name", "references.curie", - "references.primaryCrossReferenceCurie", "freeText_keyword", "noteType.name_keyword", "references.curie_keyword", - "references.primaryCrossReferenceCurie_keyword" + "references.primaryCrossReferenceCurie", "freeText_keyword", "noteType.name_keyword", "references.curie_keyword", + "references.primaryCrossReferenceCurie_keyword" }) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java index 112da96c6..8b0e94ba2 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java @@ -59,7 +59,11 @@ public class ExonGenomicLocationAssociation extends LocationAssociation { }) @ManyToOne @JsonView({ View.FieldsOnly.class }) - @JsonIgnoreProperties("exonGenomicLocationAssociations") + @JsonIgnoreProperties({ + "codingSequenceGenomicLocationAssociations", + "exonGenomicLocationAssociations", + "transcriptGenomicLocationAssociations" + }) @Fetch(FetchMode.JOIN) private AssemblyComponent exonGenomicLocationAssociationObject; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java index 91f1e4a79..fd492c504 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java @@ -61,11 +61,16 @@ public class TranscriptGenomicLocationAssociation extends LocationAssociation { }) @ManyToOne @JsonView({ View.FieldsOnly.class }) - @JsonIgnoreProperties("transcriptGenomicLocationAssociations") + @JsonIgnoreProperties({ + "codingSequenceGenomicLocationAssociations", + "exonGenomicLocationAssociations", + "transcriptGenomicLocationAssociations" + }) @Fetch(FetchMode.JOIN) private AssemblyComponent transcriptGenomicLocationAssociationObject; @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @JsonView({ View.FieldsOnly.class }) private Integer phase; @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/OntologyTerm.java b/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/OntologyTerm.java index 134613a09..9050efe31 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/OntologyTerm.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/OntologyTerm.java @@ -10,6 +10,8 @@ import org.alliancegenome.curation_api.model.entities.Synonym; import org.alliancegenome.curation_api.model.entities.base.CurieObject; import org.alliancegenome.curation_api.view.View; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; import org.hibernate.search.engine.backend.types.Aggregable; import org.hibernate.search.engine.backend.types.Searchable; import org.hibernate.search.engine.backend.types.Sortable; diff --git a/src/main/java/org/alliancegenome/curation_api/services/AssemblyComponentService.java b/src/main/java/org/alliancegenome/curation_api/services/AssemblyComponentService.java index 49aeca977..50d797d3c 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/AssemblyComponentService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/AssemblyComponentService.java @@ -23,6 +23,7 @@ public class AssemblyComponentService extends BaseEntityCrudService { @Inject AssemblyComponentDAO assemblyComponentDAO; + @Inject GenomeAssemblyService genomeAssemblyService; @Inject NcbiTaxonTermService ncbiTaxonTermService; @Inject DataProviderService dataProviderService; @@ -36,12 +37,12 @@ protected void init() { } @Transactional - public AssemblyComponent fetchOrCreate(String name, GenomeAssembly assembly, String taxonCurie, String dataProviderAbbreviation) { + public AssemblyComponent fetchOrCreate(String name, String assemblyId, String taxonCurie, String dataProviderAbbreviation) { AssemblyComponent assemblyComponent = null; if (assemblyComponentRequest != null) { UniqueIdGeneratorHelper uniqueIdGen = new UniqueIdGeneratorHelper(); uniqueIdGen.add(name); - uniqueIdGen.add(assembly.getModEntityId()); + uniqueIdGen.add(assemblyId); uniqueIdGen.add(taxonCurie); uniqueIdGen.add(dataProviderAbbreviation); String uniqueId = uniqueIdGen.getUniqueId(); @@ -49,20 +50,20 @@ public AssemblyComponent fetchOrCreate(String name, GenomeAssembly assembly, Str assemblyComponent = assemblyComponentCacheMap.get(uniqueId); } else { Log.debug("AssemblyComponent not cached, caching name|assembly: (" + uniqueId + ")"); - assemblyComponent = findAssemblyComponentOrCreateDB(name, assembly, taxonCurie, dataProviderAbbreviation); + assemblyComponent = findAssemblyComponentOrCreateDB(name, assemblyId, taxonCurie, dataProviderAbbreviation); assemblyComponentCacheMap.put(uniqueId, assemblyComponent); } } else { - assemblyComponent = findAssemblyComponentOrCreateDB(name, assembly, taxonCurie, dataProviderAbbreviation); + assemblyComponent = findAssemblyComponentOrCreateDB(name, assemblyId, taxonCurie, dataProviderAbbreviation); assemblyComponentRequest = new Date(); } return assemblyComponent; } - private AssemblyComponent findAssemblyComponentOrCreateDB(String name, GenomeAssembly assembly, String taxonCurie, String dataProviderAbbreviation) { + private AssemblyComponent findAssemblyComponentOrCreateDB(String name, String assemblyId, String taxonCurie, String dataProviderAbbreviation) { Map params = new HashMap<>(); params.put("name", name); - params.put(EntityFieldConstants.ASSEMBLY, assembly.getModEntityId()); + params.put(EntityFieldConstants.ASSEMBLY, assemblyId); params.put(EntityFieldConstants.TAXON, taxonCurie); params.put(EntityFieldConstants.DATA_PROVIDER, dataProviderAbbreviation); SearchResponse assemblyComponentResponse = assemblyComponentDAO.findByParams(params); @@ -71,10 +72,12 @@ private AssemblyComponent findAssemblyComponentOrCreateDB(String name, GenomeAss } AssemblyComponent assemblyComponent = new AssemblyComponent(); assemblyComponent.setName(name); - assemblyComponent.setGenomeAssembly(assembly); + SearchResponse assemblyResponse = genomeAssemblyService.findByField("modEntityId", assemblyId); + if (assemblyResponse != null && assemblyResponse.getSingleResult() != null) { + assemblyComponent.setGenomeAssembly(assemblyResponse.getSingleResult()); + } assemblyComponent.setTaxon(ncbiTaxonTermService.getByCurie(taxonCurie).getEntity()); assemblyComponent.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProviderAbbreviation)); - return assemblyComponentDAO.persist(assemblyComponent); } diff --git a/src/main/java/org/alliancegenome/curation_api/services/GenomeAssemblyService.java b/src/main/java/org/alliancegenome/curation_api/services/GenomeAssemblyService.java new file mode 100644 index 000000000..8c826d5ac --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/services/GenomeAssemblyService.java @@ -0,0 +1,23 @@ +package org.alliancegenome.curation_api.services; + +import org.alliancegenome.curation_api.dao.GenomeAssemblyDAO; +import org.alliancegenome.curation_api.model.entities.GenomeAssembly; +import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; + +@RequestScoped +public class GenomeAssemblyService extends BaseEntityCrudService { + + @Inject GenomeAssemblyDAO genomeAssemblyDAO; + + @Override + @PostConstruct + protected void init() { + setSQLDao(genomeAssemblyDAO); + } + + +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java index 4e3afe373..6256b6613 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java +++ b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java @@ -31,7 +31,6 @@ import org.alliancegenome.curation_api.services.helpers.gff3.Gff3UniqueIdHelper; import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; import org.alliancegenome.curation_api.services.validation.dto.Gff3DtoValidator; -import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import jakarta.enterprise.context.RequestScoped; @@ -53,7 +52,7 @@ public class Gff3Service { @Inject Gff3DtoValidator gff3DtoValidator; @Transactional - public GenomeAssembly loadGenomeAssembly(String assemblyName, List gffHeaderData, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { + public void loadGenomeAssembly(String assemblyName, List gffHeaderData, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { if (StringUtils.isBlank(assemblyName)) { for (String header : gffHeaderData) { @@ -69,18 +68,17 @@ public GenomeAssembly loadGenomeAssembly(String assemblyName, List gffHe params.put(EntityFieldConstants.TAXON, dataProvider.canonicalTaxonCurie); SearchResponse resp = genomeAssemblyDAO.findByParams(params); - if (resp != null && resp.getSingleResult() != null) { - return resp.getSingleResult(); - } - - GenomeAssembly assembly = new GenomeAssembly(); - assembly.setModEntityId(assemblyName); - assembly.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProvider.sourceOrganization)); - assembly.setTaxon(ncbiTaxonTermService.getByCurie(dataProvider.canonicalTaxonCurie).getEntity()); + if (resp == null || resp.getSingleResult() == null) { + GenomeAssembly assembly = new GenomeAssembly(); + assembly.setModEntityId(assemblyName); + assembly.setDataProvider(dataProviderService.createOrganizationDataProvider(dataProvider.sourceOrganization)); + assembly.setTaxon(ncbiTaxonTermService.getByCurie(dataProvider.canonicalTaxonCurie).getEntity()); - return genomeAssemblyDAO.persist(assembly); + genomeAssemblyDAO.persist(assembly); + } + } else { + throw new ObjectValidationException(gffHeaderData, "#!assembly - " + ValidationConstants.REQUIRED_MESSAGE); } - throw new ObjectValidationException(gffHeaderData, "#!assembly - " + ValidationConstants.REQUIRED_MESSAGE); } public Map> loadEntity(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { @@ -107,8 +105,8 @@ public Map> loadEntity(BulkLoadFileHistory history, Gff3DTO g } @Transactional - public Map> loadAssociations(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider, GenomeAssembly assembly) throws ObjectUpdateException { - if (ObjectUtils.isEmpty(assembly)) { + public Map> loadAssociations(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider, String assemblyId) throws ObjectUpdateException { + if (StringUtils.isEmpty(assemblyId)) { throw new ObjectValidationException(gffEntry, "Cannot load associations without assembly"); } @@ -121,7 +119,7 @@ public Map> loadAssociations(BulkLoadFileHistory history, Gff } Exon exon = response.getSingleResult(); - ExonGenomicLocationAssociation exonLocation = gff3DtoValidator.validateExonLocation(gffEntry, exon, assembly, dataProvider); + ExonGenomicLocationAssociation exonLocation = gff3DtoValidator.validateExonLocation(gffEntry, exon, assemblyId, dataProvider); if (exonLocation != null) { idsAdded.get("ExonGenomicLocationAssociation").add(exonLocation.getId()); exonLocationService.addAssociationToSubjectAndObject(exonLocation); @@ -133,7 +131,7 @@ public Map> loadAssociations(BulkLoadFileHistory history, Gff throw new ObjectValidationException(gffEntry, "uniqueId - " + ValidationConstants.INVALID_MESSAGE + " (" + uniqueId + ")"); } CodingSequence cds = response.getSingleResult(); - CodingSequenceGenomicLocationAssociation cdsLocation = gff3DtoValidator.validateCdsLocation(gffEntry, cds, assembly, dataProvider); + CodingSequenceGenomicLocationAssociation cdsLocation = gff3DtoValidator.validateCdsLocation(gffEntry, cds, assemblyId, dataProvider); if (cdsLocation != null) { idsAdded.get("CodingSequenceGenomicLocationAssociation").add(cdsLocation.getId()); cdsLocationService.addAssociationToSubjectAndObject(cdsLocation); @@ -150,7 +148,7 @@ public Map> loadAssociations(BulkLoadFileHistory history, Gff throw new ObjectValidationException(gffEntry, "attributes - ID - " + ValidationConstants.INVALID_MESSAGE + " (" + attributes.get("ID") + ")"); } Transcript transcript = response.getSingleResult(); - TranscriptGenomicLocationAssociation transcriptLocation = gff3DtoValidator.validateTranscriptLocation(gffEntry, transcript, assembly, dataProvider); + TranscriptGenomicLocationAssociation transcriptLocation = gff3DtoValidator.validateTranscriptLocation(gffEntry, transcript, assemblyId, dataProvider); if (transcriptLocation != null) { idsAdded.get("TranscriptGenomicLocationAssociation").add(transcriptLocation.getId()); transcriptLocationService.addAssociationToSubjectAndObject(transcriptLocation); diff --git a/src/main/java/org/alliancegenome/curation_api/services/ontology/NcbiTaxonTermService.java b/src/main/java/org/alliancegenome/curation_api/services/ontology/NcbiTaxonTermService.java index 6ca8f7868..f3636138d 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/ontology/NcbiTaxonTermService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/ontology/NcbiTaxonTermService.java @@ -16,6 +16,7 @@ import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; +import jakarta.transaction.Transactional; import si.mazi.rescu.RestProxyFactory; @RequestScoped @@ -58,6 +59,7 @@ public ObjectResponse getByCurie(String taxonCurie) { return response; } + @Transactional public NCBITaxonTerm getTaxonFromDB(String taxonCurie) { NCBITaxonTerm taxon = findByCurie(taxonCurie); if (taxon == null) { @@ -69,7 +71,7 @@ public NCBITaxonTerm getTaxonFromDB(String taxonCurie) { return taxon; } - public NCBITaxonTerm downloadAndSave(String taxonCurie) { + private NCBITaxonTerm downloadAndSave(String taxonCurie) { Pattern taxonIdPattern = Pattern.compile("^NCBITaxon:(\\d+)$"); Matcher taxonIdMatcher = taxonIdPattern.matcher(taxonCurie); diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/ExperimentalConditionValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/ExperimentalConditionValidator.java index e4ed7a78e..aed176046 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/ExperimentalConditionValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/ExperimentalConditionValidator.java @@ -219,7 +219,7 @@ public NCBITaxonTerm validateConditionTaxon(ExperimentalCondition uiEntity, Expe if (StringUtils.isNotBlank(uiEntity.getConditionTaxon().getCurie())) { taxonTerm = ncbiTaxonTermService.findByCurie(uiEntity.getConditionTaxon().getCurie()); if (taxonTerm == null) { - taxonTerm = ncbiTaxonTermService.downloadAndSave(uiEntity.getConditionTaxon().getCurie()); + taxonTerm = ncbiTaxonTermService.getTaxonFromDB(uiEntity.getConditionTaxon().getCurie()); } if (taxonTerm == null) { addMessageResponse(field, ValidationConstants.INVALID_MESSAGE); diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java index e7f4126ae..934ff490b 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -161,15 +161,15 @@ private ObjectResponse validateGffEntity(E entity, } @Transactional - public CodingSequenceGenomicLocationAssociation validateCdsLocation(Gff3DTO gffEntry, CodingSequence cds, GenomeAssembly assembly, BackendBulkDataProvider dataProvider) throws ObjectValidationException { + public CodingSequenceGenomicLocationAssociation validateCdsLocation(Gff3DTO gffEntry, CodingSequence cds, String assemblyId, BackendBulkDataProvider dataProvider) throws ObjectValidationException { AssemblyComponent assemblyComponent = null; CodingSequenceGenomicLocationAssociation locationAssociation = new CodingSequenceGenomicLocationAssociation(); if (StringUtils.isNotBlank(gffEntry.getSeqId())) { - assemblyComponent = assemblyComponentService.fetchOrCreate(gffEntry.getSeqId(), assembly, dataProvider.canonicalTaxonCurie, dataProvider.sourceOrganization); + assemblyComponent = assemblyComponentService.fetchOrCreate(gffEntry.getSeqId(), assemblyId, dataProvider.canonicalTaxonCurie, dataProvider.sourceOrganization); Map params = new HashMap<>(); params.put(EntityFieldConstants.CODING_SEQUENCE_ASSOCIATION_SUBJECT + ".id", cds.getId()); params.put(EntityFieldConstants.CODING_SEQUENCE_GENOMIC_LOCATION_ASSOCIATION_OBJECT, assemblyComponent.getName()); - params.put(EntityFieldConstants.CODING_SEQUENCE_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY, assembly.getModEntityId()); + params.put(EntityFieldConstants.CODING_SEQUENCE_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY, assemblyId); SearchResponse locationSearchResponse = cdsLocationDAO.findByParams(params); if (locationSearchResponse != null && locationSearchResponse.getSingleResult() != null) { locationAssociation = locationSearchResponse.getSingleResult(); @@ -189,15 +189,15 @@ public CodingSequenceGenomicLocationAssociation validateCdsLocation(Gff3DTO gffE } @Transactional - public ExonGenomicLocationAssociation validateExonLocation(Gff3DTO gffEntry, Exon exon, GenomeAssembly assembly, BackendBulkDataProvider dataProvider) throws ObjectValidationException { + public ExonGenomicLocationAssociation validateExonLocation(Gff3DTO gffEntry, Exon exon, String assemblyId, BackendBulkDataProvider dataProvider) throws ObjectValidationException { AssemblyComponent assemblyComponent = null; ExonGenomicLocationAssociation locationAssociation = new ExonGenomicLocationAssociation(); if (StringUtils.isNotBlank(gffEntry.getSeqId())) { - assemblyComponent = assemblyComponentService.fetchOrCreate(gffEntry.getSeqId(), assembly, dataProvider.canonicalTaxonCurie, dataProvider.sourceOrganization); + assemblyComponent = assemblyComponentService.fetchOrCreate(gffEntry.getSeqId(), assemblyId, dataProvider.canonicalTaxonCurie, dataProvider.sourceOrganization); Map params = new HashMap<>(); params.put(EntityFieldConstants.EXON_ASSOCIATION_SUBJECT + ".id", exon.getId()); params.put(EntityFieldConstants.EXON_GENOMIC_LOCATION_ASSOCIATION_OBJECT, assemblyComponent.getName()); - params.put(EntityFieldConstants.EXON_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY, assembly.getModEntityId()); + params.put(EntityFieldConstants.EXON_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY, assemblyId); SearchResponse locationSearchResponse = exonLocationDAO.findByParams(params); if (locationSearchResponse != null && locationSearchResponse.getSingleResult() != null) { locationAssociation = locationSearchResponse.getSingleResult(); @@ -216,15 +216,14 @@ public ExonGenomicLocationAssociation validateExonLocation(Gff3DTO gffEntry, Exo } @Transactional - public TranscriptGenomicLocationAssociation validateTranscriptLocation(Gff3DTO gffEntry, Transcript transcript, GenomeAssembly assembly, BackendBulkDataProvider dataProvider) throws ObjectValidationException { + public TranscriptGenomicLocationAssociation validateTranscriptLocation(Gff3DTO gffEntry, Transcript transcript, String assemblyId, BackendBulkDataProvider dataProvider) throws ObjectValidationException { AssemblyComponent assemblyComponent = null; TranscriptGenomicLocationAssociation locationAssociation = new TranscriptGenomicLocationAssociation(); if (StringUtils.isNotBlank(gffEntry.getSeqId())) { - assemblyComponent = assemblyComponentService.fetchOrCreate(gffEntry.getSeqId(), assembly, dataProvider.canonicalTaxonCurie, dataProvider.sourceOrganization); + assemblyComponent = assemblyComponentService.fetchOrCreate(gffEntry.getSeqId(), assemblyId, dataProvider.canonicalTaxonCurie, dataProvider.sourceOrganization); Map params = new HashMap<>(); params.put(EntityFieldConstants.TRANSCRIPT_ASSOCIATION_SUBJECT + ".id", transcript.getId()); - params.put(EntityFieldConstants.TRANSCRIPT_GENOMIC_LOCATION_ASSOCIATION_OBJECT, assemblyComponent.getName()); - params.put(EntityFieldConstants.TRANSCRIPT_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY, assembly.getModEntityId()); + params.put(EntityFieldConstants.TRANSCRIPT_GENOMIC_LOCATION_ASSOCIATION_OBJECT_ASSEMBLY, assemblyId); SearchResponse locationSearchResponse = transcriptLocationDAO.findByParams(params); if (locationSearchResponse != null && locationSearchResponse.getSingleResult() != null) { locationAssociation = locationSearchResponse.getSingleResult(); diff --git a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java index 4344a0230..038ce6e0f 100644 --- a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java @@ -48,6 +48,7 @@ public void init() { private void loadRequiredEntities() throws Exception { createSoTerm("SO:0000234", "mRNA", false); + createSoTerm("SO:0001035", "piRNA", false); createSoTerm("SO:0000147", "exon", false); createSoTerm("SO:0000316", "CDS", false); } @@ -57,7 +58,7 @@ private void loadRequiredEntities() throws Exception { public void gff3DataBulkUploadTranscriptEntity() throws Exception { loadRequiredEntities(); - checkSuccessfulBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "GFF01_transcript.json", 3); + checkSuccessfulBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "GFF_01_transcript.json", 3); RestAssured.given(). when(). @@ -71,7 +72,7 @@ public void gff3DataBulkUploadTranscriptEntity() throws Exception { body("entity.transcriptType.curie", is("SO:0000234")). body("entity.transcriptGenomicLocationAssociations", hasSize(1)). body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.name", is("I")). - body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.taxonCurie", is("NCBITaxon:6239")). + body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.taxon.curie", is("NCBITaxon:6239")). body("entity.transcriptGenomicLocationAssociations[0].start", is(1)). body("entity.transcriptGenomicLocationAssociations[0].end", is(1000)). body("entity.transcriptGenomicLocationAssociations[0].phase", is(0)). @@ -82,7 +83,7 @@ public void gff3DataBulkUploadTranscriptEntity() throws Exception { @Test @Order(2) public void gff3DataBulkUploadExonEntity() throws Exception { - checkSuccessfulBulkLoad(exonBulkPostEndpoint, gffDataTestFilePath + "GFF02_exon.json", 3); + checkSuccessfulBulkLoad(exonBulkPostEndpoint, gffDataTestFilePath + "GFF_02_exon.json", 3); RestAssured.given(). when(). @@ -94,7 +95,7 @@ public void gff3DataBulkUploadExonEntity() throws Exception { body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")). body("entity.exonGenomicLocationAssociations", hasSize(1)). body("entity.exonGenomicLocationAssociations[0].exonGenomicLocationAssociationObject.name", is("I")). - body("entity.exonGenomicLocationAssociations[0].exonGenomicLocationAssociationObject.taxonCurie", is("NCBITaxon:6239")). + body("entity.exonGenomicLocationAssociations[0].exonGenomicLocationAssociationObject.taxon.curie", is("NCBITaxon:6239")). body("entity.exonGenomicLocationAssociations[0].start", is(1)). body("entity.exonGenomicLocationAssociations[0].end", is(100)). body("entity.exonGenomicLocationAssociations[0].strand", is("+")); @@ -104,7 +105,7 @@ public void gff3DataBulkUploadExonEntity() throws Exception { @Test @Order(3) public void gff3DataBulkUploadCodingSequenceEntity() throws Exception { - checkSuccessfulBulkLoad(cdsBulkPostEndpoint, gffDataTestFilePath + "GFF03_CDS.json", 3); + checkSuccessfulBulkLoad(cdsBulkPostEndpoint, gffDataTestFilePath + "GFF_03_CDS.json", 3); RestAssured.given(). when(). @@ -116,12 +117,60 @@ public void gff3DataBulkUploadCodingSequenceEntity() throws Exception { body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")). body("entity.codingSequenceGenomicLocationAssociations", hasSize(1)). body("entity.codingSequenceGenomicLocationAssociations[0].codingSequenceGenomicLocationAssociationObject.name", is("I")). - body("entity.codingSequenceGenomicLocationAssociations[0].codingSequenceGenomicLocationAssociationObject.taxonCurie", is("NCBITaxon:6239")). + body("entity.codingSequenceGenomicLocationAssociations[0].codingSequenceGenomicLocationAssociationObject.taxon.curie", is("NCBITaxon:6239")). body("entity.codingSequenceGenomicLocationAssociations[0].start", is(10)). body("entity.codingSequenceGenomicLocationAssociations[0].end", is(100)). body("entity.codingSequenceGenomicLocationAssociations[0].phase", is(1)). body("entity.codingSequenceGenomicLocationAssociations[0].strand", is("+")); } + + @Test + @Order(4) + public void gff3DataBulkUploadUpdateTranscriptEntity() throws Exception { + checkSuccessfulBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "UD_01_update_transcript.json", 3); + + RestAssured.given(). + when(). + get(transcriptGetEndpoint + transcriptId). + then(). + statusCode(200). + body("entity.modInternalId", is(transcriptId)). + body("entity.name", is("Y74C9A.2a.1")). + body("entity.taxon.curie", is("NCBITaxon:6239")). + body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")). + body("entity.transcriptType.curie", is("SO:0001035")). + body("entity.transcriptGenomicLocationAssociations", hasSize(1)). + body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.name", is("II")). + body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.taxon.curie", is("NCBITaxon:6239")). + body("entity.transcriptGenomicLocationAssociations[0].start", is(2)). + body("entity.transcriptGenomicLocationAssociations[0].end", is(2000)). + body("entity.transcriptGenomicLocationAssociations[0].phase", is(1)). + body("entity.transcriptGenomicLocationAssociations[0].strand", is("-")); + + } + + @Test + @Order(5) + public void gff3DataBulkUploadMissingRequiredFields() throws Exception { + checkFailedBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "MR_01_no_seq_id.json", 3, 1, 2); + checkFailedBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "MR_02_no_start.json", 3, 1, 2); + checkFailedBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "MR_03_no_end.json", 3, 1, 2); + checkFailedBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "MR_04_no_strand.json", 3, 1, 2); + } + + @Test + @Order(6) + public void gff3DataBulkUploadEmptyRequiredFields() throws Exception { + checkFailedBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "ER_01_empty_seq_id.json", 3, 1, 2); + checkFailedBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "ER_02_empty_strand.json", 3, 1, 2); + } + + @Test + @Order(7) + public void gff3DataBulkUploadInvalidFields() throws Exception { + checkFailedBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "IV_01_invalid_strand.json", 3, 1, 2); + checkFailedBulkLoad(transcriptBulkPostEndpoint, gffDataTestFilePath + "IV_02_invalid_phase.json", 3, 1, 2); + } } diff --git a/src/test/resources/bulk/fms/08_gff_data/ER_01_empty_seq_id.json b/src/test/resources/bulk/fms/08_gff_data/ER_01_empty_seq_id.json new file mode 100644 index 000000000..a691479e6 --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/ER_01_empty_seq_id.json @@ -0,0 +1,16 @@ +[ + { + "seqId": "", + "source": "WormBase", + "type": "mRNA", + "start": 1, + "end": 1000, + "strand": "+", + "phase": 0, + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/ER_02_empty_strand.json b/src/test/resources/bulk/fms/08_gff_data/ER_02_empty_strand.json new file mode 100644 index 000000000..32a9ac0ec --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/ER_02_empty_strand.json @@ -0,0 +1,16 @@ +[ + { + "seqId": "I", + "source": "WormBase", + "type": "mRNA", + "start": 1, + "end": 1000, + "strand": "", + "phase": 0, + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json b/src/test/resources/bulk/fms/08_gff_data/GFF_01_transcript.json similarity index 100% rename from src/test/resources/bulk/fms/08_gff_data/GFF01_transcript.json rename to src/test/resources/bulk/fms/08_gff_data/GFF_01_transcript.json diff --git a/src/test/resources/bulk/fms/08_gff_data/GFF02_exon.json b/src/test/resources/bulk/fms/08_gff_data/GFF_02_exon.json similarity index 100% rename from src/test/resources/bulk/fms/08_gff_data/GFF02_exon.json rename to src/test/resources/bulk/fms/08_gff_data/GFF_02_exon.json diff --git a/src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json b/src/test/resources/bulk/fms/08_gff_data/GFF_03_CDS.json similarity index 100% rename from src/test/resources/bulk/fms/08_gff_data/GFF03_CDS.json rename to src/test/resources/bulk/fms/08_gff_data/GFF_03_CDS.json diff --git a/src/test/resources/bulk/fms/08_gff_data/IV_01_invalid_strand.json b/src/test/resources/bulk/fms/08_gff_data/IV_01_invalid_strand.json new file mode 100644 index 000000000..920bde5f5 --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/IV_01_invalid_strand.json @@ -0,0 +1,16 @@ +[ + { + "seqId": "I", + "source": "WormBase", + "type": "mRNA", + "start": 1, + "end": 1000, + "strand": "X", + "phase": 0, + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/IV_02_invalid_phase.json b/src/test/resources/bulk/fms/08_gff_data/IV_02_invalid_phase.json new file mode 100644 index 000000000..e6f751326 --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/IV_02_invalid_phase.json @@ -0,0 +1,16 @@ +[ + { + "seqId": "I", + "source": "WormBase", + "type": "mRNA", + "start": 1, + "end": 1000, + "strand": "+", + "phase": 3, + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/MR_01_no_seq_id.json b/src/test/resources/bulk/fms/08_gff_data/MR_01_no_seq_id.json new file mode 100644 index 000000000..e9651e61e --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/MR_01_no_seq_id.json @@ -0,0 +1,15 @@ +[ + { + "source": "WormBase", + "type": "mRNA", + "start": 1, + "end": 1000, + "strand": "+", + "phase": 0, + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/MR_02_no_start.json b/src/test/resources/bulk/fms/08_gff_data/MR_02_no_start.json new file mode 100644 index 000000000..0997e4e33 --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/MR_02_no_start.json @@ -0,0 +1,15 @@ +[ + { + "seqId": "I", + "source": "WormBase", + "type": "mRNA", + "end": 1000, + "strand": "+", + "phase": 0, + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/MR_03_no_end.json b/src/test/resources/bulk/fms/08_gff_data/MR_03_no_end.json new file mode 100644 index 000000000..7284de1d8 --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/MR_03_no_end.json @@ -0,0 +1,15 @@ +[ + { + "seqId": "I", + "source": "WormBase", + "type": "mRNA", + "start": 1, + "strand": "+", + "phase": 0, + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/MR_04_no_strand.json b/src/test/resources/bulk/fms/08_gff_data/MR_04_no_strand.json new file mode 100644 index 000000000..3a6cdcbd6 --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/MR_04_no_strand.json @@ -0,0 +1,15 @@ +[ + { + "seqId": "I", + "source": "WormBase", + "type": "mRNA", + "start": 1, + "end": 1000, + "phase": 0, + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" + ] + } +] diff --git a/src/test/resources/bulk/fms/08_gff_data/UD_01_update_transcript.json b/src/test/resources/bulk/fms/08_gff_data/UD_01_update_transcript.json new file mode 100644 index 000000000..ed9d9e98e --- /dev/null +++ b/src/test/resources/bulk/fms/08_gff_data/UD_01_update_transcript.json @@ -0,0 +1,16 @@ +[ + { + "seqId": "II", + "source": "WormBase", + "type": "piRNA", + "start": 2, + "end": 2000, + "strand": "-", + "phase": 1, + "attributes": [ + "ID=Transcript:Y74C9A.2a.1", + "Parent=Gene:WBGene00022276", + "Name=Y74C9A.2a.1" + ] + } +] From ce2f45707c8b99afdd4df30b483e9b93799dbcc9 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Mon, 15 Jul 2024 07:41:53 +0100 Subject: [PATCH 47/82] Add relation --- .../services/validation/dto/Gff3DtoValidator.java | 5 ++++- .../db/migration/v0.36.0.4__gff_association_tables.sql | 6 +++++- .../alliancegenome/curation_api/Gff3BulkUploadITCase.java | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java index 934ff490b..a89ff1654 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java +++ b/src/main/java/org/alliancegenome/curation_api/services/validation/dto/Gff3DtoValidator.java @@ -18,7 +18,6 @@ import org.alliancegenome.curation_api.model.entities.AssemblyComponent; import org.alliancegenome.curation_api.model.entities.CodingSequence; import org.alliancegenome.curation_api.model.entities.Exon; -import org.alliancegenome.curation_api.model.entities.GenomeAssembly; import org.alliancegenome.curation_api.model.entities.GenomicEntity; import org.alliancegenome.curation_api.model.entities.LocationAssociation; import org.alliancegenome.curation_api.model.entities.Transcript; @@ -32,6 +31,7 @@ import org.alliancegenome.curation_api.services.AssemblyComponentService; import org.alliancegenome.curation_api.services.DataProviderService; import org.alliancegenome.curation_api.services.Gff3Service; +import org.alliancegenome.curation_api.services.VocabularyTermService; import org.alliancegenome.curation_api.services.helpers.gff3.Gff3AttributesHelper; import org.alliancegenome.curation_api.services.helpers.gff3.Gff3UniqueIdHelper; import org.alliancegenome.curation_api.services.ontology.NcbiTaxonTermService; @@ -55,6 +55,7 @@ public class Gff3DtoValidator { @Inject NcbiTaxonTermService ncbiTaxonTermService; @Inject SoTermDAO soTermDAO; @Inject Gff3Service gff3Service; + @Inject VocabularyTermService vocabularyTermService; @Transactional public Exon validateExonEntry(Gff3DTO dto, BackendBulkDataProvider dataProvider) throws ObjectValidationException { @@ -245,6 +246,8 @@ public TranscriptGenomicLocationAssociation validateTranscriptLocation(Gff3DTO g private ObjectResponse validateLocationAssociation(E association, Gff3DTO dto, AssemblyComponent assemblyComponent) { ObjectResponse associationResponse = new ObjectResponse(); + association.setRelation(vocabularyTermService.getTermInVocabulary("location_association_relation", "located_on").getEntity()); + if (assemblyComponent == null) { associationResponse.addErrorMessage("SeqId", ValidationConstants.REQUIRED_MESSAGE); } diff --git a/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql b/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql index 27c13e338..afa406dc2 100644 --- a/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql +++ b/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql @@ -127,4 +127,8 @@ CREATE INDEX transcriptlocationassociation_relation_index ON transcriptgenomiclo CREATE INDEX transcriptlocationassociation_subject_index ON transcriptgenomiclocationassociation USING btree (transcriptassociationsubject_id); CREATE INDEX transcriptlocationassociation_object_index ON transcriptgenomiclocationassociation - USING btree (transcriptgenomiclocationassociationobject_id); \ No newline at end of file + USING btree (transcriptgenomiclocationassociationobject_id); + +INSERT INTO vocabulary (id, name, vocabularylabel) VALUES (nextval('vocabulary_seq'), 'Location Association Relation', 'location_association_relation'); +INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'located_on', id FROM vocabulary WHERE vocabularylabel = 'location_association_relation'; + \ No newline at end of file diff --git a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java index 038ce6e0f..5ea4d9709 100644 --- a/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/Gff3BulkUploadITCase.java @@ -71,6 +71,7 @@ public void gff3DataBulkUploadTranscriptEntity() throws Exception { body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")). body("entity.transcriptType.curie", is("SO:0000234")). body("entity.transcriptGenomicLocationAssociations", hasSize(1)). + body("entity.transcriptGenomicLocationAssociations[0].relation.name", is("located_on")). body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.name", is("I")). body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.taxon.curie", is("NCBITaxon:6239")). body("entity.transcriptGenomicLocationAssociations[0].start", is(1)). @@ -94,6 +95,7 @@ public void gff3DataBulkUploadExonEntity() throws Exception { body("entity.taxon.curie", is("NCBITaxon:6239")). body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")). body("entity.exonGenomicLocationAssociations", hasSize(1)). + body("entity.exonGenomicLocationAssociations[0].relation.name", is("located_on")). body("entity.exonGenomicLocationAssociations[0].exonGenomicLocationAssociationObject.name", is("I")). body("entity.exonGenomicLocationAssociations[0].exonGenomicLocationAssociationObject.taxon.curie", is("NCBITaxon:6239")). body("entity.exonGenomicLocationAssociations[0].start", is(1)). @@ -116,6 +118,7 @@ public void gff3DataBulkUploadCodingSequenceEntity() throws Exception { body("entity.taxon.curie", is("NCBITaxon:6239")). body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")). body("entity.codingSequenceGenomicLocationAssociations", hasSize(1)). + body("entity.codingSequenceGenomicLocationAssociations[0].relation.name", is("located_on")). body("entity.codingSequenceGenomicLocationAssociations[0].codingSequenceGenomicLocationAssociationObject.name", is("I")). body("entity.codingSequenceGenomicLocationAssociations[0].codingSequenceGenomicLocationAssociationObject.taxon.curie", is("NCBITaxon:6239")). body("entity.codingSequenceGenomicLocationAssociations[0].start", is(10)). @@ -141,6 +144,7 @@ public void gff3DataBulkUploadUpdateTranscriptEntity() throws Exception { body("entity.dataProvider.sourceOrganization.abbreviation", is("WB")). body("entity.transcriptType.curie", is("SO:0001035")). body("entity.transcriptGenomicLocationAssociations", hasSize(1)). + body("entity.transcriptGenomicLocationAssociations[0].relation.name", is("located_on")). body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.name", is("II")). body("entity.transcriptGenomicLocationAssociations[0].transcriptGenomicLocationAssociationObject.taxon.curie", is("NCBITaxon:6239")). body("entity.transcriptGenomicLocationAssociations[0].start", is(2)). From 72c4679b7ac3dcc67b1d4fa8bff394a5b6a4b676 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Mon, 15 Jul 2024 11:30:22 +0100 Subject: [PATCH 48/82] Checkstyle fixes --- .../curation_api/model/entities/LocationAssociation.java | 6 +++--- .../CodingSequenceGenomicLocationAssociation.java | 2 +- .../exonAssociations/ExonGenomicLocationAssociation.java | 2 +- .../TranscriptGenomicLocationAssociation.java | 4 ++-- .../curation_api/model/entities/ontology/OntologyTerm.java | 2 -- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java index 20eade1bc..ce3000a70 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java @@ -33,12 +33,12 @@ public abstract class LocationAssociation extends EvidenceAssociation { private VocabularyTerm relation; @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) - @Column(name="`start`") + @Column(name = "`start`") @JsonView({ View.FieldsOnly.class }) private Integer start; - @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) - @Column(name="`end`") + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @Column(name = "`end`") @JsonView({ View.FieldsOnly.class }) private Integer end; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java index 1dc03bec4..0d15a045b 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java @@ -69,7 +69,7 @@ public class CodingSequenceGenomicLocationAssociation extends LocationAssociatio @Fetch(FetchMode.JOIN) private AssemblyComponent codingSequenceGenomicLocationAssociationObject; - @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) @JsonView({ View.FieldsOnly.class }) private Integer phase; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java index 8b0e94ba2..3cc57e566 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java @@ -65,7 +65,7 @@ public class ExonGenomicLocationAssociation extends LocationAssociation { "transcriptGenomicLocationAssociations" }) @Fetch(FetchMode.JOIN) - private AssemblyComponent exonGenomicLocationAssociationObject; + private AssemblyComponent exonGenomicLocationAssociationObject; @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") @KeywordField(name = "phenotypeAnnotationObject_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java index fd492c504..8f4558793 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java @@ -67,9 +67,9 @@ public class TranscriptGenomicLocationAssociation extends LocationAssociation { "transcriptGenomicLocationAssociations" }) @Fetch(FetchMode.JOIN) - private AssemblyComponent transcriptGenomicLocationAssociationObject; + private AssemblyComponent transcriptGenomicLocationAssociationObject; - @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) @JsonView({ View.FieldsOnly.class }) private Integer phase; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/OntologyTerm.java b/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/OntologyTerm.java index 9050efe31..134613a09 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/OntologyTerm.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/ontology/OntologyTerm.java @@ -10,8 +10,6 @@ import org.alliancegenome.curation_api.model.entities.Synonym; import org.alliancegenome.curation_api.model.entities.base.CurieObject; import org.alliancegenome.curation_api.view.View; -import org.hibernate.annotations.Fetch; -import org.hibernate.annotations.FetchMode; import org.hibernate.search.engine.backend.types.Aggregable; import org.hibernate.search.engine.backend.types.Searchable; import org.hibernate.search.engine.backend.types.Sortable; From 882813a2083969fad78a4042acfa3a764156ce1e Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Mon, 15 Jul 2024 11:38:09 +0100 Subject: [PATCH 49/82] Another checkstyle fix --- .../curation_api/model/entities/LocationAssociation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java index ce3000a70..09baf468a 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/LocationAssociation.java @@ -32,7 +32,7 @@ public abstract class LocationAssociation extends EvidenceAssociation { @JsonView({ View.FieldsOnly.class }) private VocabularyTerm relation; - @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) @Column(name = "`start`") @JsonView({ View.FieldsOnly.class }) private Integer start; From 2a423d0c0a58791970febad8a53761b685c8419a Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Mon, 15 Jul 2024 12:50:24 +0100 Subject: [PATCH 50/82] Remove FBCV terms attached to phenotypeannotations --- .../v0.36.0.4__remove_fbcv_terms_loaded_as_phenotype_terms.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/main/resources/db/migration/v0.36.0.4__remove_fbcv_terms_loaded_as_phenotype_terms.sql diff --git a/src/main/resources/db/migration/v0.36.0.4__remove_fbcv_terms_loaded_as_phenotype_terms.sql b/src/main/resources/db/migration/v0.36.0.4__remove_fbcv_terms_loaded_as_phenotype_terms.sql new file mode 100644 index 000000000..c7f020214 --- /dev/null +++ b/src/main/resources/db/migration/v0.36.0.4__remove_fbcv_terms_loaded_as_phenotype_terms.sql @@ -0,0 +1,3 @@ +DELETE FROM phenotypeannotation_ontologyterm WHERE phenotypeterms_id IN ( + SELECT id FROM ontologyterm WHERE ontologytermtype = 'FBCVTerm' +); \ No newline at end of file From 3add3f0738664b0706c287b1a95fff17335acfb9 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Mon, 15 Jul 2024 14:20:48 +0100 Subject: [PATCH 51/82] Bump migration version --- ...sociation_tables.sql => v0.36.0.5__gff_association_tables.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{v0.36.0.4__gff_association_tables.sql => v0.36.0.5__gff_association_tables.sql} (100%) diff --git a/src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql b/src/main/resources/db/migration/v0.36.0.5__gff_association_tables.sql similarity index 100% rename from src/main/resources/db/migration/v0.36.0.4__gff_association_tables.sql rename to src/main/resources/db/migration/v0.36.0.5__gff_association_tables.sql From 37beb3cfc7110290e94e920eeee0a163136e360d Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Tue, 16 Jul 2024 08:27:20 -0500 Subject: [PATCH 52/82] Added vocabulary terms for HTP Dataset and HTP Dataset Sample --- .../cliapp/src/service/DataLoadService.js | 2 +- .../enums/BackendBulkLoadType.java | 2 +- ...6.0.4__highthroughputexpressiondataset.sql | 61 ++++++++++++++----- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/main/cliapp/src/service/DataLoadService.js b/src/main/cliapp/src/service/DataLoadService.js index 8eaf6fb4a..28b2eaa66 100644 --- a/src/main/cliapp/src/service/DataLoadService.js +++ b/src/main/cliapp/src/service/DataLoadService.js @@ -81,7 +81,7 @@ export class DataLoadService extends BaseAuthService { const bulkLoadTypes = { BulkFMSLoad: [ 'GFF', - 'HTP_EXPRESSION_DATASET_ANNOTATION', + 'HTPDATASET', 'INTERACTION-GEN', 'INTERACTION-MOL', 'MOLECULE', diff --git a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java index 119aef824..2c3ae805d 100644 --- a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java +++ b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java @@ -24,7 +24,7 @@ public enum BackendBulkLoadType { PARALOGY("json"), SEQUENCE_TARGETING_REAGENT("json"), EXPRESSION("json"), - HTP_EXPRESSION_DATASET_ANNOTATION("json"); + HTPDATASET("json"); public String fileExtension; diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql index 62108110c..da1345447 100644 --- a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql +++ b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql @@ -3,41 +3,74 @@ INSERT INTO bulkloadgroup (id, name) VALUES (nextval('bulkloadgroup_seq'), 'HTP Expression Dataset Annotation Bulk Loads'); INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'FB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'ZFIN HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'ZFIN HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'MGI HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'MGI HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'RGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'RGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'SGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'SGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'WB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) -SELECT id, '0 0 22 ? * SUN-THU', true FROM bulkload WHERE backendbulkloadtype = 'HTP_EXPRESSION_DATASET_ANNOTATION'; +SELECT id, '0 0 22 ? * SUN-THU', true FROM bulkload WHERE backendbulkloadtype = 'HTPDATASET'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB' FROM bulkload WHERE name = 'FB HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'FB' FROM bulkload WHERE name = 'FB HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'MGI' FROM bulkload WHERE name = 'MGI HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'MGI' FROM bulkload WHERE name = 'MGI HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'RGD' FROM bulkload WHERE name = 'RGD HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'RGD' FROM bulkload WHERE name = 'RGD HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'SGD' FROM bulkload WHERE name = 'SGD HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'SGD' FROM bulkload WHERE name = 'SGD HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB' FROM bulkload WHERE name = 'WB HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'WB' FROM bulkload WHERE name = 'WB HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'ZFIN' FROM bulkload WHERE name = 'ZFIN HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'ZFIN' FROM bulkload WHERE name = 'ZFIN HTP Expression Dataset Annotation Load'; ---Adding 3 extra vocabulary terms for HTPTags +--Adding vocabulary terms INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'epigenome', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional genomics and proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'karyotyping', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; +INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'HTP Expression Dataset Summary', 'Summary of the high-throughput expression dataset' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; +INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'HTP Expression Dataset Sample Note', 'Note pertaining to a high-throughput expression dataset sample' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; + +INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) + SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Note Type', 'htp_expression_dataset_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; + +INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) + WITH + t1 AS ( + SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_note_type' + ), + t2 AS ( + SELECT id FROM vocabularyterm WHERE name = 'HTP Expression Dataset Summary' AND vocabulary_id = ( + SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' + ) + ) + SELECT t1.id, t2.id FROM t1,t2; + +INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) + SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Sample Note Type', 'htp_expression_dataset_sample_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; + +INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) + WITH + t1 AS ( + SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_sample_note_type' + ), + t2 AS ( + SELECT id FROM vocabularyterm WHERE name = 'HTP Expression Dataset Sample Note' AND vocabulary_id = ( + SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' + ) + ) + SELECT t1.id, t2.id FROM t1,t2; + -- Adding highthroughputexpressiondatasetannotation CREATE SEQUENCE highthroughputexpressiondatasetannotation_seq START WITH 1 INCREMENT BY 50 NO MINVALUE NO MAXVALUE CACHE 1; From e1a5d54d43ba566acfbf4a66d26f31b5b76e953f Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Tue, 16 Jul 2024 08:29:40 -0500 Subject: [PATCH 53/82] changes vocabulary terms name into snake case --- .../v0.36.0.4__highthroughputexpressiondataset.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql index da1345447..a2fd4fef3 100644 --- a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql +++ b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql @@ -38,8 +38,8 @@ INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyt INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional genomics and proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'karyotyping', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; -INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'HTP Expression Dataset Summary', 'Summary of the high-throughput expression dataset' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; -INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'HTP Expression Dataset Sample Note', 'Note pertaining to a high-throughput expression dataset sample' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; +INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_summary', 'Summary of the high-throughput expression dataset' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; +INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_sample_note', 'Note pertaining to a high-throughput expression dataset sample' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Note Type', 'htp_expression_dataset_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; @@ -50,7 +50,7 @@ INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_note_type' ), t2 AS ( - SELECT id FROM vocabularyterm WHERE name = 'HTP Expression Dataset Summary' AND vocabulary_id = ( + SELECT id FROM vocabularyterm WHERE name = 'htp_expression_dataset_summary' AND vocabulary_id = ( SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' ) ) @@ -65,7 +65,7 @@ INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_sample_note_type' ), t2 AS ( - SELECT id FROM vocabularyterm WHERE name = 'HTP Expression Dataset Sample Note' AND vocabulary_id = ( + SELECT id FROM vocabularyterm WHERE name = 'htp_expression_dataset_sample_note' AND vocabulary_id = ( SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' ) ) From bc408ff7b4004d1220d9e0e21fcc0578fafd75dd Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Tue, 16 Jul 2024 08:37:00 -0500 Subject: [PATCH 54/82] Changed the version of the migration file --- ...dataset.sql => v0.36.0.5__highthroughputexpressiondataset.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{v0.36.0.4__highthroughputexpressiondataset.sql => v0.36.0.5__highthroughputexpressiondataset.sql} (100%) diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql similarity index 100% rename from src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql rename to src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql From 58475774833a6d554e8a12922d60dfc0dc06bb93 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Tue, 16 Jul 2024 08:46:05 -0500 Subject: [PATCH 55/82] Changed the naming convention of vocabulary terms --- .../v0.36.0.5__highthroughputexpressiondataset.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql index a2fd4fef3..5ba060867 100644 --- a/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql +++ b/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql @@ -35,13 +35,13 @@ SELECT id, 'HTPDATASET', 'ZFIN' FROM bulkload WHERE name = 'ZFIN HTP Expression --Adding vocabulary terms INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'epigenome', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; -INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional genomics and proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; +INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional_genomics_and_proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'karyotyping', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_summary', 'Summary of the high-throughput expression dataset' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_sample_note', 'Note pertaining to a high-throughput expression dataset sample' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; -INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) +INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id) SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Note Type', 'htp_expression_dataset_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) @@ -56,7 +56,7 @@ INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms ) SELECT t1.id, t2.id FROM t1,t2; -INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) +INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id) SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Sample Note Type', 'htp_expression_dataset_sample_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) From 198d959087e8d9be732b9c3d295fb84ab8446d69 Mon Sep 17 00:00:00 2001 From: Varun Reddy <90427085+VarunReddy1111@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:01:37 -0500 Subject: [PATCH 56/82] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b825ef545..fb72a41d5 100644 --- a/README.md +++ b/README.md @@ -481,6 +481,7 @@ As the code goes through the different stages, it becomes more and more stable a * Incrementing the `MAJOR` or `MINOR` release numbers as appropriate when the previous release candidate was (or will be) promoted to a full release and reset to rc1 for the next release. + * When choosing an alpha release make sure to include the Pull Requests that may have fixed bugs shortly after the sprint review, if they needed to be included in beta release. 4. Create a release/v`x`.`y`.`z`-rc`a` branch from the commit on the alpha branch that was chosen earlier to be promoted. ```bash From 7f0051a8c959d77cedde90ff1839f4cc0ccc7656 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Tue, 16 Jul 2024 15:36:52 -0500 Subject: [PATCH 57/82] SCRUM-4188 add sqtr gene association tests --- ...gReagentGeneAssociationCrudController.java | 6 + ...SequenceTargetingReagentCrudInterface.java | 9 ++ ...ngReagentGeneAssociationCrudInterface.java | 14 ++- ...argetingReagentGeneAssociationService.java | 22 ++++ ...entGeneAssociationBulkUploadFmsITCase.java | 105 ++++++++++++++++++ .../curation_api/base/BaseITCase.java | 17 +++ .../AF_01_all_fields.json | 31 ++++++ .../IV_01_invalid_gene_ids.json | 31 ++++++ .../UE_01_update_empty_gene_ids.json | 29 +++++ 9 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java create mode 100644 src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/AF_01_all_fields.json create mode 100644 src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/IV_01_invalid_gene_ids.json create mode 100644 src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/UE_01_update_empty_gene_ids.json diff --git a/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java b/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java index 9823f666f..a6ad9b86a 100644 --- a/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java +++ b/src/main/java/org/alliancegenome/curation_api/controllers/crud/associations/SequenceTargetingReagentGeneAssociationCrudController.java @@ -5,6 +5,7 @@ import org.alliancegenome.curation_api.interfaces.crud.associations.SequenceTargetingReagentGeneAssociationCrudInterface; import org.alliancegenome.curation_api.jobs.executors.SequenceTargetingReagentExecutor; import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; +import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.services.associations.SequenceTargetingReagentGeneAssociationService; import jakarta.annotation.PostConstruct; @@ -23,4 +24,9 @@ public class SequenceTargetingReagentGeneAssociationCrudController extends protected void init() { setService(sequenceTargetingReagentGeneAssociationService); } + + @Override + public ObjectResponse getAssociation(Long sqtrId, String relationName, Long geneId) { + return sequenceTargetingReagentGeneAssociationService.getAssociation(sqtrId, relationName, geneId); + } } diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java index db9f22b12..da513eca4 100644 --- a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/SequenceTargetingReagentCrudInterface.java @@ -6,6 +6,7 @@ import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentIngestFmsDTO; import org.alliancegenome.curation_api.response.APIResponse; +import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.response.SearchResponse; import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; @@ -15,6 +16,7 @@ import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DefaultValue; +import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; @@ -46,4 +48,11 @@ public interface SequenceTargetingReagentCrudInterface extends BaseIdCrudInterfa @Tag(name = "Elastic Search Browsing Endpoints") @JsonView({ View.SequenceTargetingReagentView.class }) SearchResponse search(@DefaultValue("0") @QueryParam("page") Integer page, @DefaultValue("10") @QueryParam("limit") Integer limit, @RequestBody HashMap params); + + + @Override + @GET + @Path("/{id}") + @JsonView(View.SequenceTargetingReagentDetailView.class) + ObjectResponse getById(@PathParam("id") Long id); } diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java index 918543e49..38711f98a 100644 --- a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java @@ -1,17 +1,29 @@ package org.alliancegenome.curation_api.interfaces.crud.associations; import org.alliancegenome.curation_api.interfaces.base.BaseIdCrudInterface; +import org.alliancegenome.curation_api.model.entities.associations.alleleAssociations.AlleleGeneAssociation; import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.tags.Tag; +import com.fasterxml.jackson.annotation.JsonView; import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; @Path("/sqtrgeneassociation") @Tag(name = "CRUD - SQTR Gene Associations") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public interface SequenceTargetingReagentGeneAssociationCrudInterface extends BaseIdCrudInterface { } +public interface SequenceTargetingReagentGeneAssociationCrudInterface extends BaseIdCrudInterface { + + @GET + @Path("/findBy") + @JsonView(View.FieldsAndLists.class) + ObjectResponse getAssociation(@QueryParam("sqtrId") Long alleleId, @QueryParam("relationName") String relationName, @QueryParam("geneId") Long geneId); +} diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java index 5e9e002dd..5114bec77 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java @@ -13,8 +13,11 @@ import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; import org.alliancegenome.curation_api.model.entities.Gene; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; +import org.alliancegenome.curation_api.model.entities.associations.alleleAssociations.AlleleGeneAssociation; import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; +import org.alliancegenome.curation_api.response.ObjectResponse; +import org.alliancegenome.curation_api.response.SearchResponse; import org.alliancegenome.curation_api.services.base.BaseEntityCrudService; import org.alliancegenome.curation_api.services.validation.associations.SequenceTargetingReagentGeneAssociationFmsDTOValidator; @@ -101,4 +104,23 @@ public List getIdsByDataProvider(BackendBulkDataProvider dataProvider) { return ids; } + public ObjectResponse getAssociation(Long sqtrId, String relationName, Long geneId) { + SequenceTargetingReagentGeneAssociation association = null; + + Map params = new HashMap<>(); + params.put("sequenceTargetingReagentAssociationSubject.id", sqtrId); + params.put("relation.name", relationName); + params.put("sequenceTargetingReagentGeneAssociationObject.id", geneId); + + SearchResponse resp = sequenceTargetingReagentGeneAssociationDAO.findByParams(params); + if (resp != null && resp.getSingleResult() != null) { + association = resp.getSingleResult(); + } + + ObjectResponse response = new ObjectResponse<>(); + response.setEntity(association); + + return response; + } + } diff --git a/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java new file mode 100644 index 000000000..6d9bbeb7b --- /dev/null +++ b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java @@ -0,0 +1,105 @@ +package org.alliancegenome.curation_api; + +import static org.hamcrest.Matchers.hasKey; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; + +import org.alliancegenome.curation_api.base.BaseITCase; +import org.alliancegenome.curation_api.model.entities.Gene; +import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; +import org.alliancegenome.curation_api.model.entities.Vocabulary; +import org.alliancegenome.curation_api.model.entities.VocabularyTerm; +import org.alliancegenome.curation_api.resources.TestContainerResource; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestMethodOrder; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import io.restassured.RestAssured; + +@QuarkusIntegrationTest +@QuarkusTestResource(TestContainerResource.Initializer.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@DisplayName("609 - Sequence Targeting Reagent Gene Associations bulk upload") +@Order(609) +public class SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase extends BaseITCase { + + private Gene gene; + private SequenceTargetingReagent sqtr; + VocabularyTerm relation; + private String relationName = "targets"; + private String geneCurie = "GENETEST:Gene0001"; + private String sqtrId = "83"; + private String sqtrModEntityId = "ZFIN:ZDB-TALEN-180503-1"; + + private final String sqtrGeneAssociationGetEndpoint = "/api/sqtrgeneassociation/findBy"; + private final String sqtrGeneAssociationTestFilePath = "src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/"; + private final String geneGetEndpoint = "/api/gene/"; + private final String sqtrGetEndpoint = "/api/sqtr/"; + + private final String sqtrBulkPostEndpoint = "/api/sqtr/bulk/ZFIN/sqtrfile"; + + private void loadRequiredEntities() throws Exception { + Vocabulary noteTypeVocab = getVocabulary("construct_relation"); + relation = getVocabularyTerm(noteTypeVocab, relationName); + gene = getGene(geneCurie); + sqtr = getSequenceTargetingReagent(sqtrId); + } + + @Test + @Order(1) + public void sqtrGeneAssociationBulkUploadCheckFields() throws Exception { + loadRequiredEntities(); + + checkSuccessfulBulkLoad(sqtrBulkPostEndpoint, sqtrGeneAssociationTestFilePath + "AF_01_all_fields.json", 2); + + RestAssured.given(). + when(). + get(sqtrGeneAssociationGetEndpoint + "?sqtrId=" + sqtr.getId() + "&relationName=" + relationName + "&geneId=" + gene.getId()). + then(). + statusCode(200). + body("entity.relation.name", is(relationName)). + body("entity.sequenceTargetingReagentGeneAssociationObject.modEntityId", is(geneCurie)). + body("entity.sequenceTargetingReagentAssociationSubject.modEntityId", is(sqtrModEntityId)); + + RestAssured.given(). + when(). + get(sqtrGetEndpoint + sqtrId). + then(). + statusCode(200). + body("entity.sequenceTargetingReagentGeneAssociations", hasSize(1)). + body("entity.sequenceTargetingReagentGeneAssociations[0].relation.name", is(relationName)). + body("entity.sequenceTargetingReagentGeneAssociations[0].sequenceTargetingReagentGeneAssociationObject.modEntityId", is(geneCurie)). + body("entity.sequenceTargetingReagentGeneAssociations[0].sequenceTargetingReagentAssociationSubject", not(hasKey("sequenceTargetingReagentGeneAssociations"))); + + RestAssured.given(). + when(). + get(geneGetEndpoint + geneCurie). + then(). + statusCode(200). + body("entity.sequenceTargetingReagentGeneAssociations", hasSize(1)). + body("entity.sequenceTargetingReagentGeneAssociations[0].relation.name", is(relationName)). + body("entity.sequenceTargetingReagentGeneAssociations[0].sequenceTargetingReagentGeneAssociationObject.modEntityId", is(geneCurie)). + body("entity.sequenceTargetingReagentGeneAssociations[0].sequenceTargetingReagentGeneAssociationObject", not(hasKey("sequenceTargetingReagentGeneAssociations"))); + } + + @Test + @Order(2) + public void sqtrGeneAssociationBulkUploadInvalidGenes() throws Exception { + checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrGeneAssociationTestFilePath + "IV_01_invalid_gene_ids.json", 2, 1, 1); + } + + @Test + @Order(3) + public void sqtrGeneAssociationBulkUploadMissingGenes() throws Exception { + checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrGeneAssociationTestFilePath + "UE_01_update_empty_gene_ids.json", 2, 0, 1); + } + + +} diff --git a/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java b/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java index 42c239537..b32949a87 100644 --- a/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/base/BaseITCase.java @@ -31,6 +31,7 @@ import org.alliancegenome.curation_api.model.entities.Reference; import org.alliancegenome.curation_api.model.entities.ResourceDescriptor; import org.alliancegenome.curation_api.model.entities.ResourceDescriptorPage; +import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; import org.alliancegenome.curation_api.model.entities.Variant; import org.alliancegenome.curation_api.model.entities.Vocabulary; import org.alliancegenome.curation_api.model.entities.VocabularyTerm; @@ -760,6 +761,17 @@ public Gene getGene(String identifier) { return res.getEntity(); } + public SequenceTargetingReagent getSequenceTargetingReagent(String identifier) { + ObjectResponse res = RestAssured.given(). + when(). + get("/api/sqtr/" + identifier). + then(). + statusCode(200). + extract().body().as(getObjectResponseTypeRefSequenceTargetingReagent()); + + return res.getEntity(); + } + public GeneDiseaseAnnotation getGeneDiseaseAnnotation(String uniqueId) { ObjectResponse res = RestAssured.given(). when(). @@ -893,6 +905,11 @@ private TypeRef> getObjectResponseTypeRefGene() { }; } + private TypeRef> getObjectResponseTypeRefSequenceTargetingReagent() { + return new TypeRef>() { + }; + } + private TypeRef> getObjectResponseTypeRefGeneDiseaseAnnotation() { return new TypeRef>() { }; diff --git a/src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/AF_01_all_fields.json b/src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/AF_01_all_fields.json new file mode 100644 index 000000000..0cb3a1365 --- /dev/null +++ b/src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/AF_01_all_fields.json @@ -0,0 +1,31 @@ +{ + "data": [ + { + "primaryId": "ZFIN:ZDB-TALEN-180503-1", + "name": "TALEN-inhbaa", + "soTermId": "SO:0000059", + "taxonId": "NCBITaxon:7955", + "synonyms": [ + "#4" + ], + "secondaryIds": [ + "ZFIN:ZDB-MRKRSEQ-100429-7" + ], + "targetGeneIds": [ + "GENETEST:Gene0001" + ] + } + ], + "metaData": { + "dateProduced": "2024-04-18T20:10:35-07:00", + "dataProvider": { + "crossReference": { + "id": "ZFIN", + "pages": [ + "homepage" + ] + }, + "type": "curated" + } + } +} \ No newline at end of file diff --git a/src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/IV_01_invalid_gene_ids.json b/src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/IV_01_invalid_gene_ids.json new file mode 100644 index 000000000..4b088b391 --- /dev/null +++ b/src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/IV_01_invalid_gene_ids.json @@ -0,0 +1,31 @@ +{ + "data": [ + { + "primaryId": "ZFIN:ZDB-TALEN-180503-1", + "name": "TALEN-inhbaa", + "soTermId": "SO:0000059", + "taxonId": "NCBITaxon:7955", + "synonyms": [ + "#4" + ], + "secondaryIds": [ + "ZFIN:ZDB-MRKRSEQ-100429-7" + ], + "targetGeneIds": [ + "GENETEST:GeneInvalid0001" + ] + } + ], + "metaData": { + "dateProduced": "2024-04-18T20:10:35-07:00", + "dataProvider": { + "crossReference": { + "id": "ZFIN", + "pages": [ + "homepage" + ] + }, + "type": "curated" + } + } +} \ No newline at end of file diff --git a/src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/UE_01_update_empty_gene_ids.json b/src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/UE_01_update_empty_gene_ids.json new file mode 100644 index 000000000..4acb0a2ba --- /dev/null +++ b/src/test/resources/bulk/fms/SA01_sequencetargetingreagent_gene_association/UE_01_update_empty_gene_ids.json @@ -0,0 +1,29 @@ +{ + "data": [ + { + "primaryId": "ZFIN:ZDB-TALEN-180503-1", + "name": "TALEN-inhbaa", + "soTermId": "SO:0000059", + "taxonId": "NCBITaxon:7955", + "synonyms": [ + "#4" + ], + "secondaryIds": [ + "ZFIN:ZDB-MRKRSEQ-100429-7" + ], + "targetGeneIds": [] + } + ], + "metaData": { + "dateProduced": "2024-04-18T20:10:35-07:00", + "dataProvider": { + "crossReference": { + "id": "ZFIN", + "pages": [ + "homepage" + ] + }, + "type": "curated" + } + } +} \ No newline at end of file From 3cc30106249561c0a7545f984cc1ae4639391741 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Tue, 16 Jul 2024 15:39:25 -0500 Subject: [PATCH 58/82] SCRUM-4188 checkstyle formatting --- ...enceTargetingReagentGeneAssociationCrudInterface.java | 9 ++++----- .../SequenceTargetingReagentGeneAssociationService.java | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java index 38711f98a..2f6964dad 100644 --- a/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java +++ b/src/main/java/org/alliancegenome/curation_api/interfaces/crud/associations/SequenceTargetingReagentGeneAssociationCrudInterface.java @@ -1,7 +1,6 @@ package org.alliancegenome.curation_api.interfaces.crud.associations; import org.alliancegenome.curation_api.interfaces.base.BaseIdCrudInterface; -import org.alliancegenome.curation_api.model.entities.associations.alleleAssociations.AlleleGeneAssociation; import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.response.ObjectResponse; import org.alliancegenome.curation_api.view.View; @@ -22,8 +21,8 @@ @Consumes(MediaType.APPLICATION_JSON) public interface SequenceTargetingReagentGeneAssociationCrudInterface extends BaseIdCrudInterface { - @GET - @Path("/findBy") - @JsonView(View.FieldsAndLists.class) - ObjectResponse getAssociation(@QueryParam("sqtrId") Long alleleId, @QueryParam("relationName") String relationName, @QueryParam("geneId") Long geneId); + @GET + @Path("/findBy") + @JsonView(View.FieldsAndLists.class) + ObjectResponse getAssociation(@QueryParam("sqtrId") Long alleleId, @QueryParam("relationName") String relationName, @QueryParam("geneId") Long geneId); } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java index 5114bec77..feeef193a 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/SequenceTargetingReagentGeneAssociationService.java @@ -13,7 +13,6 @@ import org.alliancegenome.curation_api.exceptions.ObjectUpdateException; import org.alliancegenome.curation_api.model.entities.Gene; import org.alliancegenome.curation_api.model.entities.SequenceTargetingReagent; -import org.alliancegenome.curation_api.model.entities.associations.alleleAssociations.AlleleGeneAssociation; import org.alliancegenome.curation_api.model.entities.associations.sequenceTargetingReagentAssociations.SequenceTargetingReagentGeneAssociation; import org.alliancegenome.curation_api.model.ingest.dto.fms.SequenceTargetingReagentFmsDTO; import org.alliancegenome.curation_api.response.ObjectResponse; From e42c3079cc42bc4fe7752ff85d4cdd56357f0511 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Tue, 16 Jul 2024 22:05:58 +0100 Subject: [PATCH 59/82] Remove unnecessary @RequestScoped --- .../services/helpers/gff3/Gff3AttributesHelper.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3AttributesHelper.java b/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3AttributesHelper.java index ee5765a29..50239d962 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3AttributesHelper.java +++ b/src/main/java/org/alliancegenome/curation_api/services/helpers/gff3/Gff3AttributesHelper.java @@ -9,9 +9,6 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import jakarta.enterprise.context.RequestScoped; - -@RequestScoped public class Gff3AttributesHelper { public static Map getAttributes(Gff3DTO dto, BackendBulkDataProvider dataProvider) { From ba2c92a6427bad966bc8743742cd8ba4dc78857a Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Wed, 17 Jul 2024 08:05:19 -0500 Subject: [PATCH 60/82] SCRUM-4188 update completed records exepected count --- ...nceTargetingReagentGeneAssociationBulkUploadFmsITCase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java index 6d9bbeb7b..ed5460ac0 100644 --- a/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java @@ -32,7 +32,7 @@ public class SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase extends private Gene gene; private SequenceTargetingReagent sqtr; - VocabularyTerm relation; + private VocabularyTerm relation; private String relationName = "targets"; private String geneCurie = "GENETEST:Gene0001"; private String sqtrId = "83"; @@ -98,7 +98,7 @@ public void sqtrGeneAssociationBulkUploadInvalidGenes() throws Exception { @Test @Order(3) public void sqtrGeneAssociationBulkUploadMissingGenes() throws Exception { - checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrGeneAssociationTestFilePath + "UE_01_update_empty_gene_ids.json", 2, 0, 1); + checkFailedBulkLoad(sqtrBulkPostEndpoint, sqtrGeneAssociationTestFilePath + "UE_01_update_empty_gene_ids.json", 2, 0, 2); } From 18490061a5b66a5096cb6745f346ea6116beca14 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Thu, 18 Jul 2024 13:51:25 +0100 Subject: [PATCH 61/82] Return assembly name so available for association loads --- .../curation_api/jobs/executors/Gff3Executor.java | 8 +++++--- .../alliancegenome/curation_api/services/Gff3Service.java | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java index aa7fa7938..794ef80ea 100644 --- a/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java +++ b/src/main/java/org/alliancegenome/curation_api/jobs/executors/Gff3Executor.java @@ -120,7 +120,7 @@ private Map> runLoad(BulkLoadFileHistory history, List gffHeaderData, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { + private String loadGenomeAssembly(String assemblyName, BulkLoadFileHistory history, List gffHeaderData, BackendBulkDataProvider dataProvider, ProcessDisplayHelper ph) { try { - gff3Service.loadGenomeAssembly(assemblyName, gffHeaderData, dataProvider); + assemblyName = gff3Service.loadGenomeAssembly(assemblyName, gffHeaderData, dataProvider); history.incrementCompleted(); } catch (ObjectUpdateException e) { history.incrementFailed(); @@ -157,6 +157,8 @@ private void loadGenomeAssembly(String assemblyName, BulkLoadFileHistory history } updateHistory(history); ph.progressProcess(); + + return assemblyName; } private Map> loadEntities(BulkLoadFileHistory history, List gffData, Map> idsAdded, diff --git a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java index 6256b6613..69d86ef4d 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java +++ b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java @@ -52,7 +52,7 @@ public class Gff3Service { @Inject Gff3DtoValidator gff3DtoValidator; @Transactional - public void loadGenomeAssembly(String assemblyName, List gffHeaderData, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { + public String loadGenomeAssembly(String assemblyName, List gffHeaderData, BackendBulkDataProvider dataProvider) throws ObjectUpdateException { if (StringUtils.isBlank(assemblyName)) { for (String header : gffHeaderData) { @@ -76,6 +76,8 @@ public void loadGenomeAssembly(String assemblyName, List gffHeaderData, genomeAssemblyDAO.persist(assembly); } + + return assemblyName; } else { throw new ObjectValidationException(gffHeaderData, "#!assembly - " + ValidationConstants.REQUIRED_MESSAGE); } @@ -106,7 +108,7 @@ public Map> loadEntity(BulkLoadFileHistory history, Gff3DTO g @Transactional public Map> loadAssociations(BulkLoadFileHistory history, Gff3DTO gffEntry, Map> idsAdded, BackendBulkDataProvider dataProvider, String assemblyId) throws ObjectUpdateException { - if (StringUtils.isEmpty(assemblyId)) { + if (StringUtils.isBlank(assemblyId)) { throw new ObjectValidationException(gffEntry, "Cannot load associations without assembly"); } From 944c076d5211fc20939e0991211b4023f0bc2d5a Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Fri, 19 Jul 2024 09:42:10 +0100 Subject: [PATCH 62/82] Remove reverse associations --- .../model/entities/AssemblyComponent.java | 21 +------------------ ...ingSequenceGenomicLocationAssociation.java | 8 +++---- .../ExonGenomicLocationAssociation.java | 8 +++---- .../TranscriptGenomicLocationAssociation.java | 8 +++---- .../curation_api/services/Gff3Service.java | 6 +++--- ...enceGenomicLocationAssociationService.java | 16 +------------- ...ExonGenomicLocationAssociationService.java | 16 +------------- ...riptGenomicLocationAssociationService.java | 16 +------------- 8 files changed, 16 insertions(+), 83 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java b/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java index 018cc8c9e..862c73da6 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/AssemblyComponent.java @@ -1,12 +1,7 @@ package org.alliancegenome.curation_api.model.entities; -import java.util.List; - import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; -import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; -import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; -import org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations.TranscriptGenomicLocationAssociation; import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; @@ -16,11 +11,9 @@ import com.fasterxml.jackson.annotation.JsonView; -import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; import jakarta.persistence.Index; import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; @@ -30,7 +23,7 @@ @Entity @Data @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) -@ToString(exclude = {"transcriptGenomicLocationAssociations", "exonGenomicLocationAssociations", "codingSequenceGenomicLocationAssociations"}, callSuper = true) +@ToString(callSuper = true) @Schema(name = "AssemblyComponent", description = "POJO that represents the AssemblyComponent") @AGRCurationSchemaVersion(min = "2.4.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { GenomicEntity.class }) @Table( @@ -54,17 +47,5 @@ public class AssemblyComponent extends GenomicEntity { @ManyToOne @JsonView({ View.FieldsOnly.class }) private Chromosome mapsToChromosome; - - @OneToMany(mappedBy = "transcriptGenomicLocationAssociationObject", cascade = CascadeType.ALL, orphanRemoval = true) - @JsonView({ View.FieldsAndLists.class }) - private List transcriptGenomicLocationAssociations; - - @OneToMany(mappedBy = "exonGenomicLocationAssociationObject", cascade = CascadeType.ALL, orphanRemoval = true) - @JsonView({ View.FieldsAndLists.class }) - private List exonGenomicLocationAssociations; - - @OneToMany(mappedBy = "codingSequenceGenomicLocationAssociationObject", cascade = CascadeType.ALL, orphanRemoval = true) - @JsonView({ View.FieldsAndLists.class }) - private List codingSequenceGenomicLocationAssociations; } diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java index 0d15a045b..322734ab5 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociation.java @@ -13,9 +13,11 @@ import org.hibernate.search.engine.backend.types.Projectable; import org.hibernate.search.engine.backend.types.Searchable; import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -61,11 +63,7 @@ public class CodingSequenceGenomicLocationAssociation extends LocationAssociatio }) @ManyToOne @JsonView({ View.FieldsOnly.class }) - @JsonIgnoreProperties({ - "codingSequenceGenomicLocationAssociations", - "exonGenomicLocationAssociations", - "transcriptGenomicLocationAssociations" - }) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @Fetch(FetchMode.JOIN) private AssemblyComponent codingSequenceGenomicLocationAssociationObject; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java index 3cc57e566..7db787478 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/exonAssociations/ExonGenomicLocationAssociation.java @@ -12,8 +12,10 @@ import org.hibernate.search.engine.backend.types.Aggregable; import org.hibernate.search.engine.backend.types.Searchable; import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -59,11 +61,7 @@ public class ExonGenomicLocationAssociation extends LocationAssociation { }) @ManyToOne @JsonView({ View.FieldsOnly.class }) - @JsonIgnoreProperties({ - "codingSequenceGenomicLocationAssociations", - "exonGenomicLocationAssociations", - "transcriptGenomicLocationAssociations" - }) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @Fetch(FetchMode.JOIN) private AssemblyComponent exonGenomicLocationAssociationObject; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java index 8f4558793..0669ae276 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/associations/transcriptAssociations/TranscriptGenomicLocationAssociation.java @@ -13,9 +13,11 @@ import org.hibernate.search.engine.backend.types.Projectable; import org.hibernate.search.engine.backend.types.Searchable; import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -61,11 +63,7 @@ public class TranscriptGenomicLocationAssociation extends LocationAssociation { }) @ManyToOne @JsonView({ View.FieldsOnly.class }) - @JsonIgnoreProperties({ - "codingSequenceGenomicLocationAssociations", - "exonGenomicLocationAssociations", - "transcriptGenomicLocationAssociations" - }) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @Fetch(FetchMode.JOIN) private AssemblyComponent transcriptGenomicLocationAssociationObject; diff --git a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java index 69d86ef4d..0de400d57 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java +++ b/src/main/java/org/alliancegenome/curation_api/services/Gff3Service.java @@ -124,7 +124,7 @@ public Map> loadAssociations(BulkLoadFileHistory history, Gff ExonGenomicLocationAssociation exonLocation = gff3DtoValidator.validateExonLocation(gffEntry, exon, assemblyId, dataProvider); if (exonLocation != null) { idsAdded.get("ExonGenomicLocationAssociation").add(exonLocation.getId()); - exonLocationService.addAssociationToSubjectAndObject(exonLocation); + exonLocationService.addAssociationToSubject(exonLocation); } } else if (StringUtils.equals(gffEntry.getType(), "CDS")) { String uniqueId = Gff3UniqueIdHelper.getExonOrCodingSequenceUniqueId(gffEntry, attributes, dataProvider); @@ -136,7 +136,7 @@ public Map> loadAssociations(BulkLoadFileHistory history, Gff CodingSequenceGenomicLocationAssociation cdsLocation = gff3DtoValidator.validateCdsLocation(gffEntry, cds, assemblyId, dataProvider); if (cdsLocation != null) { idsAdded.get("CodingSequenceGenomicLocationAssociation").add(cdsLocation.getId()); - cdsLocationService.addAssociationToSubjectAndObject(cdsLocation); + cdsLocationService.addAssociationToSubject(cdsLocation); } } else if (Gff3Constants.TRANSCRIPT_TYPES.contains(gffEntry.getType())) { if (StringUtils.equals(gffEntry.getType(), "lnc_RNA")) { @@ -153,7 +153,7 @@ public Map> loadAssociations(BulkLoadFileHistory history, Gff TranscriptGenomicLocationAssociation transcriptLocation = gff3DtoValidator.validateTranscriptLocation(gffEntry, transcript, assemblyId, dataProvider); if (transcriptLocation != null) { idsAdded.get("TranscriptGenomicLocationAssociation").add(transcriptLocation.getId()); - transcriptLocationService.addAssociationToSubjectAndObject(transcriptLocation); + transcriptLocationService.addAssociationToSubject(transcriptLocation); } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java index 4eb4ac33d..2bc0c88b1 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java @@ -103,7 +103,7 @@ public ObjectResponse getLocationAssoc return response; } - public void addAssociationToSubjectAndObject(CodingSequenceGenomicLocationAssociation association) { + public void addAssociationToSubject(CodingSequenceGenomicLocationAssociation association) { CodingSequence cds = association.getCodingSequenceAssociationSubject(); List currentSubjectAssociations = cds.getCodingSequenceGenomicLocationAssociations(); @@ -117,19 +117,5 @@ public void addAssociationToSubjectAndObject(CodingSequenceGenomicLocationAssoci if (!currentSubjectAssociationIds.contains(association.getId())) { currentSubjectAssociations.add(association); } - - AssemblyComponent assemblyComponent = association.getCodingSequenceGenomicLocationAssociationObject(); - - List currentObjectAssociations = assemblyComponent.getCodingSequenceGenomicLocationAssociations(); - if (currentObjectAssociations == null) { - currentObjectAssociations = new ArrayList<>(); - } - - List currentObjectAssociationIds = currentObjectAssociations.stream() - .map(CodingSequenceGenomicLocationAssociation::getId).collect(Collectors.toList()); - - if (!currentObjectAssociationIds.contains(association.getId())) { - currentObjectAssociations.add(association); - } } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java index c41861926..18b1957cd 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java @@ -103,7 +103,7 @@ public ObjectResponse getLocationAssociation(Lon return response; } - public void addAssociationToSubjectAndObject(ExonGenomicLocationAssociation association) { + public void addAssociationToSubject(ExonGenomicLocationAssociation association) { Exon exon = association.getExonAssociationSubject(); List currentSubjectAssociations = exon.getExonGenomicLocationAssociations(); @@ -117,19 +117,5 @@ public void addAssociationToSubjectAndObject(ExonGenomicLocationAssociation asso if (!currentSubjectAssociationIds.contains(association.getId())) { currentSubjectAssociations.add(association); } - - AssemblyComponent assemblyComponent = association.getExonGenomicLocationAssociationObject(); - - List currentObjectAssociations = assemblyComponent.getExonGenomicLocationAssociations(); - if (currentObjectAssociations == null) { - currentObjectAssociations = new ArrayList<>(); - } - - List currentObjectAssociationIds = currentObjectAssociations.stream() - .map(ExonGenomicLocationAssociation::getId).collect(Collectors.toList()); - - if (!currentObjectAssociationIds.contains(association.getId())) { - currentObjectAssociations.add(association); - } } } diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java index d4f06e2fe..758ef77e5 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java @@ -103,7 +103,7 @@ public ObjectResponse getLocationAssociati return response; } - public void addAssociationToSubjectAndObject(TranscriptGenomicLocationAssociation association) { + public void addAssociationToSubject(TranscriptGenomicLocationAssociation association) { Transcript transcript = association.getTranscriptAssociationSubject(); List currentSubjectAssociations = transcript.getTranscriptGenomicLocationAssociations(); @@ -117,19 +117,5 @@ public void addAssociationToSubjectAndObject(TranscriptGenomicLocationAssociatio if (!currentSubjectAssociationIds.contains(association.getId())) { currentSubjectAssociations.add(association); } - - AssemblyComponent assemblyComponent = association.getTranscriptGenomicLocationAssociationObject(); - - List currentObjectAssociations = assemblyComponent.getTranscriptGenomicLocationAssociations(); - if (currentObjectAssociations == null) { - currentObjectAssociations = new ArrayList<>(); - } - - List currentObjectAssociationIds = currentObjectAssociations.stream() - .map(TranscriptGenomicLocationAssociation::getId).collect(Collectors.toList()); - - if (!currentObjectAssociationIds.contains(association.getId())) { - currentObjectAssociations.add(association); - } } } From 2542437151cdfb023e0b5cd755cafd61657b57f0 Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Fri, 19 Jul 2024 09:49:14 +0100 Subject: [PATCH 63/82] Remove unused imports --- .../CodingSequenceGenomicLocationAssociationService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java index 2bc0c88b1..e817435c9 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/codingSequenceAssociations/CodingSequenceGenomicLocationAssociationService.java @@ -13,7 +13,6 @@ import org.alliancegenome.curation_api.dao.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociationDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ApiErrorException; -import org.alliancegenome.curation_api.model.entities.AssemblyComponent; import org.alliancegenome.curation_api.model.entities.CodingSequence; import org.alliancegenome.curation_api.model.entities.associations.codingSequenceAssociations.CodingSequenceGenomicLocationAssociation; import org.alliancegenome.curation_api.response.ObjectResponse; From ba8426e98b808e453658752cbc60abf2074cdc6c Mon Sep 17 00:00:00 2001 From: markquintontulloch Date: Fri, 19 Jul 2024 09:57:03 +0100 Subject: [PATCH 64/82] Remove more unusued imports --- .../exonAssociations/ExonGenomicLocationAssociationService.java | 1 - .../TranscriptGenomicLocationAssociationService.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java index 18b1957cd..49b3c6c02 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/exonAssociations/ExonGenomicLocationAssociationService.java @@ -13,7 +13,6 @@ import org.alliancegenome.curation_api.dao.associations.exonAssociations.ExonGenomicLocationAssociationDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ApiErrorException; -import org.alliancegenome.curation_api.model.entities.AssemblyComponent; import org.alliancegenome.curation_api.model.entities.Exon; import org.alliancegenome.curation_api.model.entities.associations.exonAssociations.ExonGenomicLocationAssociation; import org.alliancegenome.curation_api.response.ObjectResponse; diff --git a/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java b/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java index 758ef77e5..9160786f6 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java +++ b/src/main/java/org/alliancegenome/curation_api/services/associations/transcriptAssociations/TranscriptGenomicLocationAssociationService.java @@ -13,7 +13,6 @@ import org.alliancegenome.curation_api.dao.associations.transcriptAssociations.TranscriptGenomicLocationAssociationDAO; import org.alliancegenome.curation_api.enums.BackendBulkDataProvider; import org.alliancegenome.curation_api.exceptions.ApiErrorException; -import org.alliancegenome.curation_api.model.entities.AssemblyComponent; import org.alliancegenome.curation_api.model.entities.Transcript; import org.alliancegenome.curation_api.model.entities.associations.transcriptAssociations.TranscriptGenomicLocationAssociation; import org.alliancegenome.curation_api.response.ObjectResponse; From c312d633b7688bb6d1b9df4b03cd10ba41b37c06 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Wed, 24 Jul 2024 10:22:58 -0500 Subject: [PATCH 65/82] Replaced structural reasoner with ELK reasoner --- pom.xml | 8 +++++++- .../services/helpers/GenericOntologyLoadHelper.java | 6 ++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 0600e13b4..eb73d83ac 100644 --- a/pom.xml +++ b/pom.xml @@ -120,7 +120,13 @@ net.sourceforge.owlapi owlapi-distribution - 5.1.19 + 5.5.0 + + + + io.github.liveontologies + elk-owlapi + 0.6.0 diff --git a/src/main/java/org/alliancegenome/curation_api/services/helpers/GenericOntologyLoadHelper.java b/src/main/java/org/alliancegenome/curation_api/services/helpers/GenericOntologyLoadHelper.java index f4ecd55e5..05e8e35c1 100644 --- a/src/main/java/org/alliancegenome/curation_api/services/helpers/GenericOntologyLoadHelper.java +++ b/src/main/java/org/alliancegenome/curation_api/services/helpers/GenericOntologyLoadHelper.java @@ -29,16 +29,14 @@ import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLOntologyManager; import org.semanticweb.owlapi.reasoner.OWLReasoner; -import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; -import org.semanticweb.owlapi.reasoner.structural.StructuralReasonerFactory; import org.semanticweb.owlapi.search.EntitySearcher; +import org.semanticweb.elk.owlapi.ElkReasonerFactory; import io.quarkus.logging.Log; public class GenericOntologyLoadHelper implements OWLObjectVisitor { - private OWLReasonerFactory reasonerFactory = new StructuralReasonerFactory(); - // private OWLDataFactory df = OWLManager.getOWLDataFactory(); + private ElkReasonerFactory reasonerFactory = new ElkReasonerFactory(); private OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); private OWLReasoner reasoner; private OWLOntology ontology; From bbebddb64acd069d87b42665f920e1ef875a6819 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Wed, 24 Jul 2024 12:30:22 -0500 Subject: [PATCH 66/82] skip SQTR Gene Association test for now --- ...uenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java index ed5460ac0..5c9bd1bf7 100644 --- a/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java +++ b/src/test/java/org/alliancegenome/curation_api/SequenceTargetingReagentGeneAssociationBulkUploadFmsITCase.java @@ -11,6 +11,7 @@ import org.alliancegenome.curation_api.model.entities.Vocabulary; import org.alliancegenome.curation_api.model.entities.VocabularyTerm; import org.alliancegenome.curation_api.resources.TestContainerResource; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; @@ -22,6 +23,7 @@ import io.quarkus.test.junit.QuarkusIntegrationTest; import io.restassured.RestAssured; +@Disabled @QuarkusIntegrationTest @QuarkusTestResource(TestContainerResource.Initializer.class) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) From 2b36e97f24bf868819ed03bc0cf71d4c99f0c0a8 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Wed, 24 Jul 2024 09:07:11 -0500 Subject: [PATCH 67/82] SCRUM-4277 added obsolete filtering to all mod settings --- .../cliapp/src/service/TableStateService.js | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/main/cliapp/src/service/TableStateService.js b/src/main/cliapp/src/service/TableStateService.js index 0447627f1..037504ab2 100644 --- a/src/main/cliapp/src/service/TableStateService.js +++ b/src/main/cliapp/src/service/TableStateService.js @@ -47,6 +47,9 @@ const modTableSettings = { 'dataProvider.sourceOrganization.fullName': { queryString: 'RGD', tokenOperator: 'AND' }, 'dataProvider.sourceOrganization.shortName': { queryString: 'RGD', tokenOperator: 'AND' }, }, + obsoleteFilter: { + obsolete: { queryString: 'false' }, + }, }, tableKeyName: 'DiseaseAnnotations', tableSettingsKeyName: 'DiseaseAnnotationsTableSettings', @@ -93,6 +96,9 @@ const modTableSettings = { 'dataProvider.sourceOrganization.fullName': { queryString: 'SGD', tokenOperator: 'AND' }, 'dataProvider.sourceOrganization.shortName': { queryString: 'SGD', tokenOperator: 'AND' }, }, + obsoleteFilter: { + obsolete: { queryString: 'false' }, + }, }, tableKeyName: 'DiseaseAnnotations', tableSettingsKeyName: 'DiseaseAnnotationsTableSettings', @@ -103,14 +109,6 @@ const modTableSettings = { page: 0, rows: 50, first: 0, - filters: { - dataProviderFilter: { - 'dataProvider.sourceOrganization.abbreviation': { queryString: 'WB', tokenOperator: 'AND' }, - 'dataProvider.sourceOrganization.fullName': { queryString: 'WB', tokenOperator: 'AND' }, - 'dataProvider.sourceOrganization.shortName': { queryString: 'WB', tokenOperator: 'AND' }, - }, - }, - tableKeyName: 'DiseaseAnnotations', multiSortMeta: [{ field: 'dateCreated', order: -1 }], selectedColumnNames: [ 'MOD Annotation ID', @@ -148,6 +146,17 @@ const modTableSettings = { 'Genetic Modifiers', 'Asserted Genes', ], + filters: { + dataProviderFilter: { + 'dataProvider.sourceOrganization.abbreviation': { queryString: 'WB', tokenOperator: 'AND' }, + 'dataProvider.sourceOrganization.fullName': { queryString: 'WB', tokenOperator: 'AND' }, + 'dataProvider.sourceOrganization.shortName': { queryString: 'WB', tokenOperator: 'AND' }, + }, + obsoleteFilter: { + obsolete: { queryString: 'false' }, + }, + }, + tableKeyName: 'DiseaseAnnotations', tableSettingsKeyName: 'DiseaseAnnotationsTableSettings', }, }, @@ -187,14 +196,14 @@ const modTableSettings = { 'Genetic Modifiers', ], filters: { - obsoleteFilter: { - obsolete: { queryString: 'false' }, - }, dataProviderFilter: { 'dataProvider.sourceOrganization.abbreviation': { queryString: 'FB', tokenOperator: 'AND' }, 'dataProvider.sourceOrganization.fullName': { queryString: 'FB', tokenOperator: 'AND' }, 'dataProvider.sourceOrganization.shortName': { queryString: 'FB', tokenOperator: 'AND' }, }, + obsoleteFilter: { + obsolete: { queryString: 'false' }, + }, }, tableKeyName: 'DiseaseAnnotations', tableSettingsKeyName: 'DiseaseAnnotationsTableSettings', @@ -229,6 +238,9 @@ const modTableSettings = { 'dataProvider.sourceOrganization.fullName': { queryString: 'ZFIN', tokenOperator: 'AND' }, 'dataProvider.sourceOrganization.shortName': { queryString: 'ZFIN', tokenOperator: 'AND' }, }, + obsoleteFilter: { + obsolete: { queryString: 'false' }, + }, }, tableKeyName: 'DiseaseAnnotations', tableSettingsKeyName: 'DiseaseAnnotationsTableSettings', @@ -269,6 +281,9 @@ const modTableSettings = { 'dataProvider.sourceOrganization.fullName': { queryString: 'ZFIN', tokenOperator: 'AND' }, 'dataProvider.sourceOrganization.shortName': { queryString: 'ZFIN', tokenOperator: 'AND' }, }, + obsoleteFilter: { + obsolete: { queryString: 'false' }, + }, }, tableKeyName: 'DiseaseAnnotations', tableSettingsKeyName: 'DiseaseAnnotationsTableSettings', From aafab688fcea2704f7eafa16aac4e91b75f0a230 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Thu, 25 Jul 2024 15:31:05 -0500 Subject: [PATCH 68/82] SCRUM-4277 add filter to default mod --- src/main/cliapp/src/service/TableStateService.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/cliapp/src/service/TableStateService.js b/src/main/cliapp/src/service/TableStateService.js index 0447627f1..f3cdc1943 100644 --- a/src/main/cliapp/src/service/TableStateService.js +++ b/src/main/cliapp/src/service/TableStateService.js @@ -375,7 +375,11 @@ const modTableSettings = { 'Genetic Modifiers', 'Internal', ], - filters: {}, + filters: { + obsoleteFilter: { + obsolete: { queryString: 'false' }, + }, + }, tableKeyName: 'DiseaseAnnotations', tableSettingsKeyName: 'DiseaseAnnotationsTableSettings', }, From b687b2a37716fc35f21052ae0b004b57832feb6b Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Thu, 11 Jul 2024 22:30:19 -0500 Subject: [PATCH 69/82] Adding HTPexpressiondataset entities --- .../cliapp/src/service/DataLoadService.js | 1 + .../enums/BackendBulkLoadType.java | 3 +- ...ThroughputExpressionDatasetAnnotation.java | 60 ++++++++++ ...6.0.4__highthroughputexpressiondataset.sql | 103 ++++++++++++++++++ 4 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java create mode 100644 src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql diff --git a/src/main/cliapp/src/service/DataLoadService.js b/src/main/cliapp/src/service/DataLoadService.js index 5e5b729fc..c361e810e 100644 --- a/src/main/cliapp/src/service/DataLoadService.js +++ b/src/main/cliapp/src/service/DataLoadService.js @@ -81,6 +81,7 @@ export class DataLoadService extends BaseAuthService { const bulkLoadTypes = { BulkFMSLoad: [ 'GFF', + 'HTP EXPRESSION DATASET ANNOTATION', 'INTERACTION-GEN', 'INTERACTION-MOL', 'MOLECULE', diff --git a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java index 9172530be..119aef824 100644 --- a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java +++ b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java @@ -23,7 +23,8 @@ public enum BackendBulkLoadType { INTERACTION_GEN("tsv"), PARALOGY("json"), SEQUENCE_TARGETING_REAGENT("json"), - EXPRESSION("json"); + EXPRESSION("json"), + HTP_EXPRESSION_DATASET_ANNOTATION("json"); public String fileExtension; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java new file mode 100644 index 000000000..f16dbd1a8 --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -0,0 +1,60 @@ +package org.alliancegenome.curation_api.model.entities; + +import java.util.List; + +import org.alliancegenome.curation_api.model.entities.base.SubmittedObject; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Indexed +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@Schema(name = "HighThroughputExpressionDatasetAnnotation", description = "POJO that represents the HighThroughputExpressionDatasetAnnotation") +public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject{ + + @JsonView({ View.FieldsOnly.class }) + private String name; + + @IndexedEmbedded(includePaths = {"curie", "primaryCrossReferenceCurie", "crossReferences.referencedCurie", "curie_keyword", "primaryCrossReferenceCurie_keyword", "crossReferences.referencedCurie_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToMany + @Fetch(FetchMode.JOIN) + @JoinTable(indexes = { + @Index(name = "htpdatasetannotation_reference_htpdataset_index", columnList = "highthroughputexpressiondatasetannotation_id"), + @Index(name = "htpdatasetannotation_reference_references_index", columnList = "references_id") + }) + @JsonView({ View.FieldsAndLists.class }) + private List references; + + @JsonView({ View.FieldsOnly.class }) + private String realtedNote; + + @JsonView({ View.FieldsOnly.class }) + private Integer numberOfChannels; + + @IndexedEmbedded(includePaths = {"name", "name_keyword"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToMany + @JsonView({ View.FieldsAndLists.class }) + @JoinTable(name = "htpexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "highthroughputexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) + List categoryTags; + +} diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql new file mode 100644 index 000000000..605d58caa --- /dev/null +++ b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql @@ -0,0 +1,103 @@ +-- To create bulk loads + +INSERT INTO bulkloadgroup (id, name) VALUES (nextval('bulkloadgroup_seq'), 'HTP Expression Dataset Annotation Bulk Loads'); + +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'ZFIN HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'MGI HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'RGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'SGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) +SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; + +INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) +SELECT id, '0 0 22 ? * SUN-THU', false FROM bulkload WHERE backendbulkloadtype = 'HTP_EXPRESSION_DATASET_ANNOTATION'; + +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB' FROM bulkload WHERE name = 'FB HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'MGI' FROM bulkload WHERE name = 'MGI HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'RGD' FROM bulkload WHERE name = 'RGD HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'SGD' FROM bulkload WHERE name = 'SGD HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB' FROM bulkload WHERE name = 'WB HTP Expression Dataset Annotation Load'; +INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) +SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'ZFIN' FROM bulkload WHERE name = 'ZFIN HTP Expression Dataset Annotation Load'; + + +--Adding 3 extra vocabulary terms for HTPTags + +INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'epigenome', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; +INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional genomics and proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; +INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'karyotyping', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; + +-- Adding highthroughputexpressiondatasetannotation + +CREATE SEQUENCE highthroughputexpressiondatasetannotation_seq START WITH 1 INCREMENT BY 50 NO MINVALUE NO MAXVALUE CACHE 1; + +CREATE TABLE highthroughputexpressiondatasetannotation ( + id bigint NOT NULL, + datecreated timestamp(6) with time zone, + dateupdated timestamp(6) with time zone, + dbdatecreated timestamp(6) with time zone, + dbdateupdated timestamp(6) with time zone, + internal boolean DEFAULT false NOT NULL, + obsolete boolean DEFAULT false NOT NULL, + curie character varying(255), + modentityid character varying(255), + modinternalid character varying(255), + name character varying(255), + numberofchannels integer, + realtednote character varying(255), + createdby_id bigint, + updatedby_id bigint, + dataprovider_id bigint +); + +CREATE TABLE highthroughputexpressiondatasetannotation_categorytags ( + highthroughputexpressiondatasetannotation_id bigint NOT NULL, + categorytags_id bigint NOT NULL + ); + +CREATE TABLE highthroughputexpressiondatasetannotation_reference ( + highthroughputexpressiondatasetannotation_id bigint NOT NULL, + references_id bigint NOT NULL + ); + +ALTER TABLE highthroughputexpressiondatasetannotation ADD CONSTRAINT highthroughputexpressiondatasetannotation_pkey PRIMARY KEY (id); + +CREATE INDEX htpdatasetannotation_reference_htpdataset_index ON highthroughputexpressiondatasetannotation_reference USING btree (highthroughputexpressiondatasetannotation_id); + +CREATE INDEX htpdatasetannotation_reference_references_index ON highthroughputexpressiondatasetannotation_reference USING btree (references_id); + +CREATE INDEX htpdatasetannotation_categorytags_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (categorytags_id); + +CREATE INDEX htpdatasetannotation_htpdatasetid_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (highthroughputexpressiondatasetannotation_id); + +ALTER TABLE highthroughputexpressiondatasetannotation_categorytags + ADD CONSTRAINT highthroughputexpressiondatasetannotation_categorytags_highthroughputexpressiondatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); + +ALTER TABLE highthroughputexpressiondatasetannotation + ADD CONSTRAINT highthroughputexpressiondatasetannotation_dataprovider_id_fk FOREIGN KEY (dataprovider_id) REFERENCES dataprovider(id); + +ALTER TABLE highthroughputexpressiondatasetannotation_categorytags + ADD CONSTRAINT htpdatasetannotation_categorytags_categorytags_id_fk FOREIGN KEY (categorytags_id) REFERENCES vocabularyterm(id); + +ALTER TABLE highthroughputexpressiondatasetannotation_reference + ADD CONSTRAINT htpdatasetannotation_reference_htpdatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); + +ALTER TABLE highthroughputexpressiondatasetannotation_reference + ADD CONSTRAINT htpdatasetannotation_reference_references_id_fk FOREIGN KEY (references_id) REFERENCES reference(id); + +ALTER TABLE highthroughputexpressiondatasetannotation + ADD CONSTRAINT htpdatasetannotation_updatedby_id_fk FOREIGN KEY (updatedby_id) REFERENCES person(id); + +ALTER TABLE highthroughputexpressiondatasetannotation + ADD CONSTRAINT htpdatasetannotation_createdby_id_fk FOREIGN KEY (createdby_id) REFERENCES person(id); \ No newline at end of file From e061e77faade24a816a1a1e29fa7b9a1e2e31475 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Thu, 11 Jul 2024 22:39:46 -0500 Subject: [PATCH 70/82] Formatting --- ...ThroughputExpressionDatasetAnnotation.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java index f16dbd1a8..fd40d6e52 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -28,12 +28,12 @@ @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) @ToString(callSuper = true) @Schema(name = "HighThroughputExpressionDatasetAnnotation", description = "POJO that represents the HighThroughputExpressionDatasetAnnotation") -public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject{ +public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @JsonView({ View.FieldsOnly.class }) - private String name; + private String name; - @IndexedEmbedded(includePaths = {"curie", "primaryCrossReferenceCurie", "crossReferences.referencedCurie", "curie_keyword", "primaryCrossReferenceCurie_keyword", "crossReferences.referencedCurie_keyword"}) + @IndexedEmbedded(includePaths = {"curie", "primaryCrossReferenceCurie", "crossReferences.referencedCurie", "curie_keyword", "primaryCrossReferenceCurie_keyword", "crossReferences.referencedCurie_keyword"}) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @ManyToMany @Fetch(FetchMode.JOIN) @@ -44,17 +44,17 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject{ @JsonView({ View.FieldsAndLists.class }) private List references; - @JsonView({ View.FieldsOnly.class }) - private String realtedNote; + @JsonView({ View.FieldsOnly.class }) + private String realtedNote; - @JsonView({ View.FieldsOnly.class }) - private Integer numberOfChannels; + @JsonView({ View.FieldsOnly.class }) + private Integer numberOfChannels; - @IndexedEmbedded(includePaths = {"name", "name_keyword"}) + @IndexedEmbedded(includePaths = {"name", "name_keyword"}) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) - @ManyToMany - @JsonView({ View.FieldsAndLists.class }) + @ManyToMany + @JsonView({ View.FieldsAndLists.class }) @JoinTable(name = "htpexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "highthroughputexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) - List categoryTags; + List categoryTags; } From 4f2460bbc2dcfeda8b0b04b9c9f69f9c5ccb2863 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Fri, 12 Jul 2024 11:50:57 -0500 Subject: [PATCH 71/82] Note class used instead of string for related note --- .../cliapp/src/service/DataLoadService.js | 2 +- ...ThroughputExpressionDatasetAnnotation.java | 19 +++++++++++++++++-- ...6.0.4__highthroughputexpressiondataset.sql | 7 +++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/cliapp/src/service/DataLoadService.js b/src/main/cliapp/src/service/DataLoadService.js index c361e810e..8eaf6fb4a 100644 --- a/src/main/cliapp/src/service/DataLoadService.js +++ b/src/main/cliapp/src/service/DataLoadService.js @@ -81,7 +81,7 @@ export class DataLoadService extends BaseAuthService { const bulkLoadTypes = { BulkFMSLoad: [ 'GFF', - 'HTP EXPRESSION DATASET ANNOTATION', + 'HTP_EXPRESSION_DATASET_ANNOTATION', 'INTERACTION-GEN', 'INTERACTION-MOL', 'MOLECULE', diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java index fd40d6e52..7af5d1721 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -7,17 +7,26 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Projectable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonView; +import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; import jakarta.persistence.Index; import jakarta.persistence.JoinTable; import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToOne; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -31,6 +40,8 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @JsonView({ View.FieldsOnly.class }) + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") private String name; @IndexedEmbedded(includePaths = {"curie", "primaryCrossReferenceCurie", "crossReferences.referencedCurie", "curie_keyword", "primaryCrossReferenceCurie_keyword", "crossReferences.referencedCurie_keyword"}) @@ -44,17 +55,21 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @JsonView({ View.FieldsAndLists.class }) private List references; + @IndexedEmbedded(includePaths = { "freeText", "noteType.name", "references.curie", "references.primaryCrossReferenceCurie", "freeText_keyword", "noteType.name_keyword", "references.curie_keyword", "references.primaryCrossReferenceCurie_keyword" }) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JsonView({ View.FieldsOnly.class }) - private String realtedNote; + private Note relatedNote; @JsonView({ View.FieldsOnly.class }) + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) private Integer numberOfChannels; @IndexedEmbedded(includePaths = {"name", "name_keyword"}) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @ManyToMany @JsonView({ View.FieldsAndLists.class }) - @JoinTable(name = "htpexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "highthroughputexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) + @JoinTable(name = "highthroughputexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "highthroughputexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) List categoryTags; } diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql index 605d58caa..62108110c 100644 --- a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql +++ b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql @@ -16,7 +16,7 @@ INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) -SELECT id, '0 0 22 ? * SUN-THU', false FROM bulkload WHERE backendbulkloadtype = 'HTP_EXPRESSION_DATASET_ANNOTATION'; +SELECT id, '0 0 22 ? * SUN-THU', true FROM bulkload WHERE backendbulkloadtype = 'HTP_EXPRESSION_DATASET_ANNOTATION'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB' FROM bulkload WHERE name = 'FB HTP Expression Dataset Annotation Load'; @@ -55,7 +55,7 @@ CREATE TABLE highthroughputexpressiondatasetannotation ( modinternalid character varying(255), name character varying(255), numberofchannels integer, - realtednote character varying(255), + relatednote_id bigint, createdby_id bigint, updatedby_id bigint, dataprovider_id bigint @@ -81,6 +81,9 @@ CREATE INDEX htpdatasetannotation_categorytags_index ON highthroughputexpression CREATE INDEX htpdatasetannotation_htpdatasetid_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (highthroughputexpressiondatasetannotation_id); +ALTER TABLE highthroughputexpressiondatasetannotation + ADD CONSTRAINT highthroughputexpressiondatasetannotation_relatednote_id_fk FOREIGN KEY (relatednote_id) REFERENCES note (id); + ALTER TABLE highthroughputexpressiondatasetannotation_categorytags ADD CONSTRAINT highthroughputexpressiondatasetannotation_categorytags_highthroughputexpressiondatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); From 730e7e4ab971efbfa45d5bc2162dbceb3a460e83 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Fri, 12 Jul 2024 11:53:20 -0500 Subject: [PATCH 72/82] formatting --- .../entities/HighThroughputExpressionDatasetAnnotation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java index 7af5d1721..9e3431fb3 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -62,7 +62,7 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { private Note relatedNote; @JsonView({ View.FieldsOnly.class }) - @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) + @GenericField(projectable = Projectable.YES, sortable = Sortable.YES) private Integer numberOfChannels; @IndexedEmbedded(includePaths = {"name", "name_keyword"}) From a064080f64afc1d90cece7026bb07fa2912f4128 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Tue, 16 Jul 2024 08:27:20 -0500 Subject: [PATCH 73/82] Added vocabulary terms for HTP Dataset and HTP Dataset Sample --- .../cliapp/src/service/DataLoadService.js | 2 +- .../enums/BackendBulkLoadType.java | 2 +- ...6.0.4__highthroughputexpressiondataset.sql | 61 ++++++++++++++----- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/main/cliapp/src/service/DataLoadService.js b/src/main/cliapp/src/service/DataLoadService.js index 8eaf6fb4a..28b2eaa66 100644 --- a/src/main/cliapp/src/service/DataLoadService.js +++ b/src/main/cliapp/src/service/DataLoadService.js @@ -81,7 +81,7 @@ export class DataLoadService extends BaseAuthService { const bulkLoadTypes = { BulkFMSLoad: [ 'GFF', - 'HTP_EXPRESSION_DATASET_ANNOTATION', + 'HTPDATASET', 'INTERACTION-GEN', 'INTERACTION-MOL', 'MOLECULE', diff --git a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java index 119aef824..2c3ae805d 100644 --- a/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java +++ b/src/main/java/org/alliancegenome/curation_api/enums/BackendBulkLoadType.java @@ -24,7 +24,7 @@ public enum BackendBulkLoadType { PARALOGY("json"), SEQUENCE_TARGETING_REAGENT("json"), EXPRESSION("json"), - HTP_EXPRESSION_DATASET_ANNOTATION("json"); + HTPDATASET("json"); public String fileExtension; diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql index 62108110c..da1345447 100644 --- a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql +++ b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql @@ -3,41 +3,74 @@ INSERT INTO bulkloadgroup (id, name) VALUES (nextval('bulkloadgroup_seq'), 'HTP Expression Dataset Annotation Bulk Loads'); INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'FB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'ZFIN HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'ZFIN HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'MGI HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'MGI HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'RGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'RGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'SGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'SGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; +SELECT nextval('bulkload_seq'), 'HTPDATASET', 'WB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) -SELECT id, '0 0 22 ? * SUN-THU', true FROM bulkload WHERE backendbulkloadtype = 'HTP_EXPRESSION_DATASET_ANNOTATION'; +SELECT id, '0 0 22 ? * SUN-THU', true FROM bulkload WHERE backendbulkloadtype = 'HTPDATASET'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'FB' FROM bulkload WHERE name = 'FB HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'FB' FROM bulkload WHERE name = 'FB HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'MGI' FROM bulkload WHERE name = 'MGI HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'MGI' FROM bulkload WHERE name = 'MGI HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'RGD' FROM bulkload WHERE name = 'RGD HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'RGD' FROM bulkload WHERE name = 'RGD HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'SGD' FROM bulkload WHERE name = 'SGD HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'SGD' FROM bulkload WHERE name = 'SGD HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'WB' FROM bulkload WHERE name = 'WB HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'WB' FROM bulkload WHERE name = 'WB HTP Expression Dataset Annotation Load'; INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTP_EXPRESSION_DATASET_ANNOTATION', 'ZFIN' FROM bulkload WHERE name = 'ZFIN HTP Expression Dataset Annotation Load'; +SELECT id, 'HTPDATASET', 'ZFIN' FROM bulkload WHERE name = 'ZFIN HTP Expression Dataset Annotation Load'; ---Adding 3 extra vocabulary terms for HTPTags +--Adding vocabulary terms INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'epigenome', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional genomics and proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'karyotyping', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; +INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'HTP Expression Dataset Summary', 'Summary of the high-throughput expression dataset' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; +INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'HTP Expression Dataset Sample Note', 'Note pertaining to a high-throughput expression dataset sample' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; + +INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) + SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Note Type', 'htp_expression_dataset_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; + +INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) + WITH + t1 AS ( + SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_note_type' + ), + t2 AS ( + SELECT id FROM vocabularyterm WHERE name = 'HTP Expression Dataset Summary' AND vocabulary_id = ( + SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' + ) + ) + SELECT t1.id, t2.id FROM t1,t2; + +INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) + SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Sample Note Type', 'htp_expression_dataset_sample_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; + +INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) + WITH + t1 AS ( + SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_sample_note_type' + ), + t2 AS ( + SELECT id FROM vocabularyterm WHERE name = 'HTP Expression Dataset Sample Note' AND vocabulary_id = ( + SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' + ) + ) + SELECT t1.id, t2.id FROM t1,t2; + -- Adding highthroughputexpressiondatasetannotation CREATE SEQUENCE highthroughputexpressiondatasetannotation_seq START WITH 1 INCREMENT BY 50 NO MINVALUE NO MAXVALUE CACHE 1; From 45a3c6c4a8ac58ba66337db867382f6b9ea2d08e Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Tue, 16 Jul 2024 08:29:40 -0500 Subject: [PATCH 74/82] changes vocabulary terms name into snake case --- .../v0.36.0.4__highthroughputexpressiondataset.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql index da1345447..a2fd4fef3 100644 --- a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql +++ b/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql @@ -38,8 +38,8 @@ INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyt INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional genomics and proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'karyotyping', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; -INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'HTP Expression Dataset Summary', 'Summary of the high-throughput expression dataset' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; -INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'HTP Expression Dataset Sample Note', 'Note pertaining to a high-throughput expression dataset sample' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; +INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_summary', 'Summary of the high-throughput expression dataset' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; +INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_sample_note', 'Note pertaining to a high-throughput expression dataset sample' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Note Type', 'htp_expression_dataset_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; @@ -50,7 +50,7 @@ INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_note_type' ), t2 AS ( - SELECT id FROM vocabularyterm WHERE name = 'HTP Expression Dataset Summary' AND vocabulary_id = ( + SELECT id FROM vocabularyterm WHERE name = 'htp_expression_dataset_summary' AND vocabulary_id = ( SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' ) ) @@ -65,7 +65,7 @@ INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_sample_note_type' ), t2 AS ( - SELECT id FROM vocabularyterm WHERE name = 'HTP Expression Dataset Sample Note' AND vocabulary_id = ( + SELECT id FROM vocabularyterm WHERE name = 'htp_expression_dataset_sample_note' AND vocabulary_id = ( SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' ) ) From e600f5527e47a47c0a4d8b1c04b9908a0f8936ba Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Tue, 16 Jul 2024 08:37:00 -0500 Subject: [PATCH 75/82] Changed the version of the migration file --- ...dataset.sql => v0.36.0.5__highthroughputexpressiondataset.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{v0.36.0.4__highthroughputexpressiondataset.sql => v0.36.0.5__highthroughputexpressiondataset.sql} (100%) diff --git a/src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql similarity index 100% rename from src/main/resources/db/migration/v0.36.0.4__highthroughputexpressiondataset.sql rename to src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql From 1086337878847fced39c208ff759c940fe96ece0 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Tue, 16 Jul 2024 08:46:05 -0500 Subject: [PATCH 76/82] Changed the naming convention of vocabulary terms --- .../v0.36.0.5__highthroughputexpressiondataset.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql index a2fd4fef3..5ba060867 100644 --- a/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql +++ b/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql @@ -35,13 +35,13 @@ SELECT id, 'HTPDATASET', 'ZFIN' FROM bulkload WHERE name = 'ZFIN HTP Expression --Adding vocabulary terms INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'epigenome', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; -INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional genomics and proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; +INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional_genomics_and_proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'karyotyping', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_summary', 'Summary of the high-throughput expression dataset' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_sample_note', 'Note pertaining to a high-throughput expression dataset sample' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; -INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) +INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id) SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Note Type', 'htp_expression_dataset_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) @@ -56,7 +56,7 @@ INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms ) SELECT t1.id, t2.id FROM t1,t2; -INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id, vocabularytermsetdescription) +INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id) SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Sample Note Type', 'htp_expression_dataset_sample_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) From a3a266a6ec862e99d7fa443de476063aab64bf90 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Fri, 26 Jul 2024 14:10:56 -0500 Subject: [PATCH 77/82] New model changes according to LinkMl --- .../entities/ExternalDataBaseEntity.java | 67 +++++++++++++++++++ ...ThroughputExpressionDatasetAnnotation.java | 15 +++++ ....0.6__highthroughputexpressiondataset.sql} | 0 3 files changed, 82 insertions(+) create mode 100644 src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java rename src/main/resources/db/migration/{v0.36.0.5__highthroughputexpressiondataset.sql => v0.36.0.6__highthroughputexpressiondataset.sql} (100%) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java b/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java new file mode 100644 index 000000000..063932efd --- /dev/null +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java @@ -0,0 +1,67 @@ +package org.alliancegenome.curation_api.model.entities; + +import java.util.List; + +import org.alliancegenome.curation_api.model.entities.base.CurieObject; +import org.alliancegenome.curation_api.view.View; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; +import org.hibernate.search.engine.backend.types.Aggregable; +import org.hibernate.search.engine.backend.types.Searchable; +import org.hibernate.search.engine.backend.types.Sortable; +import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToOne; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Indexed +@Entity +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@ToString(callSuper = true) +@Schema(name = "ExternalDataBaseEntity", description = "POJO that represents the ExternalDataBaseEntity") +public class ExternalDataBaseEntity extends CurieObject{ + + @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") + @KeywordField(name = "secondaryIdentifiers_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") + @ElementCollection + @JsonView(View.FieldsAndLists.class) + @Column(columnDefinition = "TEXT") + @JoinTable(indexes = @Index(name = "externaldatabaseentity_secondaryIdentifiers_externaldatabaseentity_index", columnList = "externaldatabaseentity_id")) + private List secondaryIdentifiers; + + @IndexedEmbedded(includeDepth = 1) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) + @JsonView({ View.FieldsOnly.class }) + private CrossReference preferredCrossReference; + + @IndexedEmbedded(includeDepth = 1) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToMany + @OnDelete(action = OnDeleteAction.CASCADE) + @JoinTable(indexes = { + @Index(columnList = "externaldatabaseentity_id", name = "externaldatabaseentity_crossreference_externaldatabaseentity_index"), + @Index(columnList = "crossreferences_id", name = "externaldatabaseentity_crossreference_crossreferences_index") + }) + @JsonView({ View.FieldsAndLists.class }) + private List crossReferences; + +} diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java index 9e3431fb3..c62508033 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -39,6 +39,21 @@ @Schema(name = "HighThroughputExpressionDatasetAnnotation", description = "POJO that represents the HighThroughputExpressionDatasetAnnotation") public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) + @JsonView({ View.FieldsOnly.class }) + private ExternalDataBaseEntity htpExpressionDataset; + + @IndexedEmbedded(includePaths = {"secondaryIdentifiers", "preferredCrossReference", "crossReferences"}) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) + @ManyToMany + @Fetch(FetchMode.JOIN) + @JoinTable(indexes = { + @Index(name = "htpdatasetannotation_reference_htpdataset_index", columnList = "highthroughputexpressiondatasetannotation_id"), + @Index(name = "htpdatasetannotation_reference_references_index", columnList = "references_id") + }) + @JsonView({ View.FieldsAndLists.class }) + private List subSeries; + @JsonView({ View.FieldsOnly.class }) @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") @KeywordField(name = "name_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") diff --git a/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.6__highthroughputexpressiondataset.sql similarity index 100% rename from src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql rename to src/main/resources/db/migration/v0.36.0.6__highthroughputexpressiondataset.sql From a515e571d04bf6d8085d9fbe842bfec567409f76 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Fri, 26 Jul 2024 14:37:51 -0500 Subject: [PATCH 78/82] Model changes --- .../curation_api/model/entities/ExternalDataBaseEntity.java | 2 +- .../entities/HighThroughputExpressionDatasetAnnotation.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java b/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java index 063932efd..32aadf624 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java @@ -37,7 +37,7 @@ @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) @ToString(callSuper = true) @Schema(name = "ExternalDataBaseEntity", description = "POJO that represents the ExternalDataBaseEntity") -public class ExternalDataBaseEntity extends CurieObject{ +public class ExternalDataBaseEntity extends CurieObject { @FullTextField(analyzer = "autocompleteAnalyzer", searchAnalyzer = "autocompleteSearchAnalyzer") @KeywordField(name = "secondaryIdentifiers_keyword", aggregable = Aggregable.YES, sortable = Sortable.YES, searchable = Searchable.YES, normalizer = "sortNormalizer") diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java index c62508033..a363d96ec 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java @@ -43,13 +43,13 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @JsonView({ View.FieldsOnly.class }) private ExternalDataBaseEntity htpExpressionDataset; - @IndexedEmbedded(includePaths = {"secondaryIdentifiers", "preferredCrossReference", "crossReferences"}) + @IndexedEmbedded(includeDepth = 1) @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @ManyToMany @Fetch(FetchMode.JOIN) @JoinTable(indexes = { - @Index(name = "htpdatasetannotation_reference_htpdataset_index", columnList = "highthroughputexpressiondatasetannotation_id"), - @Index(name = "htpdatasetannotation_reference_references_index", columnList = "references_id") + @Index(name = "htpdatasetannotation_externaldatabaseentity_htpdataset_index", columnList = "highthroughputexpressiondatasetannotation_id"), + @Index(name = "htpdatasetannotation_externaldatabaseentity_subseries_index", columnList = "subseries_id") }) @JsonView({ View.FieldsAndLists.class }) private List subSeries; From c49e1f74fa6bf71b6a34f7ae06e219c13ee14959 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Fri, 26 Jul 2024 14:42:59 -0500 Subject: [PATCH 79/82] removed old migration file --- ...6.0.5__highthroughputexpressiondataset.sql | 139 ------------------ 1 file changed, 139 deletions(-) delete mode 100644 src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql diff --git a/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql deleted file mode 100644 index 5ba060867..000000000 --- a/src/main/resources/db/migration/v0.36.0.5__highthroughputexpressiondataset.sql +++ /dev/null @@ -1,139 +0,0 @@ --- To create bulk loads - -INSERT INTO bulkloadgroup (id, name) VALUES (nextval('bulkloadgroup_seq'), 'HTP Expression Dataset Annotation Bulk Loads'); - -INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTPDATASET', 'FB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; -INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTPDATASET', 'ZFIN HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; -INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTPDATASET', 'MGI HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; -INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTPDATASET', 'RGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; -INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTPDATASET', 'SGD HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; -INSERT INTO bulkload (id, backendbulkloadtype, name, bulkloadstatus, group_id) -SELECT nextval('bulkload_seq'), 'HTPDATASET', 'WB HTP Expression Dataset Annotation Load', 'STOPPED', id FROM bulkloadgroup WHERE name = 'HTP Expression Dataset Annotation Bulk Loads'; - -INSERT INTO bulkscheduledload (id, cronschedule, scheduleactive) -SELECT id, '0 0 22 ? * SUN-THU', true FROM bulkload WHERE backendbulkloadtype = 'HTPDATASET'; - -INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTPDATASET', 'FB' FROM bulkload WHERE name = 'FB HTP Expression Dataset Annotation Load'; -INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTPDATASET', 'MGI' FROM bulkload WHERE name = 'MGI HTP Expression Dataset Annotation Load'; -INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTPDATASET', 'RGD' FROM bulkload WHERE name = 'RGD HTP Expression Dataset Annotation Load'; -INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTPDATASET', 'SGD' FROM bulkload WHERE name = 'SGD HTP Expression Dataset Annotation Load'; -INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTPDATASET', 'WB' FROM bulkload WHERE name = 'WB HTP Expression Dataset Annotation Load'; -INSERT INTO bulkfmsload (id, fmsdatatype, fmsdatasubtype) -SELECT id, 'HTPDATASET', 'ZFIN' FROM bulkload WHERE name = 'ZFIN HTP Expression Dataset Annotation Load'; - - ---Adding vocabulary terms - -INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'epigenome', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; -INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'functional_genomics_and_proteomics', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; -INSERT INTO vocabularyterm (id, name, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'karyotyping', id FROM vocabulary WHERE vocabularylabel = 'data_set_category_tags'; - -INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_summary', 'Summary of the high-throughput expression dataset' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; -INSERT INTO vocabularyterm (id, name, definition, vocabulary_id) SELECT nextval('vocabularyterm_seq'), 'htp_expression_dataset_sample_note', 'Note pertaining to a high-throughput expression dataset sample' ,id FROM vocabulary WHERE vocabularylabel = 'note_type'; - -INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id) - SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Note Type', 'htp_expression_dataset_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; - -INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) - WITH - t1 AS ( - SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_note_type' - ), - t2 AS ( - SELECT id FROM vocabularyterm WHERE name = 'htp_expression_dataset_summary' AND vocabulary_id = ( - SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' - ) - ) - SELECT t1.id, t2.id FROM t1,t2; - -INSERT INTO vocabularytermset (id, name, vocabularylabel, vocabularytermsetvocabulary_id) - SELECT nextval('vocabularytermset_seq'), 'HTP Expression Dataset Sample Note Type', 'htp_expression_dataset_sample_note_type', id FROM vocabulary WHERE vocabularylabel = 'note_type'; - -INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms_id) - WITH - t1 AS ( - SELECT id FROM vocabularytermset WHERE vocabularylabel = 'htp_expression_dataset_sample_note_type' - ), - t2 AS ( - SELECT id FROM vocabularyterm WHERE name = 'htp_expression_dataset_sample_note' AND vocabulary_id = ( - SELECT id FROM vocabulary WHERE vocabularylabel = 'note_type' - ) - ) - SELECT t1.id, t2.id FROM t1,t2; - --- Adding highthroughputexpressiondatasetannotation - -CREATE SEQUENCE highthroughputexpressiondatasetannotation_seq START WITH 1 INCREMENT BY 50 NO MINVALUE NO MAXVALUE CACHE 1; - -CREATE TABLE highthroughputexpressiondatasetannotation ( - id bigint NOT NULL, - datecreated timestamp(6) with time zone, - dateupdated timestamp(6) with time zone, - dbdatecreated timestamp(6) with time zone, - dbdateupdated timestamp(6) with time zone, - internal boolean DEFAULT false NOT NULL, - obsolete boolean DEFAULT false NOT NULL, - curie character varying(255), - modentityid character varying(255), - modinternalid character varying(255), - name character varying(255), - numberofchannels integer, - relatednote_id bigint, - createdby_id bigint, - updatedby_id bigint, - dataprovider_id bigint -); - -CREATE TABLE highthroughputexpressiondatasetannotation_categorytags ( - highthroughputexpressiondatasetannotation_id bigint NOT NULL, - categorytags_id bigint NOT NULL - ); - -CREATE TABLE highthroughputexpressiondatasetannotation_reference ( - highthroughputexpressiondatasetannotation_id bigint NOT NULL, - references_id bigint NOT NULL - ); - -ALTER TABLE highthroughputexpressiondatasetannotation ADD CONSTRAINT highthroughputexpressiondatasetannotation_pkey PRIMARY KEY (id); - -CREATE INDEX htpdatasetannotation_reference_htpdataset_index ON highthroughputexpressiondatasetannotation_reference USING btree (highthroughputexpressiondatasetannotation_id); - -CREATE INDEX htpdatasetannotation_reference_references_index ON highthroughputexpressiondatasetannotation_reference USING btree (references_id); - -CREATE INDEX htpdatasetannotation_categorytags_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (categorytags_id); - -CREATE INDEX htpdatasetannotation_htpdatasetid_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (highthroughputexpressiondatasetannotation_id); - -ALTER TABLE highthroughputexpressiondatasetannotation - ADD CONSTRAINT highthroughputexpressiondatasetannotation_relatednote_id_fk FOREIGN KEY (relatednote_id) REFERENCES note (id); - -ALTER TABLE highthroughputexpressiondatasetannotation_categorytags - ADD CONSTRAINT highthroughputexpressiondatasetannotation_categorytags_highthroughputexpressiondatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); - -ALTER TABLE highthroughputexpressiondatasetannotation - ADD CONSTRAINT highthroughputexpressiondatasetannotation_dataprovider_id_fk FOREIGN KEY (dataprovider_id) REFERENCES dataprovider(id); - -ALTER TABLE highthroughputexpressiondatasetannotation_categorytags - ADD CONSTRAINT htpdatasetannotation_categorytags_categorytags_id_fk FOREIGN KEY (categorytags_id) REFERENCES vocabularyterm(id); - -ALTER TABLE highthroughputexpressiondatasetannotation_reference - ADD CONSTRAINT htpdatasetannotation_reference_htpdatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); - -ALTER TABLE highthroughputexpressiondatasetannotation_reference - ADD CONSTRAINT htpdatasetannotation_reference_references_id_fk FOREIGN KEY (references_id) REFERENCES reference(id); - -ALTER TABLE highthroughputexpressiondatasetannotation - ADD CONSTRAINT htpdatasetannotation_updatedby_id_fk FOREIGN KEY (updatedby_id) REFERENCES person(id); - -ALTER TABLE highthroughputexpressiondatasetannotation - ADD CONSTRAINT htpdatasetannotation_createdby_id_fk FOREIGN KEY (createdby_id) REFERENCES person(id); \ No newline at end of file From 97954bb5aab30f091cae387dcad9f1b0f3598d26 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Mon, 29 Jul 2024 10:53:45 -0500 Subject: [PATCH 80/82] Changed the class name --- .../entities/ExternalDataBaseEntity.java | 6 +- ...va => HTPExpressionDatasetAnnotation.java} | 23 ++- ...6.0.6__highthroughputexpressiondataset.sql | 131 ++++++++++++++---- 3 files changed, 117 insertions(+), 43 deletions(-) rename src/main/java/org/alliancegenome/curation_api/model/entities/{HighThroughputExpressionDatasetAnnotation.java => HTPExpressionDatasetAnnotation.java} (78%) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java b/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java index 32aadf624..87c0b26d7 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/ExternalDataBaseEntity.java @@ -44,7 +44,7 @@ public class ExternalDataBaseEntity extends CurieObject { @ElementCollection @JsonView(View.FieldsAndLists.class) @Column(columnDefinition = "TEXT") - @JoinTable(indexes = @Index(name = "externaldatabaseentity_secondaryIdentifiers_externaldatabaseentity_index", columnList = "externaldatabaseentity_id")) + @JoinTable(indexes = @Index(name = "externaldbentity_secondaryidentifiers_externaldbentity_index", columnList = "externaldatabaseentity_id")) private List secondaryIdentifiers; @IndexedEmbedded(includeDepth = 1) @@ -58,8 +58,8 @@ public class ExternalDataBaseEntity extends CurieObject { @ManyToMany @OnDelete(action = OnDeleteAction.CASCADE) @JoinTable(indexes = { - @Index(columnList = "externaldatabaseentity_id", name = "externaldatabaseentity_crossreference_externaldatabaseentity_index"), - @Index(columnList = "crossreferences_id", name = "externaldatabaseentity_crossreference_crossreferences_index") + @Index(columnList = "externaldatabaseentity_id", name = "externaldbentity_crossreference_externaldbentity_index"), + @Index(columnList = "crossreferences_id", name = "externaldbentity_crossreference_crossreferences_index") }) @JsonView({ View.FieldsAndLists.class }) private List crossReferences; diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java similarity index 78% rename from src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java rename to src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java index a363d96ec..0245fe622 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HighThroughputExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java @@ -14,31 +14,26 @@ import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; -import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; import com.fasterxml.jackson.annotation.JsonView; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.JoinTable; -import jakarta.persistence.ManyToMany; -import jakarta.persistence.OneToOne; +import jakarta.persistence.*; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; - -@Indexed @Entity @Data @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) @ToString(callSuper = true) -@Schema(name = "HighThroughputExpressionDatasetAnnotation", description = "POJO that represents the HighThroughputExpressionDatasetAnnotation") -public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { +@Table(name = "htpexpressiondatasetannotation") +@Schema(name = "HTPExpressionDatasetAnnotation", description = "POJO that represents the HighThroughputExpressionDatasetAnnotation") +public class HTPExpressionDatasetAnnotation extends SubmittedObject { + @IndexedEmbedded(includeDepth = 1) + @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JsonView({ View.FieldsOnly.class }) private ExternalDataBaseEntity htpExpressionDataset; @@ -48,7 +43,7 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @ManyToMany @Fetch(FetchMode.JOIN) @JoinTable(indexes = { - @Index(name = "htpdatasetannotation_externaldatabaseentity_htpdataset_index", columnList = "highthroughputexpressiondatasetannotation_id"), + @Index(name = "htpdatasetannotation_externaldatabaseentity_htpdataset_index", columnList = "htpexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_externaldatabaseentity_subseries_index", columnList = "subseries_id") }) @JsonView({ View.FieldsAndLists.class }) @@ -64,7 +59,7 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @ManyToMany @Fetch(FetchMode.JOIN) @JoinTable(indexes = { - @Index(name = "htpdatasetannotation_reference_htpdataset_index", columnList = "highthroughputexpressiondatasetannotation_id"), + @Index(name = "htpdatasetannotation_reference_htpdataset_index", columnList = "htpexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_reference_references_index", columnList = "references_id") }) @JsonView({ View.FieldsAndLists.class }) @@ -84,7 +79,7 @@ public class HighThroughputExpressionDatasetAnnotation extends SubmittedObject { @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW) @ManyToMany @JsonView({ View.FieldsAndLists.class }) - @JoinTable(name = "highthroughputexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "highthroughputexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) + @JoinTable(name = "htpexpressiondatasetannotation_categorytags", indexes = { @Index(name = "htpdatasetannotation_htpdatasetid_index", columnList = "htpexpressiondatasetannotation_id"), @Index(name = "htpdatasetannotation_categorytags_index", columnList = "categorytags_id")}) List categoryTags; } diff --git a/src/main/resources/db/migration/v0.36.0.6__highthroughputexpressiondataset.sql b/src/main/resources/db/migration/v0.36.0.6__highthroughputexpressiondataset.sql index 5ba060867..37edab450 100644 --- a/src/main/resources/db/migration/v0.36.0.6__highthroughputexpressiondataset.sql +++ b/src/main/resources/db/migration/v0.36.0.6__highthroughputexpressiondataset.sql @@ -71,11 +71,12 @@ INSERT INTO vocabularytermset_vocabularyterm (vocabularytermsets_id, memberterms ) SELECT t1.id, t2.id FROM t1,t2; --- Adding highthroughputexpressiondatasetannotation +-- Adding htpexpressiondatasetannotation -CREATE SEQUENCE highthroughputexpressiondatasetannotation_seq START WITH 1 INCREMENT BY 50 NO MINVALUE NO MAXVALUE CACHE 1; +CREATE SEQUENCE htpexpressiondatasetannotation_seq START WITH 1 INCREMENT BY 50 NO MINVALUE NO MAXVALUE CACHE 1; +CREATE SEQUENCE externaldatabaseentity_seq START WITH 1 INCREMENT BY 50 NO MINVALUE NO MAXVALUE CACHE 1; -CREATE TABLE highthroughputexpressiondatasetannotation ( +CREATE TABLE htpexpressiondatasetannotation ( id bigint NOT NULL, datecreated timestamp(6) with time zone, dateupdated timestamp(6) with time zone, @@ -91,49 +92,127 @@ CREATE TABLE highthroughputexpressiondatasetannotation ( relatednote_id bigint, createdby_id bigint, updatedby_id bigint, - dataprovider_id bigint + dataprovider_id bigint, + htpexpressiondataset_id bigint ); -CREATE TABLE highthroughputexpressiondatasetannotation_categorytags ( - highthroughputexpressiondatasetannotation_id bigint NOT NULL, +CREATE TABLE externaldatabaseentity ( + id bigint NOT NULL, + datecreated timestamp(6) with time zone, + dateupdated timestamp(6) with time zone, + dbdatecreated timestamp(6) with time zone, + dbdateupdated timestamp(6) with time zone, + internal boolean DEFAULT false NOT NULL, + obsolete boolean DEFAULT false NOT NULL, + curie character varying(255), + createdby_id bigint, + updatedby_id bigint, + preferredcrossreference_id bigint +); + +CREATE TABLE externaldatabaseentity_crossreference ( + externaldatabaseentity_id bigint NOT NULL, + crossreferences_id bigint NOT NULL +); + +CREATE TABLE externaldatabaseentity_secondaryidentifiers ( + externaldatabaseentity_id bigint NOT NULL, + secondaryidentifiers text +); + +CREATE TABLE htpexpressiondatasetannotation_externaldatabaseentity ( + htpexpressiondatasetannotation_id bigint NOT NULL, + subseries_id bigint NOT NULL +); + +CREATE TABLE htpexpressiondatasetannotation_categorytags ( + htpexpressiondatasetannotation_id bigint NOT NULL, categorytags_id bigint NOT NULL ); -CREATE TABLE highthroughputexpressiondatasetannotation_reference ( - highthroughputexpressiondatasetannotation_id bigint NOT NULL, +CREATE TABLE htpexpressiondatasetannotation_reference ( + htpexpressiondatasetannotation_id bigint NOT NULL, references_id bigint NOT NULL ); -ALTER TABLE highthroughputexpressiondatasetannotation ADD CONSTRAINT highthroughputexpressiondatasetannotation_pkey PRIMARY KEY (id); +ALTER TABLE htpexpressiondatasetannotation ADD CONSTRAINT htpexpressiondatasetannotation_pkey PRIMARY KEY (id); -CREATE INDEX htpdatasetannotation_reference_htpdataset_index ON highthroughputexpressiondatasetannotation_reference USING btree (highthroughputexpressiondatasetannotation_id); +ALTER TABLE externaldatabaseentity ADD CONSTRAINT externaldatabaseentity_pkey PRIMARY KEY (id); -CREATE INDEX htpdatasetannotation_reference_references_index ON highthroughputexpressiondatasetannotation_reference USING btree (references_id); +CREATE INDEX htpdatasetannotation_reference_htpdataset_index ON htpexpressiondatasetannotation_reference USING btree (htpexpressiondatasetannotation_id); -CREATE INDEX htpdatasetannotation_categorytags_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (categorytags_id); +CREATE INDEX htpdatasetannotation_reference_references_index ON htpexpressiondatasetannotation_reference USING btree (references_id); -CREATE INDEX htpdatasetannotation_htpdatasetid_index ON highthroughputexpressiondatasetannotation_categorytags USING btree (highthroughputexpressiondatasetannotation_id); +CREATE INDEX htpdatasetannotation_categorytags_index ON htpexpressiondatasetannotation_categorytags USING btree (categorytags_id); -ALTER TABLE highthroughputexpressiondatasetannotation - ADD CONSTRAINT highthroughputexpressiondatasetannotation_relatednote_id_fk FOREIGN KEY (relatednote_id) REFERENCES note (id); +CREATE INDEX htpdatasetannotation_htpdatasetid_index ON htpexpressiondatasetannotation_categorytags USING btree (htpexpressiondatasetannotation_id); -ALTER TABLE highthroughputexpressiondatasetannotation_categorytags - ADD CONSTRAINT highthroughputexpressiondatasetannotation_categorytags_highthroughputexpressiondatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); +CREATE INDEX externaldbentity_crossreference_crossreferences_index ON externaldatabaseentity_crossreference USING btree (crossreferences_id); -ALTER TABLE highthroughputexpressiondatasetannotation - ADD CONSTRAINT highthroughputexpressiondatasetannotation_dataprovider_id_fk FOREIGN KEY (dataprovider_id) REFERENCES dataprovider(id); +CREATE INDEX externaldbentity_crossreference_externaldbentity_index ON externaldatabaseentity_crossreference USING btree (externaldatabaseentity_id); -ALTER TABLE highthroughputexpressiondatasetannotation_categorytags +CREATE INDEX externaldbentity_secondaryidentifiers_externaldbentity_index ON externaldatabaseentity_secondaryidentifiers USING btree (externaldatabaseentity_id); + +CREATE INDEX htpdatasetannotation_externaldatabaseentity_htpdataset_index ON htpexpressiondatasetannotation_externaldatabaseentity USING btree (htpexpressiondatasetannotation_id); + +CREATE INDEX htpdatasetannotation_externaldatabaseentity_subseries_index ON htpexpressiondatasetannotation_externaldatabaseentity USING btree (subseries_id); + +ALTER TABLE htpexpressiondatasetannotation_externaldatabaseentity + ADD CONSTRAINT htpdatasetannotation_externaldbentity_subseries_id_fk FOREIGN KEY (subseries_id) REFERENCES externaldatabaseentity(id); + +ALTER TABLE externaldatabaseentity_secondaryidentifiers + ADD CONSTRAINT externaldbentity_secondaryidentifiers_externaldbentity_id_fk FOREIGN KEY (externaldatabaseentity_id) REFERENCES externaldatabaseentity(id); + +ALTER TABLE externaldatabaseentity_crossreference + ADD CONSTRAINT externaldbentity_crossreference_externaldbentity_id_fk FOREIGN KEY (externaldatabaseentity_id) REFERENCES externaldatabaseentity(id) ON DELETE CASCADE; + +ALTER TABLE htpexpressiondatasetannotation + ADD CONSTRAINT htpexpressiondatasetannotation_htpexpressiondataset_id_fk FOREIGN KEY (htpexpressiondataset_id) REFERENCES externaldatabaseentity(id); + +ALTER TABLE externaldatabaseentity + ADD CONSTRAINT externaldatabaseentity_preferredcrossreference_id FOREIGN KEY (preferredcrossreference_id) REFERENCES crossreference(id); + +ALTER TABLE externaldatabaseentity + ADD CONSTRAINT externaldatabaseentity_createdby_id_fk FOREIGN KEY (createdby_id) REFERENCES person(id); + +ALTER TABLE htpexpressiondatasetannotation_externaldatabaseentity + ADD CONSTRAINT htpannotation_externaldbentity_htpannotation_id_fk FOREIGN KEY (htpexpressiondatasetannotation_id) REFERENCES htpexpressiondatasetannotation(id); + +ALTER TABLE externaldatabaseentity_crossreference + ADD CONSTRAINT externaldatabaseentity_crossreference_crossreferences_id_fk FOREIGN KEY (crossreferences_id) REFERENCES crossreference(id); + +ALTER TABLE externaldatabaseentity + ADD CONSTRAINT externaldatabaseentity_updatedby_id_fk FOREIGN KEY (updatedby_id) REFERENCES person(id); + +ALTER TABLE htpexpressiondatasetannotation + ADD CONSTRAINT htpexpressiondatasetannotation_relatednote_id_fk FOREIGN KEY (relatednote_id) REFERENCES note (id); + +ALTER TABLE htpexpressiondatasetannotation_categorytags + ADD CONSTRAINT htpdatasetannotation_categorytags_htpdatasetannotation_id_fk FOREIGN KEY (htpexpressiondatasetannotation_id) REFERENCES htpexpressiondatasetannotation(id); + +ALTER TABLE htpexpressiondatasetannotation + ADD CONSTRAINT htpexpressiondatasetannotation_dataprovider_id_fk FOREIGN KEY (dataprovider_id) REFERENCES dataprovider(id); + +ALTER TABLE htpexpressiondatasetannotation_categorytags ADD CONSTRAINT htpdatasetannotation_categorytags_categorytags_id_fk FOREIGN KEY (categorytags_id) REFERENCES vocabularyterm(id); -ALTER TABLE highthroughputexpressiondatasetannotation_reference - ADD CONSTRAINT htpdatasetannotation_reference_htpdatasetannotation_id_fk FOREIGN KEY (highthroughputexpressiondatasetannotation_id) REFERENCES highthroughputexpressiondatasetannotation(id); +ALTER TABLE htpexpressiondatasetannotation_reference + ADD CONSTRAINT htpdatasetannotation_reference_htpdatasetannotation_id_fk FOREIGN KEY (htpexpressiondatasetannotation_id) REFERENCES htpexpressiondatasetannotation(id); -ALTER TABLE highthroughputexpressiondatasetannotation_reference +ALTER TABLE htpexpressiondatasetannotation_reference ADD CONSTRAINT htpdatasetannotation_reference_references_id_fk FOREIGN KEY (references_id) REFERENCES reference(id); -ALTER TABLE highthroughputexpressiondatasetannotation +ALTER TABLE htpexpressiondatasetannotation ADD CONSTRAINT htpdatasetannotation_updatedby_id_fk FOREIGN KEY (updatedby_id) REFERENCES person(id); -ALTER TABLE highthroughputexpressiondatasetannotation - ADD CONSTRAINT htpdatasetannotation_createdby_id_fk FOREIGN KEY (createdby_id) REFERENCES person(id); \ No newline at end of file +ALTER TABLE htpexpressiondatasetannotation + ADD CONSTRAINT htpdatasetannotation_createdby_id_fk FOREIGN KEY (createdby_id) REFERENCES person(id); + +ALTER TABLE htpexpressiondatasetannotation + ADD CONSTRAINT htpdatasetexpressionannotation_htpdataset_id_uk UNIQUE (htpexpressiondataset_id); + +ALTER TABLE externaldatabaseentity + ADD CONSTRAINT externaldatabaseentity_preferredcrossreference_id_uk UNIQUE (preferredcrossreference_id); + + ALTER TABLE htpexpressiondatasetannotation + ADD CONSTRAINT htpexpressiondatasetannotation_relatednote_id_uk UNIQUE (relatednote_id); \ No newline at end of file From 6d39216fe2db330a2035dc07d7332534d71d287e Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Mon, 29 Jul 2024 16:22:39 -0500 Subject: [PATCH 81/82] Added linkml version --- .../curation_api/model/entities/GeneToGeneParalogy.java | 2 +- .../model/entities/HTPExpressionDatasetAnnotation.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/GeneToGeneParalogy.java b/src/main/java/org/alliancegenome/curation_api/model/entities/GeneToGeneParalogy.java index d31d173f7..7499d68d1 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/GeneToGeneParalogy.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/GeneToGeneParalogy.java @@ -22,7 +22,7 @@ @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @Schema(name = "GeneToGeneParalogy", description = "POJO that represents paralogy between two genes") -@AGRCurationSchemaVersion(min = "1.7.4", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { AuditedObject.class }) +@AGRCurationSchemaVersion(min = "2.3.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { AuditedObject.class }) @Table(indexes = { @Index(name = "genetogeneparalogy_createdby_index", columnList = "createdBy_id"), @Index(name = "genetogeneparalogy_updatedby_index", columnList = "updatedBy_id"), diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java index 0245fe622..8bc88cd45 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java @@ -2,6 +2,9 @@ import java.util.List; +import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; +import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; +import org.alliancegenome.curation_api.model.entities.base.AuditedObject; import org.alliancegenome.curation_api.model.entities.base.SubmittedObject; import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.media.Schema; @@ -30,6 +33,7 @@ @ToString(callSuper = true) @Table(name = "htpexpressiondatasetannotation") @Schema(name = "HTPExpressionDatasetAnnotation", description = "POJO that represents the HighThroughputExpressionDatasetAnnotation") +@AGRCurationSchemaVersion(min = "2.6.0", max = LinkMLSchemaConstants.LATEST_RELEASE, dependencies = { SubmittedObject.class }) public class HTPExpressionDatasetAnnotation extends SubmittedObject { @IndexedEmbedded(includeDepth = 1) From b8827f23bcfa3270458898dbfef34f3dde5d2ef4 Mon Sep 17 00:00:00 2001 From: VarunReddy1111 Date: Mon, 29 Jul 2024 16:24:45 -0500 Subject: [PATCH 82/82] Removed unused import --- .../model/entities/HTPExpressionDatasetAnnotation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java b/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java index 8bc88cd45..ca9d7a342 100644 --- a/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java +++ b/src/main/java/org/alliancegenome/curation_api/model/entities/HTPExpressionDatasetAnnotation.java @@ -4,7 +4,6 @@ import org.alliancegenome.curation_api.constants.LinkMLSchemaConstants; import org.alliancegenome.curation_api.interfaces.AGRCurationSchemaVersion; -import org.alliancegenome.curation_api.model.entities.base.AuditedObject; import org.alliancegenome.curation_api.model.entities.base.SubmittedObject; import org.alliancegenome.curation_api.view.View; import org.eclipse.microprofile.openapi.annotations.media.Schema;