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; + } +}