From f3e7f590c2b215c7f273b808a6df38601d21fcd2 Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Tue, 12 Nov 2024 11:56:59 +0100 Subject: [PATCH 01/12] Filling MARS receipt error in case of exception occuring instead of throwing it --- .../WebinIsaToXmlSubmissionController.java | 75 ++++++----- .../sra/service/MarsReceiptService.java | 31 +++-- .../MarsReceiptServiceInterceptorConfig.java | 18 +++ .../ISAToSRA/receipt/MarsReceiptProvider.java | 122 ++++++++++-------- .../receipt/marsmodel/MarsErrorType.java | 3 +- 5 files changed, 148 insertions(+), 101 deletions(-) create mode 100644 repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptServiceInterceptorConfig.java diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java index 1531232..51820d5 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java @@ -5,7 +5,6 @@ import static org.springframework.http.MediaType.APPLICATION_XML_VALUE; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; -import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.*; import com.elixir.biohackaton.ISAToSRA.sra.model.Receipt; import com.elixir.biohackaton.ISAToSRA.sra.service.MarsReceiptService; import com.elixir.biohackaton.ISAToSRA.sra.service.ReceiptConversionService; @@ -67,50 +66,56 @@ public class WebinIsaToXmlSubmissionController { public String performSubmissionToEna( @RequestBody final String submissionPayload, @RequestParam(value = "webinUserName") String webinUserName, - @RequestParam(value = "webinPassword") String webinPassword) - throws Exception { - if (webinUserName == null) { - throw new RuntimeException("Webin Authentication username is not provided"); - } + @RequestParam(value = "webinPassword") String webinPassword) { + try { + if (webinUserName == null || webinUserName.isEmpty()) { + throw new Exception("Webin Authentication username is not provided"); + } - if (webinPassword == null) { - throw new RuntimeException("Webin Authentication password is not provided"); - } + if (webinPassword == null || webinPassword.isEmpty()) { + throw new Exception("Webin Authentication password is not provided"); + } + + final IsaJson isaJson = this.objectMapper.readValue(submissionPayload, IsaJson.class); - final IsaJson isaJson = this.objectMapper.readValue(submissionPayload, IsaJson.class); + final Document document = DocumentHelper.createDocument(); + final Element webinElement = startPreparingWebinV2SubmissionXml(document); + final String randomSubmissionIdentifier = String.valueOf(Math.random()); - final Document document = DocumentHelper.createDocument(); - final Element webinElement = startPreparingWebinV2SubmissionXml(document); - final String randomSubmissionIdentifier = String.valueOf(Math.random()); + final List studies = getStudies(isaJson); + this.webinStudyXmlCreator.createENAStudySetElement( + webinElement, studies, randomSubmissionIdentifier); - final List studies = getStudies(isaJson); - this.webinStudyXmlCreator.createENAStudySetElement( - webinElement, studies, randomSubmissionIdentifier); + final Map typeToBioSamplesAccessionMap = getBiosamples(studies); + final Map experimentSequenceMap = + this.webinExperimentXmlCreator.createENAExperimentSetElement( + typeToBioSamplesAccessionMap, webinElement, studies, randomSubmissionIdentifier); - final Map typeToBioSamplesAccessionMap = getBiosamples(studies); - final Map experimentSequenceMap = - this.webinExperimentXmlCreator.createENAExperimentSetElement( - typeToBioSamplesAccessionMap, webinElement, studies, randomSubmissionIdentifier); + this.webinRunXmlCreator.createENARunSetElement( + webinElement, studies, experimentSequenceMap, randomSubmissionIdentifier); + this.webinProjectXmlCreator.createENAProjectSetElement( + webinElement, getInvestigation(isaJson), randomSubmissionIdentifier); - this.webinRunXmlCreator.createENARunSetElement( - webinElement, studies, experimentSequenceMap, randomSubmissionIdentifier); - this.webinProjectXmlCreator.createENAProjectSetElement( - webinElement, getInvestigation(isaJson), randomSubmissionIdentifier); + final OutputFormat format = OutputFormat.createPrettyPrint(); + final XMLWriter writer = new XMLWriter(System.out, format); - final OutputFormat format = OutputFormat.createPrettyPrint(); - final XMLWriter writer = new XMLWriter(System.out, format); + writer.write(document); - writer.write(document); + final String receiptXml = + webinHttpSubmissionService.performWebinSubmission( + webinUserName, document.asXML(), webinPassword); + log.info("ENA receipt", receiptXml); + final Receipt receiptJson = receiptConversionService.readReceiptXml(receiptXml); + log.info("ENA receipt object", this.objectMapper.writeValueAsString(receiptJson)); + marsReceiptService.convertReceiptToMars(receiptJson, isaJson); - final String receiptXml = - webinHttpSubmissionService.performWebinSubmission( - webinUserName, document.asXML(), webinPassword); - final Receipt receiptJson = receiptConversionService.readReceiptXml(receiptXml); - System.out.println(receiptXml); - System.out.println(receiptJson); - final MarsReceipt marsReceipt = marsReceiptService.convertReceiptToMars(receiptJson, isaJson); + return marsReceiptService.convertMarsReceiptToJson(); - return marsReceiptService.convertMarsReceiptToJson(marsReceipt); + } catch (Exception e) { + log.error("Internal server error", e); + marsReceiptService.setMarsReceiptErrors(e.getMessage()); + return marsReceiptService.convertMarsReceiptToJson(); + } } public List getStudies(final IsaJson isaJson) { diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java index d9ec770..e8c31ac 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java @@ -15,10 +15,13 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Service; +import org.springframework.web.servlet.HandlerInterceptor; @Service -public class MarsReceiptService extends MarsReceiptProvider { +public class MarsReceiptService extends MarsReceiptProvider implements HandlerInterceptor { private final ObjectMapper jsonMapper = new ObjectMapper(); private void setupJsonMapper() { @@ -28,17 +31,31 @@ private void setupJsonMapper() { } public MarsReceiptService() { + super("ena"); // TODO decide whether to use instead + // https://registry.identifiers.org/registry/ena.embl setupJsonMapper(); } - public String convertMarsReceiptToJson(final MarsReceipt marsReceipt) { + // Reset MARS receipt per request + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + resetMarsReceipt(); + return HandlerInterceptor.super.preHandle(request, response, handler); + } + + public String convertMarsReceiptToJson() { try { - return jsonMapper.writeValueAsString(marsReceipt); + return jsonMapper.writeValueAsString(getMarsReceipt()); } catch (Exception ex) { throw new RuntimeException("receipt", ex); } } + public void setMarsReceiptErrors(String... errors) { + super.setMarsReceiptErrors(MarsErrorType.INTERNAL_SERVER_ERROR, errors); + } + /** * Converting ENA receipt to Mars data format * @@ -46,12 +63,9 @@ public String convertMarsReceiptToJson(final MarsReceipt marsReceipt) { * https://github.com/elixir-europe/MARS/blob/refactor/repository-services/repository-api.md#response * @param receipt {@link Receipt} Receipt from ENA * @param isaJson {@link IsaJson} Requested ISA-Json - * @return {@link MarsReceipt} Mars response data */ - public MarsReceipt convertReceiptToMars(final Receipt receipt, final IsaJson isaJson) { - return buildMarsReceipt( - "ena", // TODO decide whether to use instead - // https://registry.identifiers.org/registry/ena.embl + public void convertReceiptToMars(final Receipt receipt, final IsaJson isaJson) { + buildMarsReceipt( getAliasAccessionPairs( Study.Fields.title, Optional.ofNullable(receipt.getStudies()).orElse(receipt.getProjects())), @@ -79,6 +93,7 @@ private ReceiptAccessionsMap getAliasAccessionPairs( new HashMap( Optional.ofNullable(items).orElse(new ArrayList<>()).stream() .filter(item -> item != null) + .filter(item -> item.getAccession() != null) .collect( Collectors.toMap( MarsReceiptService::getPreRandomizedAlias, diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptServiceInterceptorConfig.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptServiceInterceptorConfig.java new file mode 100644 index 0000000..859f911 --- /dev/null +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptServiceInterceptorConfig.java @@ -0,0 +1,18 @@ +/** Elixir BioHackathon 2022 */ +package com.elixir.biohackaton.ISAToSRA.sra.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class MarsReceiptServiceInterceptorConfig implements WebMvcConfigurer { + + @Autowired private MarsReceiptService marsReceiptService; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(marsReceiptService); + } +} diff --git a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java index 2d85361..2abd944 100644 --- a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java +++ b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java @@ -5,12 +5,24 @@ import java.util.List; import java.util.Optional; -import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; -import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.*; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.IsaJson; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsAccession; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsError; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsErrorType; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsInfo; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsMessage; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsPath; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsReceipt; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsWhere; import com.fasterxml.jackson.annotation.JsonProperty; public abstract class MarsReceiptProvider { + private MarsReceipt.MarsReceiptBuilder marsReceiptBuilder; + private MarsMessage marsMessage; + private List marsAccessions; + private final String targetRepository; + private class ReceiptAccessionMap { public String keyName; public String isaKeyName; @@ -18,25 +30,37 @@ private class ReceiptAccessionMap { public String accession; } - public MarsReceiptProvider() { + public MarsReceiptProvider(final String targetRepository) { + this.targetRepository = targetRepository; + resetMarsReceipt(); } - public abstract String convertMarsReceiptToJson(final MarsReceipt marsReceipt); + public abstract String convertMarsReceiptToJson(); + + public void resetMarsReceipt() { + marsMessage = MarsMessage.builder().build(); + marsAccessions = new ArrayList<>(); + marsReceiptBuilder = MarsReceipt.builder() + .targetRepository(targetRepository) + .accessions(marsAccessions) + .errors(marsMessage.errors) + .info(marsMessage.info); + } + + public MarsReceipt getMarsReceipt() { + return marsReceiptBuilder.build(); + } /** * Converts target receipt to Mars data format * * @see * https://github.com/elixir-europe/MARS/blob/refactor/repository-services/repository-api.md#response - * @param targetRepository Prefix of an item on - * https://registry.identifiers.org/registry - * @param isaJson Requested ISA-Json - * @param info List of info messages - * @param errors List of error messages - * @return {@link MarsReceipt} Mars response data + * @param isaJson Requested ISA-Json + * @param info List of info messages + * @param errors List of error messages */ - protected MarsReceipt buildMarsReceipt( - final String targetRepository, + protected void buildMarsReceipt( final ReceiptAccessionsMap studiesAccessionsMap, final ReceiptAccessionsMap samplesAccessionsMap, final ReceiptAccessionsMap sourcesAccessionsMap, @@ -45,63 +69,49 @@ protected MarsReceipt buildMarsReceipt( final List info, final List errors, final IsaJson isaJson) { - final MarsMessage marsMessage = MarsMessage.builder().build(); - final List marsAccessions = new ArrayList<>(); - setMarsReceiptErrors(errors, marsMessage); - setMarsReceiptInfo(info, marsMessage); + setMarsReceiptErrors(MarsErrorType.INVALID_METADATA, errors.toArray(String[]::new)); + setMarsReceiptInfo(info.toArray(String[]::new)); setMarsAccessions( studiesAccessionsMap, samplesAccessionsMap, sourcesAccessionsMap, otherMaterialsAccessionsMap, dataFilesAccessionsMap, - isaJson, - marsMessage, - marsAccessions); - return MarsReceipt.builder() - .targetRepository(targetRepository) + isaJson); + marsReceiptBuilder .accessions(marsAccessions) .errors(marsMessage.errors) - .info(marsMessage.info) - .build(); + .info(marsMessage.info); } - protected void setMarsReceiptErrors(final List errors, final MarsMessage marsMessage) { - Optional.ofNullable(errors) - .orElse(new ArrayList<>()) - .forEach( - error -> { - marsMessage.errors - .add( - MarsError.builder() - .message(error) - .type(MarsErrorType.INVALID_METADATA) - .build()); - }); + protected void setMarsReceiptErrors(MarsErrorType type, final String... errors) { + for (String error : Optional.ofNullable(errors).orElse(new String[0])) { + marsMessage.errors + .add( + MarsError.builder() + .message(error) + .type(type) + .build()); + } } - protected void setMarsReceiptInfo(final List infoList, final MarsMessage marsMessage) { - Optional.ofNullable(infoList) - .orElse(new ArrayList<>()) - .forEach( - info -> { - marsMessage.info - .add( - MarsInfo.builder() - .message(info) - .build()); - }); + protected void setMarsReceiptInfo(final String... info) { + for (String infoItem : Optional.ofNullable(info).orElse(new String[0])) { + marsMessage.info + .add( + MarsInfo.builder() + .message(infoItem) + .build()); + } } - protected List setMarsAccessions( + protected void setMarsAccessions( final ReceiptAccessionsMap studiesAccessionsMap, final ReceiptAccessionsMap samplesAccessionsMap, final ReceiptAccessionsMap sourcesAccessionsMap, final ReceiptAccessionsMap otherMaterialsAccessionsMap, final ReceiptAccessionsMap dataFilesAccessionsMap, - final IsaJson isaJson, - final MarsMessage marsMessage, - final List accessions) { + final IsaJson isaJson) { Optional.ofNullable(isaJson.investigation.studies) .orElse(new ArrayList<>()) .forEach( @@ -110,7 +120,7 @@ protected List setMarsAccessions( ReceiptAccessionMap studyAccessionMap = getAccessionMapEntry( studiesAccessionsMap, study, marsMessage); if (studyAccessionMap.accession != null) { - accessions.add(getStudyMarsAccession(studyAccessionMap)); + marsAccessions.add(getStudyMarsAccession(studyAccessionMap)); } if (samplesAccessionsMap != null) { Optional.ofNullable(study.materials.samples) @@ -120,7 +130,7 @@ protected List setMarsAccessions( ReceiptAccessionMap samplAccessionMap = getAccessionMapEntry( samplesAccessionsMap, sample, marsMessage); if (samplAccessionMap.accession != null) { - accessions.add(getSampleMarsAccession(studyAccessionMap, samplAccessionMap)); + marsAccessions.add(getSampleMarsAccession(studyAccessionMap, samplAccessionMap)); } }); } @@ -132,7 +142,7 @@ protected List setMarsAccessions( ReceiptAccessionMap sourceAccessionMap = getAccessionMapEntry( sourcesAccessionsMap, source, marsMessage); if (sourceAccessionMap.accession != null) { - accessions.add(getSourceMarsAccession(studyAccessionMap, sourceAccessionMap)); + marsAccessions.add(getSourceMarsAccession(studyAccessionMap, sourceAccessionMap)); } }); } @@ -149,7 +159,7 @@ protected List setMarsAccessions( ReceiptAccessionMap otherMaterialAccessionMap = getAccessionMapEntry( otherMaterialsAccessionsMap, otherMaterial, marsMessage); if (otherMaterialAccessionMap.accession != null) { - accessions.add(getOtherMaterialMarsAccession( + marsAccessions.add(getOtherMaterialMarsAccession( studyAccessionMap, assay.id, otherMaterialAccessionMap)); @@ -165,7 +175,7 @@ protected List setMarsAccessions( ReceiptAccessionMap dataFileAccessionMap = getAccessionMapEntry( dataFilesAccessionsMap, dataFile, marsMessage); if (dataFileAccessionMap.accession != null) { - accessions.add(getDataFileMarsAccession( + marsAccessions.add(getDataFileMarsAccession( studyAccessionMap, assay.id, dataFileAccessionMap)); @@ -176,8 +186,6 @@ protected List setMarsAccessions( } } }); - - return accessions; } // --------------------------------- diff --git a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/marsmodel/MarsErrorType.java b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/marsmodel/MarsErrorType.java index 8b55fc3..14ff43b 100644 --- a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/marsmodel/MarsErrorType.java +++ b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/marsmodel/MarsErrorType.java @@ -2,5 +2,6 @@ public enum MarsErrorType { INVALID_METADATA, - INVALID_DATA; + INVALID_DATA, + INTERNAL_SERVER_ERROR; } From 2d72fcbdd0f362d271f02e2c3883425872b35a7d Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Tue, 12 Nov 2024 14:11:43 +0100 Subject: [PATCH 02/12] MarsReceiptException (RuntimeException) --- .../BioSampleSubmissionController.java | 61 +++++++++++-------- .../service/BioSamplesSubmitter.java | 11 ++-- .../service/MarsReceiptService.java | 44 +++++++++---- .../WebinIsaToXmlSubmissionController.java | 27 ++++---- .../sra/service/MarsReceiptService.java | 2 +- .../sra/service/SRAAnalysisXmlCreator.java | 3 +- .../service/WebinExperimentXmlCreator.java | 6 +- .../sra/service/WebinStudyXmlCreator.java | 3 +- .../receipt/MarsReceiptException.java | 17 ++++++ 9 files changed, 112 insertions(+), 62 deletions(-) create mode 100644 repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptException.java diff --git a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java index b0b9ce7..1149a1b 100644 --- a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java +++ b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java @@ -4,21 +4,27 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_XML_VALUE; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + import com.elixir.biohackaton.ISAToSRA.biosamples.model.BiosampleAccessionsMap; import com.elixir.biohackaton.ISAToSRA.biosamples.service.BioSamplesSubmitter; import com.elixir.biohackaton.ISAToSRA.biosamples.service.MarsReceiptService; -import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; -import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsReceipt; +import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptException; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.IsaJson; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.Study; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; + import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; - -import java.util.List; - import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; @Slf4j @RestController @@ -42,33 +48,40 @@ public class BioSampleSubmissionController { consumes = { APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE }) public String performSubmissionToBioSamplesAndEna( @RequestBody final String submissionPayload, - @RequestParam(value = "webinjwt") String webinJwt) - throws Exception { - String webinToken; - if (webinJwt != null) { - webinToken = webinJwt; - } else { - throw new RuntimeException("Webin Authentication Token is not provided"); - } + @RequestParam(value = "webinjwt") String webinJwt) { + try { + String webinToken; + if (webinJwt != null) { + webinToken = webinJwt; + } else { + throw new RuntimeException("Webin Authentication Token is not provided"); + } - objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - final IsaJson isaJson = this.objectMapper.readValue(submissionPayload, IsaJson.class); - final List studies = getStudies(isaJson); + final IsaJson isaJson = this.objectMapper.readValue(submissionPayload, IsaJson.class); + final List studies = getStudies(isaJson); - final BiosampleAccessionsMap accessionsMap = this.bioSamplesSubmitter.createBioSamples(studies, webinToken); - final MarsReceipt marsReceipt = marsReceiptService.convertReceiptToMars(accessionsMap, isaJson); + final BiosampleAccessionsMap accessionsMap = this.bioSamplesSubmitter.createBioSamples(studies, webinToken); + marsReceiptService.convertReceiptToMars(accessionsMap, isaJson); - return marsReceiptService.convertMarsReceiptToJson(marsReceipt); + return marsReceiptService.convertMarsReceiptToJson(); + } catch (final MarsReceiptException e) { + log.error("Mars receipt excption", e); + marsReceiptService.setMarsReceiptErrors(e.getReceiptErrorMessage()); + return marsReceiptService.convertMarsReceiptToJson(); + } catch (final Exception e) { + log.error("Internal server error", e); + marsReceiptService.setMarsReceiptErrors(e.getMessage()); + return marsReceiptService.convertMarsReceiptToJson(); + } } public List getStudies(final IsaJson isaJson) { try { return isaJson.getInvestigation().getStudies(); } catch (final Exception e) { - log.info("Failed to parse ISA JSON and get studies", e); + throw new MarsReceiptException("Failed to parse ISA JSON and get studies", e); } - - return null; } } diff --git a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/BioSamplesSubmitter.java b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/BioSamplesSubmitter.java index 8c8ad47..ced6377 100644 --- a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/BioSamplesSubmitter.java +++ b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/BioSamplesSubmitter.java @@ -5,6 +5,7 @@ import com.elixir.biohackaton.ISAToSRA.biosamples.model.BiosampleAccessionsMap; import com.elixir.biohackaton.ISAToSRA.biosamples.model.Relationship; import com.elixir.biohackaton.ISAToSRA.biosamples.model.BioSample; +import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptException; import com.elixir.biohackaton.ISAToSRA.receipt.ReceiptAccessionsMap; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; @@ -80,7 +81,7 @@ public BiosampleAccessionsMap createBioSamples(final List studies, final }); } } catch (final Exception e) { - throw new RuntimeException("Failed to parse ISA Json and create samples in BioSamples", e); + throw new MarsReceiptException("Failed to parse ISA Json and create samples in BioSamples", e); } return typeToBioSamplesAccessionMap; @@ -122,7 +123,7 @@ private BioSample createAndUpdateChildSampleWithRelationship( return null; } } catch (final Exception e) { - throw new RuntimeException("Failed to handle child samples", e); + throw new MarsReceiptException("Failed to handle child samples", e); } } @@ -165,7 +166,7 @@ private BioSample createSourceBioSample(final List studies, final String sourceCharacteristics.add(biosampleAccessionCharacteristic); source.setCharacteristics(sourceCharacteristics); } else { - throw new RuntimeException("Failed to store source sample to BioSamples"); + throw new MarsReceiptException("Failed to store source sample to BioSamples"); } })); @@ -205,7 +206,7 @@ private BioSample updateSampleWithRelationshipsToBioSamples( }); return biosamplesResponse.getBody().getContent(); } catch (final Exception ex) { - throw new RuntimeException("Failed to add relationships to child samples", ex); + throw new MarsReceiptException("Failed to add relationships to child samples", ex); } } @@ -227,7 +228,7 @@ private EntityModel createSampleInBioSamples( return biosamplesResponse.getBody(); } catch (final Exception ex) { - throw new RuntimeException("Failed to create samples in BioSamples", ex); + throw new MarsReceiptException("Failed to create samples in BioSamples", ex); } } diff --git a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java index 49f60e5..af5377d 100644 --- a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java +++ b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java @@ -1,17 +1,22 @@ /** Elixir BioHackathon 2022 */ package com.elixir.biohackaton.ISAToSRA.biosamples.service; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.HandlerInterceptor; + import com.elixir.biohackaton.ISAToSRA.biosamples.model.BiosampleAccessionsMap; import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptProvider; -import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; -import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.*; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.IsaJson; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsErrorType; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import org.springframework.stereotype.Service; @Service -public class MarsReceiptService extends MarsReceiptProvider { +public class MarsReceiptService extends MarsReceiptProvider implements HandlerInterceptor { private final ObjectMapper jsonMapper = new ObjectMapper(); private void setupJsonMapper() { @@ -21,29 +26,42 @@ private void setupJsonMapper() { } public MarsReceiptService() { + super("biosamples"); // TODO decide whether to use instead + // https://registry.identifiers.org/registry/biosample setupJsonMapper(); } - public String convertMarsReceiptToJson(final MarsReceipt marsReceipt) { + // Reset MARS receipt per request + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + resetMarsReceipt(); + return HandlerInterceptor.super.preHandle(request, response, handler); + } + + public String convertMarsReceiptToJson() { try { - return jsonMapper.writeValueAsString(marsReceipt); + return jsonMapper.writeValueAsString(getMarsReceipt()); } catch (Exception ex) { - throw new RuntimeException("receipt", ex); + throw new RuntimeException("Receipt", ex); } } + public void setMarsReceiptErrors(String... errors) { + super.setMarsReceiptErrors(MarsErrorType.INTERNAL_SERVER_ERROR, errors); + } + /** * Converting BioSample receipt to Mars data format * * @see * https://github.com/elixir-europe/MARS/blob/refactor/repository-services/repository-api.md#response - * @param biosampleAccessionsMap {@link BiosampleAccessionsMap} Receipt from Biosample - * @param isaJson {@link IsaJson} Requested ISA-Json - * @return {@link MarsReceipt} Mars response data + * @param biosampleAccessionsMap {@link BiosampleAccessionsMap} Receipt from + * Biosample + * @param isaJson {@link IsaJson} Requested ISA-Json */ - public MarsReceipt convertReceiptToMars(final BiosampleAccessionsMap biosampleAccessionsMap, final IsaJson isaJson) { - return buildMarsReceipt( - "biosamples", // https://registry.identifiers.org/registry/biosample + public void convertReceiptToMars(final BiosampleAccessionsMap biosampleAccessionsMap, final IsaJson isaJson) { + buildMarsReceipt( biosampleAccessionsMap.studyAccessionsMap, biosampleAccessionsMap.sampleAccessionsMap, biosampleAccessionsMap.sourceAccessionsMap, diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java index 51820d5..128a576 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java @@ -4,6 +4,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_XML_VALUE; +import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptException; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; import com.elixir.biohackaton.ISAToSRA.sra.model.Receipt; import com.elixir.biohackaton.ISAToSRA.sra.service.MarsReceiptService; @@ -69,11 +70,11 @@ public String performSubmissionToEna( @RequestParam(value = "webinPassword") String webinPassword) { try { if (webinUserName == null || webinUserName.isEmpty()) { - throw new Exception("Webin Authentication username is not provided"); + throw new MarsReceiptException("Webin Authentication username is not provided"); } if (webinPassword == null || webinPassword.isEmpty()) { - throw new Exception("Webin Authentication password is not provided"); + throw new MarsReceiptException("Webin Authentication password is not provided"); } final IsaJson isaJson = this.objectMapper.readValue(submissionPayload, IsaJson.class); @@ -111,7 +112,11 @@ public String performSubmissionToEna( return marsReceiptService.convertMarsReceiptToJson(); - } catch (Exception e) { + } catch (final MarsReceiptException e) { + log.error("Mars receipt excption", e); + marsReceiptService.setMarsReceiptErrors(e.getReceiptErrorMessage()); + return marsReceiptService.convertMarsReceiptToJson(); + } catch (final Exception e) { log.error("Internal server error", e); marsReceiptService.setMarsReceiptErrors(e.getMessage()); return marsReceiptService.convertMarsReceiptToJson(); @@ -122,23 +127,19 @@ public List getStudies(final IsaJson isaJson) { try { return isaJson.getInvestigation().getStudies(); } catch (final Exception e) { - log.info("Failed to parse ISA JSON and get studies", e); + throw new MarsReceiptException("Failed to parse ISA JSON and get studies", e); } - - return null; } public Investigation getInvestigation(final IsaJson isaJson) { try { return isaJson.getInvestigation(); } catch (final Exception e) { - log.info("Failed to parse ISA JSON and get studies", e); + throw new MarsReceiptException("Failed to parse ISA JSON and get studies", e); } - - return null; } - public Map getBiosamples(List studies) { + public Map getBiosamples(List studies) throws Exception { HashMap biosamples = new HashMap<>(); for (Study study : studies) { for (Source source : study.materials.sources) { @@ -162,13 +163,11 @@ private String getCharacteresticAnnotation(List characteristics) .collect(Collectors.toList()); if (filteredCharacteristics.isEmpty()) { - log.error("No accession found in the characteristics"); - throw new RuntimeException("No accession found in the characteristics"); + throw new MarsReceiptException("No accession found in the characteristics"); } if (filteredCharacteristics.size() > 1) { - log.error("More than one accession found in the characteristics"); - throw new RuntimeException("Too many accessions found in the characteristics"); + throw new MarsReceiptException("Too many accessions found in the characteristics"); } return filteredCharacteristics.get(0).value.annotationValue; } diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java index e8c31ac..773d576 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java @@ -48,7 +48,7 @@ public String convertMarsReceiptToJson() { try { return jsonMapper.writeValueAsString(getMarsReceipt()); } catch (Exception ex) { - throw new RuntimeException("receipt", ex); + throw new RuntimeException("Receipt", ex); } } diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/SRAAnalysisXmlCreator.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/SRAAnalysisXmlCreator.java index e9311e3..2456ab2 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/SRAAnalysisXmlCreator.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/SRAAnalysisXmlCreator.java @@ -1,6 +1,7 @@ /** Elixir BioHackathon 2022 */ package com.elixir.biohackaton.ISAToSRA.sra.service; +import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptException; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; import java.util.List; import java.util.Objects; @@ -75,7 +76,7 @@ private void convertDataFileToFileElement(DataFile dataFile, Element filesElemen }); if (Objects.isNull(checksum.get()) || Objects.isNull(checksumType.get())) { - log.error("Checksum and checksum type not found"); + throw new MarsReceiptException("Checksum and checksum type not found"); } else { Element fileElement = filesElement.addElement("FILE"); fileElement.addAttribute("filename", filename); diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinExperimentXmlCreator.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinExperimentXmlCreator.java index a9c2272..fa20ad3 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinExperimentXmlCreator.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinExperimentXmlCreator.java @@ -1,6 +1,7 @@ /** Elixir BioHackathon 2022 */ package com.elixir.biohackaton.ISAToSRA.sra.service; +import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptException; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; import java.util.HashMap; import java.util.List; @@ -32,10 +33,9 @@ public Map createENAExperimentSetElement( typeToBioSamplesAccessionMap, randomSubmissionIdentifier); } catch (final Exception e) { - log.info("Failed to parse experiments from ISA Json file and create ENA Experiments"); + throw new MarsReceiptException( + "Failed to parse experiments from ISA Json file and create ENA Experiments", e); } - - return null; } private String populateProcessSequenceToParameterValuesMapAndGetExecutesProtocolId( diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinStudyXmlCreator.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinStudyXmlCreator.java index 24e6550..daf594e 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinStudyXmlCreator.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinStudyXmlCreator.java @@ -1,6 +1,7 @@ /** Elixir BioHackathon 2022 */ package com.elixir.biohackaton.ISAToSRA.sra.service; +import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptException; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; import java.util.List; import lombok.extern.slf4j.Slf4j; @@ -48,7 +49,7 @@ public void createENAStudySetElement( }); }); } catch (final Exception e) { - log.info("Failed to parse ISA JSON and create ENA study"); + throw new MarsReceiptException("Failed to parse ISA JSON and create ENA study"); } } } diff --git a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptException.java b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptException.java new file mode 100644 index 0000000..0ad40f8 --- /dev/null +++ b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptException.java @@ -0,0 +1,17 @@ +package com.elixir.biohackaton.ISAToSRA.receipt; + +import lombok.Getter; + +public class MarsReceiptException extends RuntimeException { + @Getter + private final String receiptErrorMessage; + + public MarsReceiptException(final String receiptErrorMessage) { + this.receiptErrorMessage = receiptErrorMessage; + } + + public MarsReceiptException(final String receiptErrorMessage, final Exception exception) { + this.addSuppressed(exception); + this.receiptErrorMessage = receiptErrorMessage; + } +} From 72aa346057c7162c23905d862c4d4b95e539d38c Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Tue, 12 Nov 2024 15:36:12 +0100 Subject: [PATCH 03/12] MarsReceiptServiceInterceptorConfig for isajson-biosamples --- .../MarsReceiptServiceInterceptorConfig.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptServiceInterceptorConfig.java diff --git a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptServiceInterceptorConfig.java b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptServiceInterceptorConfig.java new file mode 100644 index 0000000..8c8541a --- /dev/null +++ b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptServiceInterceptorConfig.java @@ -0,0 +1,18 @@ +/** Elixir BioHackathon 2022 */ +package com.elixir.biohackaton.ISAToSRA.biosamples.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class MarsReceiptServiceInterceptorConfig implements WebMvcConfigurer { + + @Autowired private MarsReceiptService marsReceiptService; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(marsReceiptService); + } +} From 62597cd32666a8bed4ab2b6920a8b54dceacdce7 Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Tue, 12 Nov 2024 15:37:28 +0100 Subject: [PATCH 04/12] Mars receipt, null pointer exception handling --- .../BioSampleSubmissionController.java | 7 ++----- .../biosamples/service/MarsReceiptService.java | 2 +- .../ISAToSRA/sra/service/MarsReceiptService.java | 2 +- .../ISAToSRA/receipt/MarsReceiptProvider.java | 16 +++++++++------- .../receipt/marsmodel/MarsErrorType.java | 3 +-- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java index 1149a1b..baf4ec5 100644 --- a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java +++ b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java @@ -50,10 +50,7 @@ public String performSubmissionToBioSamplesAndEna( @RequestBody final String submissionPayload, @RequestParam(value = "webinjwt") String webinJwt) { try { - String webinToken; - if (webinJwt != null) { - webinToken = webinJwt; - } else { + if (webinJwt == null || webinJwt.isEmpty()) { throw new RuntimeException("Webin Authentication Token is not provided"); } @@ -62,7 +59,7 @@ public String performSubmissionToBioSamplesAndEna( final IsaJson isaJson = this.objectMapper.readValue(submissionPayload, IsaJson.class); final List studies = getStudies(isaJson); - final BiosampleAccessionsMap accessionsMap = this.bioSamplesSubmitter.createBioSamples(studies, webinToken); + final BiosampleAccessionsMap accessionsMap = this.bioSamplesSubmitter.createBioSamples(studies, webinJwt); marsReceiptService.convertReceiptToMars(accessionsMap, isaJson); return marsReceiptService.convertMarsReceiptToJson(); diff --git a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java index af5377d..9403eca 100644 --- a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java +++ b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java @@ -48,7 +48,7 @@ public String convertMarsReceiptToJson() { } public void setMarsReceiptErrors(String... errors) { - super.setMarsReceiptErrors(MarsErrorType.INTERNAL_SERVER_ERROR, errors); + super.setMarsReceiptErrors(MarsErrorType.INVALID_METADATA, errors); } /** diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java index 773d576..89327c8 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java @@ -53,7 +53,7 @@ public String convertMarsReceiptToJson() { } public void setMarsReceiptErrors(String... errors) { - super.setMarsReceiptErrors(MarsErrorType.INTERNAL_SERVER_ERROR, errors); + super.setMarsReceiptErrors(MarsErrorType.INVALID_METADATA, errors); } /** diff --git a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java index 2abd944..086caf1 100644 --- a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java +++ b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java @@ -69,8 +69,11 @@ protected void buildMarsReceipt( final List info, final List errors, final IsaJson isaJson) { - setMarsReceiptErrors(MarsErrorType.INVALID_METADATA, errors.toArray(String[]::new)); - setMarsReceiptInfo(info.toArray(String[]::new)); + final String[] errorArray = Optional.ofNullable(errors).orElse(new ArrayList<>()).toArray(String[]::new); + final String[] infoArray = Optional.ofNullable(info).orElse(new ArrayList<>()).toArray(String[]::new); + + setMarsReceiptErrors(MarsErrorType.INVALID_METADATA, errorArray); + setMarsReceiptInfo(infoArray); setMarsAccessions( studiesAccessionsMap, samplesAccessionsMap, @@ -122,7 +125,7 @@ protected void setMarsAccessions( if (studyAccessionMap.accession != null) { marsAccessions.add(getStudyMarsAccession(studyAccessionMap)); } - if (samplesAccessionsMap != null) { + if (samplesAccessionsMap != null && study.materials != null) { Optional.ofNullable(study.materials.samples) .orElse(new ArrayList<>()) .forEach( @@ -134,7 +137,7 @@ protected void setMarsAccessions( } }); } - if (sourcesAccessionsMap != null) { + if (sourcesAccessionsMap != null && study.materials != null) { Optional.ofNullable(study.materials.sources) .orElse(new ArrayList<>()) .forEach( @@ -151,7 +154,7 @@ protected void setMarsAccessions( .orElse(new ArrayList<>()) .forEach( assay -> { - if (otherMaterialsAccessionsMap != null) { + if (otherMaterialsAccessionsMap != null && assay.materials != null) { Optional.ofNullable(assay.materials.otherMaterials) .orElse(new ArrayList<>()) .forEach( @@ -167,8 +170,7 @@ protected void setMarsAccessions( }); } if (dataFilesAccessionsMap != null) { - Optional.ofNullable( - assay.dataFiles) + Optional.ofNullable(assay.dataFiles) .orElse(new ArrayList<>()) .forEach( dataFile -> { diff --git a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/marsmodel/MarsErrorType.java b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/marsmodel/MarsErrorType.java index 14ff43b..8b55fc3 100644 --- a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/marsmodel/MarsErrorType.java +++ b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/marsmodel/MarsErrorType.java @@ -2,6 +2,5 @@ public enum MarsErrorType { INVALID_METADATA, - INVALID_DATA, - INTERNAL_SERVER_ERROR; + INVALID_DATA; } From c2b3b1ef59c147dc458f5af74ac2551b2df88fbc Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Tue, 19 Nov 2024 13:03:29 +0100 Subject: [PATCH 05/12] More clear naming for ReceiptAccessionMap fields --- .../ISAToSRA/receipt/MarsReceiptProvider.java | 284 ++++++++++-------- .../receipt/ReceiptAccessionsMap.java | 22 +- 2 files changed, 178 insertions(+), 128 deletions(-) diff --git a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java index 086caf1..46329e0 100644 --- a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java +++ b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptProvider.java @@ -3,6 +3,8 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.IsaJson; @@ -24,9 +26,9 @@ public abstract class MarsReceiptProvider { private final String targetRepository; private class ReceiptAccessionMap { - public String keyName; - public String isaKeyName; - public String keyValue; + public String isaItemName; + public String isaFieldKey; + public String isaFieldValue; public String accession; } @@ -87,8 +89,20 @@ protected void buildMarsReceipt( .info(marsMessage.info); } + protected void setMarsReceiptErrors(MarsErrorType type, final MarsError... errors) { + for (MarsError error : Optional.ofNullable(errors).filter(error -> error != null).get()) { + marsMessage.errors + .add( + MarsError.builder() + .message(error.message) + .path(error.path) + .type(type) + .build()); + } + } + protected void setMarsReceiptErrors(MarsErrorType type, final String... errors) { - for (String error : Optional.ofNullable(errors).orElse(new String[0])) { + for (String error : Optional.ofNullable(errors).orElse(new String[] { "Null message recieved" })) { marsMessage.errors .add( MarsError.builder() @@ -190,26 +204,138 @@ protected void setMarsAccessions( }); } + // ------------------------- + // | Making Mars item path | + // ------------------------- + + public MarsPath[] getStudyMarsPath(final Entry isaStudyKeyValue) { + return new MarsPath[] { + MarsPath.builder().key("investigation").build(), + MarsPath.builder() + .key("studies") + .where( + MarsWhere.builder() + .key(isaStudyKeyValue.getKey()) + .value(isaStudyKeyValue.getValue()) + .build()) + .build() + }; + } + + public MarsPath[] getSampleMarsPath( + final Entry isaStudyKeyValue, + final Entry isaSampleKeyValue) { + return new MarsPath[] { + MarsPath.builder().key("investigation").build(), + MarsPath.builder() + .key("studies") + .where(MarsWhere.builder() + .key(isaStudyKeyValue.getKey()) + .value(isaStudyKeyValue.getValue()) + .build()) + .build(), + MarsPath.builder().key("materials").build(), + MarsPath.builder() + .key("samples") + .where(MarsWhere.builder() + .key(isaSampleKeyValue.getKey()) + .value(isaSampleKeyValue.getValue()) + .build()) + .build(), + }; + } + + public MarsPath[] getSourceMarsPath( + final Entry isaStudyKeyValue, + final Entry isaSourceKeyValue) { + return new MarsPath[] { + MarsPath.builder().key("investigation").build(), + MarsPath.builder() + .key("studies") + .where(MarsWhere.builder() + .key(isaStudyKeyValue.getKey()) + .value(isaStudyKeyValue.getValue()) + .build()) + .build(), + MarsPath.builder().key("materials").build(), + MarsPath.builder() + .key("sources") + .where(MarsWhere.builder() + .key(isaSourceKeyValue.getKey()) + .value(isaSourceKeyValue.getValue()) + .build()) + .build() + }; + } + + public MarsPath[] getOtherMaterialMarsPath( + final Entry isaStudyKeyValue, + final String assayId, + final Entry isaOtherMaterialKeyValue) { + return new MarsPath[] { + MarsPath.builder().key("investigation").build(), + MarsPath.builder() + .key("studies") + .where(MarsWhere.builder() + .key(isaStudyKeyValue.getKey()) + .value(isaStudyKeyValue.getValue()) + .build()) + .build(), + MarsPath.builder() + .key("assays") + .where(MarsWhere.builder() + .key("@id") + .value(assayId) + .build()) + .build(), + MarsPath.builder().key("materials").build(), + MarsPath.builder() + .key("otherMaterials") + .where(MarsWhere.builder() + .key(isaOtherMaterialKeyValue.getKey()) + .value(isaOtherMaterialKeyValue.getValue()) + .build()) + .build() + }; + } + + public MarsPath[] getDataFileMarsPath( + final Entry isaStudyKeyValue, + final String assayId, + final Entry isaDataFileKeyValue) { + return new MarsPath[] { + MarsPath.builder().key("investigation").build(), + MarsPath.builder() + .key("studies") + .where(MarsWhere.builder() + .key(isaStudyKeyValue.getKey()) + .value(isaStudyKeyValue.getValue()) + .build()) + .build(), + MarsPath.builder() + .key("assays") + .where(MarsWhere.builder() + .key("@id") + .value(assayId) + .build()) + .build(), + MarsPath.builder() + .key("dataFiles") + .where(MarsWhere.builder() + .key(isaDataFileKeyValue.getKey()) + .value(isaDataFileKeyValue.getValue()) + .build()) + .build() + }; + } + // --------------------------------- // | Making Mars accession objects | // --------------------------------- protected MarsAccession getStudyMarsAccession(final ReceiptAccessionMap studyAccessionMap) { return MarsAccession.builder() - .path( - new ArrayList() { - { - add(MarsPath.builder().key("investigation").build()); - add(MarsPath.builder() - .key("studies") - .where( - MarsWhere.builder() - .key(studyAccessionMap.isaKeyName) - .value(studyAccessionMap.keyValue) - .build()) - .build()); - } - }) + .path(List.of(getStudyMarsPath(Map.entry(studyAccessionMap.isaFieldKey, studyAccessionMap.isaFieldValue)))) .value(studyAccessionMap.accession) .build(); } @@ -218,27 +344,8 @@ protected MarsAccession getSampleMarsAccession( final ReceiptAccessionMap studyAccessionMap, final ReceiptAccessionMap sampleAccessionMap) { return MarsAccession.builder() - .path( - new ArrayList() { - { - add(MarsPath.builder().key("investigation").build()); - add(MarsPath.builder() - .key("studies") - .where(MarsWhere.builder() - .key(studyAccessionMap.isaKeyName) - .value(studyAccessionMap.keyValue) - .build()) - .build()); - add(MarsPath.builder().key("materials").build()); - add(MarsPath.builder() - .key("samples") - .where(MarsWhere.builder() - .key(sampleAccessionMap.isaKeyName) - .value(sampleAccessionMap.keyValue) - .build()) - .build()); - } - }) + .path(List.of(getSampleMarsPath(Map.entry(studyAccessionMap.isaFieldKey, studyAccessionMap.isaFieldValue), + Map.entry(sampleAccessionMap.isaFieldKey, sampleAccessionMap.isaFieldValue)))) .value(sampleAccessionMap.accession) .build(); } @@ -247,27 +354,8 @@ protected MarsAccession getSourceMarsAccession( final ReceiptAccessionMap studyAccessionMap, final ReceiptAccessionMap sourceAccessionMap) { return MarsAccession.builder() - .path( - new ArrayList() { - { - add(MarsPath.builder().key("investigation").build()); - add(MarsPath.builder() - .key("studies") - .where(MarsWhere.builder() - .key(studyAccessionMap.isaKeyName) - .value(studyAccessionMap.keyValue) - .build()) - .build()); - add(MarsPath.builder().key("materials").build()); - add(MarsPath.builder() - .key("sources") - .where(MarsWhere.builder() - .key(sourceAccessionMap.isaKeyName) - .value(sourceAccessionMap.keyValue) - .build()) - .build()); - } - }) + .path(List.of(getSourceMarsPath(Map.entry(studyAccessionMap.isaFieldKey, studyAccessionMap.isaFieldValue), + Map.entry(sourceAccessionMap.isaFieldKey, sourceAccessionMap.isaFieldValue)))) .value(sourceAccessionMap.accession) .build(); } @@ -277,34 +365,10 @@ protected MarsAccession getOtherMaterialMarsAccession( final String assayId, final ReceiptAccessionMap otherMaterialAccessionMap) { return MarsAccession.builder() - .path( - new ArrayList() { - { - add(MarsPath.builder().key("investigation").build()); - add(MarsPath.builder() - .key("studies") - .where(MarsWhere.builder() - .key(studyAccessionMap.isaKeyName) - .value(studyAccessionMap.keyValue) - .build()) - .build()); - add(MarsPath.builder() - .key("assays") - .where(MarsWhere.builder() - .key("@id") - .value(assayId) - .build()) - .build()); - add(MarsPath.builder().key("materials").build()); - add(MarsPath.builder() - .key("otherMaterials") - .where(MarsWhere.builder() - .key(otherMaterialAccessionMap.isaKeyName) - .value(otherMaterialAccessionMap.keyValue) - .build()) - .build()); - } - }) + .path(List.of(getOtherMaterialMarsPath( + Map.entry(studyAccessionMap.isaFieldKey, studyAccessionMap.isaFieldValue), + assayId, + Map.entry(otherMaterialAccessionMap.isaFieldKey, otherMaterialAccessionMap.isaFieldValue)))) .value(otherMaterialAccessionMap.accession) .build(); } @@ -314,33 +378,9 @@ protected MarsAccession getDataFileMarsAccession( final String assayId, final ReceiptAccessionMap dataFileAccessionMap) { return MarsAccession.builder() - .path( - new ArrayList() { - { - add(MarsPath.builder().key("investigation").build()); - add(MarsPath.builder() - .key("studies") - .where(MarsWhere.builder() - .key(studyAccessionMap.isaKeyName) - .value(studyAccessionMap.keyValue) - .build()) - .build()); - add(MarsPath.builder() - .key("assays") - .where(MarsWhere.builder() - .key("@id") - .value(assayId) - .build()) - .build()); - add(MarsPath.builder() - .key("dataFiles") - .where(MarsWhere.builder() - .key(dataFileAccessionMap.isaKeyName) - .value(dataFileAccessionMap.keyValue) - .build()) - .build()); - } - }) + .path(List.of(getDataFileMarsPath(Map.entry(studyAccessionMap.isaFieldKey, studyAccessionMap.isaFieldValue), + assayId, + Map.entry(dataFileAccessionMap.isaFieldKey, dataFileAccessionMap.isaFieldValue)))) .value(dataFileAccessionMap.accession) .build(); } @@ -354,15 +394,15 @@ private ReceiptAccessionMap getAccessionMapEntry( try { return new ReceiptAccessionMap() { { - Field field = item.getClass().getField(accessionsMap.keyName); + Field field = item.getClass().getField(accessionsMap.isaItemName); if (field.isAnnotationPresent(JsonProperty.class)) { - isaKeyName = field.getAnnotation(JsonProperty.class).value(); + isaFieldKey = field.getAnnotation(JsonProperty.class).value(); } else { - isaKeyName = accessionsMap.keyName; + isaFieldKey = accessionsMap.isaItemName; } - keyName = accessionsMap.keyName; - keyValue = field.get(item).toString(); - accession = accessionsMap.accessionMap.get(keyValue); + isaItemName = accessionsMap.isaItemName; + isaFieldValue = field.get(item).toString(); + accession = accessionsMap.accessionMap.get(isaFieldValue); } }; } catch (NoSuchFieldException | IllegalAccessException e) { @@ -372,7 +412,7 @@ private ReceiptAccessionMap getAccessionMapEntry( .message( String.format("Cannot find an item of %s with the key %s in the ISA-JSON input", item.getClass().getSimpleName(), - accessionsMap.keyName)) + accessionsMap.isaItemName)) .type(MarsErrorType.INVALID_METADATA) .build()); return new ReceiptAccessionMap(); diff --git a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/ReceiptAccessionsMap.java b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/ReceiptAccessionsMap.java index dd88d62..763f7b5 100644 --- a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/ReceiptAccessionsMap.java +++ b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/ReceiptAccessionsMap.java @@ -3,26 +3,36 @@ import java.util.HashMap; public class ReceiptAccessionsMap { + /** + * Key and accession number of ISA-JSON item + */ public HashMap accessionMap; - public String keyName; + /** + * ISA-JSON item name + */ + public String isaItemName; public ReceiptAccessionsMap() { accessionMap = new HashMap<>(); } - public ReceiptAccessionsMap(String keyName, String keyValue) { - this.keyName = keyName; + /** + * @param itemName ISA-JSON key name + * @param key ISA-JSON key value + */ + public ReceiptAccessionsMap(String itemName, String key) { + this.isaItemName = itemName; this.accessionMap = new HashMap<>() { { - put(keyValue, null); + put(key, null); } }; } public String toString() { - String result = "ReceiptAccessionsMap:" + keyName + "\n"; - for (String key: accessionMap.keySet()) { + String result = "ReceiptAccessionsMap:" + isaItemName + "\n"; + for (String key : accessionMap.keySet()) { result += key + ":" + accessionMap.get(key) + "\n"; } return result; From 87db6d6ea99ca48bb776cfd9da89ac17adc6eb0c Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Tue, 19 Nov 2024 13:05:05 +0100 Subject: [PATCH 06/12] MarsReceiptException with MarsPath --- .../receipt/MarsReceiptException.java | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptException.java b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptException.java index 0ad40f8..4cccbf3 100644 --- a/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptException.java +++ b/repository-services/receipt/src/main/java/com/elixir/biohackaton/ISAToSRA/receipt/MarsReceiptException.java @@ -1,17 +1,53 @@ package com.elixir.biohackaton.ISAToSRA.receipt; +import java.util.List; +import java.util.Optional; + +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsError; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsPath; + import lombok.Getter; public class MarsReceiptException extends RuntimeException { @Getter - private final String receiptErrorMessage; + private final MarsError error; public MarsReceiptException(final String receiptErrorMessage) { - this.receiptErrorMessage = receiptErrorMessage; + error = MarsError.builder() + .message(receiptErrorMessage) + .build(); + } + + public MarsReceiptException(final Exception exception, final String receiptErrorMessage) { + this.addSuppressed(exception); + if (exception instanceof MarsReceiptException) { + error = ((MarsReceiptException) exception).error; + } else { + error = MarsError.builder() + .message(receiptErrorMessage) + .build(); + } + } + + public MarsReceiptException(final String receiptErrorMessage, final MarsPath... errorPath) { + error = MarsError.builder() + .message(receiptErrorMessage) + .path(List.of(Optional.ofNullable(errorPath).orElse(new MarsPath[0]))) + .build(); } - public MarsReceiptException(final String receiptErrorMessage, final Exception exception) { + public MarsReceiptException( + final Exception exception, + final String receiptErrorMessage, + final MarsPath... errorPath) { this.addSuppressed(exception); - this.receiptErrorMessage = receiptErrorMessage; + if (exception instanceof MarsReceiptException) { + error = ((MarsReceiptException) exception).error; + } else { + error = MarsError.builder() + .message(receiptErrorMessage) + .path(List.of(Optional.ofNullable(errorPath).orElse(new MarsPath[0]))) + .build(); + } } } From e166fb82e0bc5f40c3974fb38890e0b7f58a9287 Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Tue, 19 Nov 2024 13:12:32 +0100 Subject: [PATCH 07/12] isajson-ena, filter invalid alias-accession pairs and set MARS errors in the receipt --- .../WebinIsaToXmlSubmissionController.java | 6 +- .../sra/service/MarsReceiptService.java | 84 +++++++++++++------ .../service/WebinExperimentXmlCreator.java | 2 +- 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java index 128a576..babc76f 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/controller/WebinIsaToXmlSubmissionController.java @@ -114,7 +114,7 @@ public String performSubmissionToEna( } catch (final MarsReceiptException e) { log.error("Mars receipt excption", e); - marsReceiptService.setMarsReceiptErrors(e.getReceiptErrorMessage()); + marsReceiptService.setMarsReceiptErrors(e.getError()); return marsReceiptService.convertMarsReceiptToJson(); } catch (final Exception e) { log.error("Internal server error", e); @@ -127,7 +127,7 @@ public List getStudies(final IsaJson isaJson) { try { return isaJson.getInvestigation().getStudies(); } catch (final Exception e) { - throw new MarsReceiptException("Failed to parse ISA JSON and get studies", e); + throw new MarsReceiptException(e, "Failed to parse ISA JSON and get studies"); } } @@ -135,7 +135,7 @@ public Investigation getInvestigation(final IsaJson isaJson) { try { return isaJson.getInvestigation(); } catch (final Exception e) { - throw new MarsReceiptException("Failed to parse ISA JSON and get studies", e); + throw new MarsReceiptException(e, "Failed to parse ISA JSON and get studies"); } } diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java index 89327c8..5edfe5f 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java @@ -1,27 +1,38 @@ /** Elixir BioHackathon 2022 */ package com.elixir.biohackaton.ISAToSRA.sra.service; -import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptProvider; -import com.elixir.biohackaton.ISAToSRA.receipt.ReceiptAccessionsMap; -import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; -import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.*; -import com.elixir.biohackaton.ISAToSRA.sra.model.Receipt; -import com.elixir.biohackaton.ISAToSRA.sra.model.ReceiptObject; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Optional; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotNull; + import org.springframework.stereotype.Service; import org.springframework.web.servlet.HandlerInterceptor; +import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptProvider; +import com.elixir.biohackaton.ISAToSRA.receipt.ReceiptAccessionsMap; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.DataFile; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.IsaJson; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.OtherMaterial; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.Study; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsError; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsErrorType; +import com.elixir.biohackaton.ISAToSRA.sra.model.Receipt; +import com.elixir.biohackaton.ISAToSRA.sra.model.ReceiptObject; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + @Service public class MarsReceiptService extends MarsReceiptProvider implements HandlerInterceptor { + private final ObjectMapper jsonMapper = new ObjectMapper(); private void setupJsonMapper() { @@ -56,13 +67,18 @@ public void setMarsReceiptErrors(String... errors) { super.setMarsReceiptErrors(MarsErrorType.INVALID_METADATA, errors); } + public void setMarsReceiptErrors(MarsError... errors) { + super.setMarsReceiptErrors(MarsErrorType.INVALID_METADATA, errors); + } + /** * Converting ENA receipt to Mars data format * - * @see - * https://github.com/elixir-europe/MARS/blob/refactor/repository-services/repository-api.md#response * @param receipt {@link Receipt} Receipt from ENA * @param isaJson {@link IsaJson} Requested ISA-Json + * @see Repository + * API response */ public void convertReceiptToMars(final Receipt receipt, final IsaJson isaJson) { buildMarsReceipt( @@ -78,27 +94,47 @@ public void convertReceiptToMars(final Receipt receipt, final IsaJson isaJson) { isaJson); } - private static String getPreRandomizedAlias(ReceiptObject receiptObject) { - // Convert Arabidopsis thaliana-0.49105604184136276 -> Arabidopsis thaliana - String alias = receiptObject.getAlias(); - return alias.substring(0, alias.lastIndexOf("-")); - } - private ReceiptAccessionsMap getAliasAccessionPairs( String keyNameInput, final List items) { + Predicate aliasAccessionPairValidateFn = this::aliasAccessionPairFilter; + Function getPreRandomizedAliasFn = this::getPreRandomizedAlias; + return new ReceiptAccessionsMap() { { - keyName = keyNameInput; + isaItemName = keyNameInput; accessionMap = - new HashMap( + new HashMap<>( Optional.ofNullable(items).orElse(new ArrayList<>()).stream() - .filter(item -> item != null) - .filter(item -> item.getAccession() != null) + .filter(aliasAccessionPairValidateFn) .collect( - Collectors.toMap( - MarsReceiptService::getPreRandomizedAlias, - ReceiptObject::getAccession))); + Collectors.toMap(getPreRandomizedAliasFn, ReceiptObject::getAccession))); } }; } + + private boolean aliasAccessionPairFilter(ReceiptObject item) { + if (item == null) { + setMarsReceiptErrors("ENA receipt: Item is NULL"); + return false; + } + boolean valid = true; + if (item.getAlias() == null) { + setMarsReceiptErrors("ENA receipt: Alias is NULL"); + valid = false; + } + if (item.getAccession() == null) { + setMarsReceiptErrors( + String.format("ENA receipt: Accession number of %s is NULL", item.getAlias())); + valid = false; + } + return valid; + } + + private String getPreRandomizedAlias(@NotNull ReceiptObject receiptObject) { + // Convert Arabidopsis thaliana-0.49105604184136276 -> Arabidopsis thaliana + final String alias = receiptObject.getAlias(); + final int lastIndexOfAcceptableAlias = alias.lastIndexOf('-'); + return alias.substring( + 0, lastIndexOfAcceptableAlias > 0 ? lastIndexOfAcceptableAlias : alias.length()); + } } diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinExperimentXmlCreator.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinExperimentXmlCreator.java index fa20ad3..9872dbd 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinExperimentXmlCreator.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/WebinExperimentXmlCreator.java @@ -34,7 +34,7 @@ public Map createENAExperimentSetElement( randomSubmissionIdentifier); } catch (final Exception e) { throw new MarsReceiptException( - "Failed to parse experiments from ISA Json file and create ENA Experiments", e); + e, "Failed to parse experiments from ISA Json file and create ENA Experiments"); } } From d9aa6ab138b8a2b219295ba1edb420a1b68ac198 Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Tue, 19 Nov 2024 13:13:28 +0100 Subject: [PATCH 08/12] isajson-ena, Java 11 in gradle config --- repository-services/isajson-ena/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/repository-services/isajson-ena/build.gradle b/repository-services/isajson-ena/build.gradle index 38301c8..63fdcde 100644 --- a/repository-services/isajson-ena/build.gradle +++ b/repository-services/isajson-ena/build.gradle @@ -5,6 +5,9 @@ plugins { id 'java' } +sourceCompatibility = 11 +targetCompatibility = 11 + group = 'com.elixir.biohackaton' version = '0.0.1-SNAPSHOT' From 225f4dc9219f935eb8a45595099531eeefd62bc5 Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Tue, 19 Nov 2024 13:20:58 +0100 Subject: [PATCH 09/12] EnaReceiptToMarsTest, validInput & invalidInput --- .../ISAToSRA/EnaReceiptToMarsTest.java | 56 ++++++++----- test-data/ena-receipt-invalid.json | 58 ++++++++++++++ test-data/mars-ena-receipt-invalid.json | 80 +++++++++++++++++++ test-data/mars-ena-receipt.json | 27 +------ 4 files changed, 176 insertions(+), 45 deletions(-) create mode 100644 test-data/ena-receipt-invalid.json create mode 100644 test-data/mars-ena-receipt-invalid.json diff --git a/repository-services/isajson-ena/src/test/java/com/elixir/biohackaton/ISAToSRA/EnaReceiptToMarsTest.java b/repository-services/isajson-ena/src/test/java/com/elixir/biohackaton/ISAToSRA/EnaReceiptToMarsTest.java index 23a9bfe..40f79d3 100644 --- a/repository-services/isajson-ena/src/test/java/com/elixir/biohackaton/ISAToSRA/EnaReceiptToMarsTest.java +++ b/repository-services/isajson-ena/src/test/java/com/elixir/biohackaton/ISAToSRA/EnaReceiptToMarsTest.java @@ -1,8 +1,8 @@ /** Elixir BioHackathon 2022 */ package com.elixir.biohackaton.ISAToSRA; +import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptException; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; -import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.*; import com.elixir.biohackaton.ISAToSRA.sra.model.Receipt; import com.elixir.biohackaton.ISAToSRA.sra.service.MarsReceiptService; import com.fasterxml.jackson.databind.ObjectMapper; @@ -15,29 +15,47 @@ class EnaReceiptToMarsTest { @Test - void convertToMars() { - try { + void convertToMars_validInput() { + String enaReceiptFilePath = "../../test-data/ena-receipt.json"; + String marsReceiptPath = "../../test-data/mars-ena-receipt.json"; + convertToMars(enaReceiptFilePath, marsReceiptPath); + } + + @Test + void convertToMars_invalidInput() { + String enaReceiptFilePath = "../../test-data/ena-receipt-invalid.json"; + String marsReceiptPath = "../../test-data/mars-ena-receipt-invalid.json"; + convertToMars(enaReceiptFilePath, marsReceiptPath); + } - // Reading Inputs - String enaReceiptFilePath = "../../test-data/ena-receipt.json"; - String isaJsonFilePath = "../../test-data/biosamples-input-isa.json"; - String receiptFile = Files.readString(new File(enaReceiptFilePath).toPath()); - String isaJsonFile = Files.readString(new File(isaJsonFilePath).toPath()); + void convertToMars(final String enaReceiptFilePath, final String marsReceiptPath) { + ObjectMapper jsonMapper = new ObjectMapper(); + MarsReceiptService marsReceiptService = new MarsReceiptService(); + try { + try { + // Reading Inputs + String receiptFile = Files.readString(new File(enaReceiptFilePath).toPath()); + String isaJsonFilePath = "../../test-data/biosamples-modified-isa.json"; + String isaJsonFile = Files.readString(new File(isaJsonFilePath).toPath()); - // Mapping inputs to the proper objects - ObjectMapper jsonMapper = new ObjectMapper(); - Receipt receipt = jsonMapper.readValue(receiptFile, Receipt.class); - IsaJson isaJson = jsonMapper.readValue(isaJsonFile, IsaJson.class); + // Mapping inputs to the proper objects + Receipt receipt = jsonMapper.readValue(receiptFile, Receipt.class); + IsaJson isaJson = jsonMapper.readValue(isaJsonFile, IsaJson.class); - // Converting ENA receipt to MARS receipt - MarsReceiptService marsReceiptService = new MarsReceiptService(); - MarsReceipt marsReceipt = marsReceiptService.convertReceiptToMars(receipt, isaJson); + // Converting ENA receipt to MARS receipt + marsReceiptService.convertReceiptToMars(receipt, isaJson); + } catch (MarsReceiptException e) { + marsReceiptService.setMarsReceiptErrors(e.getError()); + } catch (Exception e) { + marsReceiptService.setMarsReceiptErrors(e.getMessage()); + } // Saving the result as a Json file - String marsReceiptPath = "../../test-data/mars-ena-receipt.json"; - Files.write(new File(marsReceiptPath).toPath(), jsonMapper.writeValueAsBytes(marsReceipt)); - } catch (Exception ex) { - System.console().printf("%s", ex); + Files.write( + new File(marsReceiptPath).toPath(), + jsonMapper.writeValueAsBytes(marsReceiptService.getMarsReceipt())); + } catch (Exception e) { + e.printStackTrace(); } } } diff --git a/test-data/ena-receipt-invalid.json b/test-data/ena-receipt-invalid.json new file mode 100644 index 0000000..c882c0e --- /dev/null +++ b/test-data/ena-receipt-invalid.json @@ -0,0 +1,58 @@ +{ + "success": true, + "receiptDate": "2023-11-16T10:44:41.618Z", + "experiments": [ + { + "alias": "#other_material/332-0.5578006304577448", + "accession": "ERX13332762", + "status": "PRIVATE" + }, + { + "alias": "#other_material/333-0.5578006304577448", + "accession": "ERX13332763", + "status": "PRIVATE" + } + ], + "runs": [ + { + "alias": "#assay/18_20_21-0.5578006304577448", + "accession": "ERR13930853", + "status": "PRIVATE" + } + ], + "studies":[ + { + "alias":"Arabidopsis thaliana-0.5578006304577448", + "status":"PRIVATE", + "holdUntilDate": "2023-01-01Z", + "externalAccession": { + "id": "PRJEB82366", + "db": "Project" + } + } + ], + "projects": [ + { + "alias": "Bob's investigation-0.5578006304577448", + "accession": "PRJEB82365", + "status": "PRIVATE", + "holdUntilDate": "2023-01-01Z", + "externalAccession": { + "id": "ERP166076", + "db": "study" + } + } + ], + "submission": { + "alias": "SUBMISSION-07-11-2024-17:00:52:797", + "accession": "ERA30928821" + }, + "messages": { + "info": [ + "All objects in this submission are set to private status (HOLD)." + ] + }, + "actions": [ + "ADD" + ] +} \ No newline at end of file diff --git a/test-data/mars-ena-receipt-invalid.json b/test-data/mars-ena-receipt-invalid.json new file mode 100644 index 0000000..475a572 --- /dev/null +++ b/test-data/mars-ena-receipt-invalid.json @@ -0,0 +1,80 @@ +{ + "targetRepository": "ena", + "errors": [ + { + "type": "INVALID_METADATA", + "message": "ENA receipt: Accession number of Arabidopsis thaliana-0.5578006304577448 is NULL" + } + ], + "info": [ + { + "message": "All objects in this submission are set to private status (HOLD)." + } + ], + "accessions": [ + { + "value": "ERX13332762", + "path": [ + { + "key": "investigation" + }, + { + "key": "studies", + "where": { + "key": "title", + "value": "Arabidopsis thaliana" + } + }, + { + "key": "assays", + "where": { + "key": "@id", + "value": "#assay/18_20_21" + } + }, + { + "key": "materials" + }, + { + "key": "otherMaterials", + "where": { + "key": "@id", + "value": "#other_material/332" + } + } + ] + }, + { + "value": "ERX13332763", + "path": [ + { + "key": "investigation" + }, + { + "key": "studies", + "where": { + "key": "title", + "value": "Arabidopsis thaliana" + } + }, + { + "key": "assays", + "where": { + "key": "@id", + "value": "#assay/18_20_21" + } + }, + { + "key": "materials" + }, + { + "key": "otherMaterials", + "where": { + "key": "@id", + "value": "#other_material/333" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/test-data/mars-ena-receipt.json b/test-data/mars-ena-receipt.json index fc7572b..727bde4 100644 --- a/test-data/mars-ena-receipt.json +++ b/test-data/mars-ena-receipt.json @@ -1,5 +1,5 @@ { - "targetRepository": "ena.embl", + "targetRepository": "ena", "errors": [], "info": [ { @@ -22,31 +22,6 @@ } ] }, - { - "value": "ERS27605861", - "path": [ - { - "key": "investigation" - }, - { - "key": "studies", - "where": { - "key": "title", - "value": "Arabidopsis thaliana" - } - }, - { - "key": "materials" - }, - { - "key": "samples", - "where": { - "key": "@id", - "value": "#sample/331" - } - } - ] - }, { "value": "ERX9223136", "path": [ From f6b97a0da0573d1b3d2df2b601bb0310aa25f8bc Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Wed, 4 Dec 2024 09:28:06 +0100 Subject: [PATCH 10/12] MARS receipt with exception handling for isajson-biosamples --- .../BioSampleSubmissionController.java | 4 +- .../service/BioSamplesSubmitter.java | 102 +++++++++++------- .../service/MarsReceiptService.java | 11 +- 3 files changed, 71 insertions(+), 46 deletions(-) diff --git a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java index baf4ec5..bd9e27b 100644 --- a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java +++ b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/controller/BioSampleSubmissionController.java @@ -65,7 +65,7 @@ public String performSubmissionToBioSamplesAndEna( return marsReceiptService.convertMarsReceiptToJson(); } catch (final MarsReceiptException e) { log.error("Mars receipt excption", e); - marsReceiptService.setMarsReceiptErrors(e.getReceiptErrorMessage()); + marsReceiptService.setMarsReceiptErrors(e.getError()); return marsReceiptService.convertMarsReceiptToJson(); } catch (final Exception e) { log.error("Internal server error", e); @@ -78,7 +78,7 @@ public List getStudies(final IsaJson isaJson) { try { return isaJson.getInvestigation().getStudies(); } catch (final Exception e) { - throw new MarsReceiptException("Failed to parse ISA JSON and get studies", e); + throw new MarsReceiptException(e, "Failed to parse ISA JSON and get studies"); } } } diff --git a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/BioSamplesSubmitter.java b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/BioSamplesSubmitter.java index ced6377..4872c1f 100644 --- a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/BioSamplesSubmitter.java +++ b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/BioSamplesSubmitter.java @@ -1,18 +1,14 @@ /** Elixir BioHackathon 2022 */ package com.elixir.biohackaton.ISAToSRA.biosamples.service; -import com.elixir.biohackaton.ISAToSRA.biosamples.model.Attribute; -import com.elixir.biohackaton.ISAToSRA.biosamples.model.BiosampleAccessionsMap; -import com.elixir.biohackaton.ISAToSRA.biosamples.model.Relationship; -import com.elixir.biohackaton.ISAToSRA.biosamples.model.BioSample; -import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptException; -import com.elixir.biohackaton.ISAToSRA.receipt.ReceiptAccessionsMap; -import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; - import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicReference; -import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.hateoas.EntityModel; import org.springframework.http.HttpEntity; @@ -22,10 +18,28 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; +import com.elixir.biohackaton.ISAToSRA.biosamples.model.Attribute; +import com.elixir.biohackaton.ISAToSRA.biosamples.model.BioSample; +import com.elixir.biohackaton.ISAToSRA.biosamples.model.BiosampleAccessionsMap; +import com.elixir.biohackaton.ISAToSRA.biosamples.model.Relationship; +import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptException; +import com.elixir.biohackaton.ISAToSRA.receipt.ReceiptAccessionsMap; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.Category; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.Characteristic; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.Sample; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.Source; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.Study; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.Value; + +import lombok.extern.slf4j.Slf4j; + @Service @Slf4j public class BioSamplesSubmitter { + @Autowired + private MarsReceiptService marsReceiptService; + public BiosampleAccessionsMap createBioSamples(final List studies, final String webinToken) { final BiosampleAccessionsMap typeToBioSamplesAccessionMap = new BiosampleAccessionsMap(); @@ -39,7 +53,7 @@ public BiosampleAccessionsMap createBioSamples(final List studies, final } } - typeToBioSamplesAccessionMap.sourceAccessionsMap.keyName = Source.Fields.name; + typeToBioSamplesAccessionMap.sourceAccessionsMap.isaItemName = Source.Fields.name; typeToBioSamplesAccessionMap.sourceAccessionsMap.accessionMap.put( sourceBioSample.getName(), sourceBioSample.getAccession()); @@ -52,36 +66,44 @@ public BiosampleAccessionsMap createBioSamples(final List studies, final typeToBioSamplesAccessionMap.studyAccessionsMap = new ReceiptAccessionsMap( Study.Fields.title, study.getTitle()); - study .getMaterials() .getSamples() .forEach( sample -> { - final BioSample persistedChildSample = this.createAndUpdateChildSampleWithRelationship( - sample, - sourceBioSample.getAccession(), - finalSourceBioSampleOrganismAttribute.getValue(), - webinToken); - - if (persistedChildSample != null) { - final Characteristic biosampleAccessionCharacteristic = getBioSampleAccessionCharacteristic( - new AtomicReference<>(persistedChildSample)); - final ArrayList sampleCharacteristics = sample.getCharacteristics() != null - ? sample.getCharacteristics() - : new ArrayList<>(); - sampleCharacteristics.add(biosampleAccessionCharacteristic); - - typeToBioSamplesAccessionMap.sampleAccessionsMap.keyName = Sample.Fields.name; - typeToBioSamplesAccessionMap.sampleAccessionsMap.accessionMap.put( - persistedChildSample.getName(), - persistedChildSample.getAccession()); + try { + final BioSample persistedChildSample = this.createAndUpdateChildSampleWithRelationship( + sample, + sourceBioSample.getAccession(), + finalSourceBioSampleOrganismAttribute.getValue(), + webinToken); + + if (persistedChildSample != null) { + final Characteristic biosampleAccessionCharacteristic = getBioSampleAccessionCharacteristic( + new AtomicReference<>(persistedChildSample)); + final ArrayList sampleCharacteristics = sample + .getCharacteristics() != null + ? sample.getCharacteristics() + : new ArrayList<>(); + sampleCharacteristics.add(biosampleAccessionCharacteristic); + + typeToBioSamplesAccessionMap.sampleAccessionsMap.isaItemName = Sample.Fields.name; + typeToBioSamplesAccessionMap.sampleAccessionsMap.accessionMap.put( + persistedChildSample.getName(), + persistedChildSample.getAccession()); + } + } catch (Exception e) { + throw new MarsReceiptException(e, + "Failed to parse ISA Json and create samples in BioSamples (SAMPLE)", + marsReceiptService.getSampleMarsPath( + Map.entry(Study.Fields.title, study.title), + Map.entry(Sample.Fields.id, sample.id))); } }); }); } } catch (final Exception e) { - throw new MarsReceiptException("Failed to parse ISA Json and create samples in BioSamples", e); + throw new MarsReceiptException(e, "Failed to parse ISA Json and create samples in BioSamples"); } return typeToBioSamplesAccessionMap; @@ -96,8 +118,8 @@ private BioSample createAndUpdateChildSampleWithRelationship( .withRelease(Instant.now()) .withAttributes( List.of(Attribute.build("organism", parentSampleOrganism), - Attribute.build("collection date", "not provided"), - Attribute.build("geographic location (country and/or sea)", "not provided"))) + Attribute.build("collection date", "not provided"), + Attribute.build("geographic location (country and/or sea)", "not provided"))) .build(); try { final EntityModel persistedSampleEntity = this.createSampleInBioSamples(bioSample, webinToken); @@ -123,7 +145,7 @@ private BioSample createAndUpdateChildSampleWithRelationship( return null; } } catch (final Exception e) { - throw new MarsReceiptException("Failed to handle child samples", e); + throw new MarsReceiptException(e, "Failed to handle child samples"); } } @@ -151,8 +173,8 @@ private BioSample createSourceBioSample(final List studies, final String final BioSample sourceSample = new BioSample.Builder(source.getName()) .withRelease(Instant.now()) .withAttributes(List.of(organismAttribute.get(), - Attribute.build("collection date", "not provided"), - Attribute.build("geographic location (country and/or sea)", "not provided"))) + Attribute.build("collection date", "not provided"), + Attribute.build("geographic location (country and/or sea)", "not provided"))) .build(); final EntityModel persistedParentSampleEntity = this.createSampleInBioSamples(sourceSample, webinToken); @@ -205,8 +227,8 @@ private BioSample updateSampleWithRelationshipsToBioSamples( new ParameterizedTypeReference<>() { }); return biosamplesResponse.getBody().getContent(); - } catch (final Exception ex) { - throw new MarsReceiptException("Failed to add relationships to child samples", ex); + } catch (final Exception e) { + throw new MarsReceiptException(e, "Failed to add relationships to child samples"); } } @@ -227,8 +249,8 @@ private EntityModel createSampleInBioSamples( }); return biosamplesResponse.getBody(); - } catch (final Exception ex) { - throw new MarsReceiptException("Failed to create samples in BioSamples", ex); + } catch (final Exception e) { + throw new MarsReceiptException(e, "Failed to create samples in BioSamples"); } } diff --git a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java index 9403eca..8c9921b 100644 --- a/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java +++ b/repository-services/isajson-biosamples/src/main/java/com/elixir/biohackaton/ISAToSRA/biosamples/service/MarsReceiptService.java @@ -10,6 +10,7 @@ import com.elixir.biohackaton.ISAToSRA.biosamples.model.BiosampleAccessionsMap; import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptProvider; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.IsaJson; +import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsError; import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.MarsErrorType; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; @@ -51,13 +52,15 @@ public void setMarsReceiptErrors(String... errors) { super.setMarsReceiptErrors(MarsErrorType.INVALID_METADATA, errors); } + public void setMarsReceiptErrors(MarsError... errors) { + super.setMarsReceiptErrors(MarsErrorType.INVALID_METADATA, errors); + } + /** * Converting BioSample receipt to Mars data format * - * @see - * https://github.com/elixir-europe/MARS/blob/refactor/repository-services/repository-api.md#response - * @param biosampleAccessionsMap {@link BiosampleAccessionsMap} Receipt from - * Biosample + * @see Repository API Specification + * @param biosampleAccessionsMap {@link BiosampleAccessionsMap} Receipt from Biosample * @param isaJson {@link IsaJson} Requested ISA-Json */ public void convertReceiptToMars(final BiosampleAccessionsMap biosampleAccessionsMap, final IsaJson isaJson) { From f39f1989f024c0b75a09d8670abc55abd3b80059 Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Wed, 4 Dec 2024 09:30:33 +0100 Subject: [PATCH 11/12] isajson-biosamples test is updated to be synced with the new changes on mars-Receipt --- .../ISAToSRA/BiosampleReceiptToMarsTest.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/repository-services/isajson-biosamples/src/test/java/com/elixir/biohackaton/ISAToSRA/BiosampleReceiptToMarsTest.java b/repository-services/isajson-biosamples/src/test/java/com/elixir/biohackaton/ISAToSRA/BiosampleReceiptToMarsTest.java index bfb1378..20987bd 100644 --- a/repository-services/isajson-biosamples/src/test/java/com/elixir/biohackaton/ISAToSRA/BiosampleReceiptToMarsTest.java +++ b/repository-services/isajson-biosamples/src/test/java/com/elixir/biohackaton/ISAToSRA/BiosampleReceiptToMarsTest.java @@ -1,13 +1,6 @@ /** Elixir BioHackathon 2022 */ package com.elixir.biohackaton.ISAToSRA; -import com.elixir.biohackaton.ISAToSRA.biosamples.model.BiosampleAccessionsMap; -import com.elixir.biohackaton.ISAToSRA.biosamples.service.BioSamplesSubmitter; -import com.elixir.biohackaton.ISAToSRA.biosamples.service.MarsReceiptService; -import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.*; -import com.elixir.biohackaton.ISAToSRA.receipt.marsmodel.*; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.nio.file.Files; import java.util.List; @@ -15,6 +8,14 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import com.elixir.biohackaton.ISAToSRA.biosamples.model.BiosampleAccessionsMap; +import com.elixir.biohackaton.ISAToSRA.biosamples.service.BioSamplesSubmitter; +import com.elixir.biohackaton.ISAToSRA.biosamples.service.MarsReceiptService; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.IsaJson; +import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.Study; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; + @SpringBootTest class BiosampleReceiptToMarsTest { @@ -43,11 +44,11 @@ void convertToMars() { // Converting Biosample receipt to MARS receipt MarsReceiptService marsReceiptService = new MarsReceiptService(); - MarsReceipt marsReceipt = marsReceiptService.convertReceiptToMars(accessionsMap, isaJson); + marsReceiptService.convertReceiptToMars(accessionsMap, isaJson); // Saving the result as a Json file String marsReceiptPath = "../../test-data/mars-biosample-receipt.json"; - Files.write(new File(marsReceiptPath).toPath(), jsonMapper.writeValueAsBytes(marsReceipt)); + Files.write(new File(marsReceiptPath).toPath(), jsonMapper.writeValueAsBytes(marsReceiptService.getMarsReceipt())); } catch (Exception ex) { System.console().printf("%s", ex); } From 6317c9b630b06e9823b0d6e1d477977750a6a3a7 Mon Sep 17 00:00:00 2001 From: "Pedram A. Keyvani" Date: Wed, 4 Dec 2024 09:50:10 +0100 Subject: [PATCH 12/12] :spotlessApply for isajson-ena --- .../sra/service/MarsReceiptService.java | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java index 5edfe5f..32774da 100644 --- a/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java +++ b/repository-services/isajson-ena/src/main/java/com/elixir/biohackaton/ISAToSRA/sra/service/MarsReceiptService.java @@ -1,21 +1,6 @@ /** Elixir BioHackathon 2022 */ package com.elixir.biohackaton.ISAToSRA.sra.service; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.validation.constraints.NotNull; - -import org.springframework.stereotype.Service; -import org.springframework.web.servlet.HandlerInterceptor; - import com.elixir.biohackaton.ISAToSRA.receipt.MarsReceiptProvider; import com.elixir.biohackaton.ISAToSRA.receipt.ReceiptAccessionsMap; import com.elixir.biohackaton.ISAToSRA.receipt.isamodel.DataFile; @@ -29,6 +14,18 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotNull; +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.HandlerInterceptor; @Service public class MarsReceiptService extends MarsReceiptProvider implements HandlerInterceptor {