From f3f9104c56f7bc71afba1617b8985dd70d48e968 Mon Sep 17 00:00:00 2001 From: nkumar2 Date: Fri, 3 May 2024 14:01:29 +0100 Subject: [PATCH] saving metadata json --- pom.xml | 5 ++ .../submission/controller/BaseController.java | 4 +- .../submissionws/SubmissionController.java | 16 ++++-- .../submission/entity/SubmissionDetails.java | 50 +++++++++++++------ .../RequiredFieldsMissingException.java | 7 +++ .../SubmissionDetailsRepository.java | 1 + .../submission/service/SubmissionService.java | 25 +++++++++- .../SubmissionWSIntegrationTest.java | 50 +++++++++++++++++-- 8 files changed, 131 insertions(+), 27 deletions(-) create mode 100644 src/main/java/uk/ac/ebi/eva/submission/exception/RequiredFieldsMissingException.java diff --git a/pom.xml b/pom.xml index 06e2616..bc06050 100644 --- a/pom.xml +++ b/pom.xml @@ -74,6 +74,11 @@ gson 2.10.1 + + io.hypersistence + hypersistence-utils-hibernate-55 + 3.7.5 + diff --git a/src/main/java/uk/ac/ebi/eva/submission/controller/BaseController.java b/src/main/java/uk/ac/ebi/eva/submission/controller/BaseController.java index 4e1171c..fc64cce 100644 --- a/src/main/java/uk/ac/ebi/eva/submission/controller/BaseController.java +++ b/src/main/java/uk/ac/ebi/eva/submission/controller/BaseController.java @@ -39,7 +39,9 @@ public Submission stripUserDetails(Submission submission) { Submission responseSubmission = new Submission(submission.getSubmissionId()); responseSubmission.setStatus(submission.getStatus()); responseSubmission.setUploadUrl(submission.getUploadUrl()); - + responseSubmission.setInitiationTime(submission.getInitiationTime()); + responseSubmission.setUploadedTime(submission.getUploadedTime()); + responseSubmission.setCompletionTime(submission.getCompletionTime()); return responseSubmission; } } diff --git a/src/main/java/uk/ac/ebi/eva/submission/controller/submissionws/SubmissionController.java b/src/main/java/uk/ac/ebi/eva/submission/controller/submissionws/SubmissionController.java index 1d45f07..34d4989 100644 --- a/src/main/java/uk/ac/ebi/eva/submission/controller/submissionws/SubmissionController.java +++ b/src/main/java/uk/ac/ebi/eva/submission/controller/submissionws/SubmissionController.java @@ -1,5 +1,6 @@ package uk.ac.ebi.eva.submission.controller.submissionws; +import com.fasterxml.jackson.databind.JsonNode; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; @@ -10,6 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -17,6 +19,7 @@ import uk.ac.ebi.eva.submission.controller.BaseController; import uk.ac.ebi.eva.submission.entity.Submission; import uk.ac.ebi.eva.submission.entity.SubmissionAccount; +import uk.ac.ebi.eva.submission.exception.RequiredFieldsMissingException; import uk.ac.ebi.eva.submission.model.SubmissionStatus; import uk.ac.ebi.eva.submission.service.LsriTokenService; import uk.ac.ebi.eva.submission.service.SubmissionService; @@ -81,15 +84,20 @@ public ResponseEntity initiateSubmission(@RequestHeader("Authorization") Stri }) @PutMapping("submission/{submissionId}/uploaded") public ResponseEntity markSubmissionUploaded(@RequestHeader("Authorization") String bearerToken, - @PathVariable("submissionId") String submissionId) { + @PathVariable("submissionId") String submissionId, + @RequestBody JsonNode metadataJson) { SubmissionAccount submissionAccount = this.getSubmissionAccount(bearerToken); if (Objects.isNull(submissionAccount) || !submissionService.checkUserHasAccessToSubmission(submissionAccount, submissionId)) { return new ResponseEntity<>("Unauthorized", HttpStatus.UNAUTHORIZED); } - Submission submission = this.submissionService.markSubmissionUploaded(submissionId); - submissionService.sendMailNotificationForStatusUpdate(submissionAccount, submissionId, SubmissionStatus.UPLOADED, true); - return new ResponseEntity<>(stripUserDetails(submission), HttpStatus.OK); + try { + Submission submission = this.submissionService.uploadMetadataJsonAndMarkUploaded(submissionId, metadataJson); + submissionService.sendMailNotificationForStatusUpdate(submissionAccount, submissionId, SubmissionStatus.UPLOADED, true); + return new ResponseEntity<>(stripUserDetails(submission), HttpStatus.OK); + } catch (RequiredFieldsMissingException ex) { + return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); + } } @Operation(summary = "Given a submission id, this endpoint retrieves the current status of a submission") diff --git a/src/main/java/uk/ac/ebi/eva/submission/entity/SubmissionDetails.java b/src/main/java/uk/ac/ebi/eva/submission/entity/SubmissionDetails.java index a1e859d..e071dbe 100644 --- a/src/main/java/uk/ac/ebi/eva/submission/entity/SubmissionDetails.java +++ b/src/main/java/uk/ac/ebi/eva/submission/entity/SubmissionDetails.java @@ -1,5 +1,9 @@ package uk.ac.ebi.eva.submission.entity; +import com.fasterxml.jackson.databind.JsonNode; +import io.hypersistence.utils.hibernate.type.json.JsonType; +import org.hibernate.annotations.TypeDef; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @@ -9,8 +13,8 @@ @Entity @Table(schema = "eva_submissions", name = "submission_details") +@TypeDef(typeClass = JsonType.class, defaultForType = JsonNode.class) public class SubmissionDetails { - @Id @Column(name = "submission_id") private String submissionId; @@ -19,18 +23,20 @@ public class SubmissionDetails { @PrimaryKeyJoinColumn(name = "submission_id", referencedColumnName = "submission_id") private Submission submission; - @Column(nullable = false, name = "project_alias") - private String projectAlias; + @Column(nullable = false, name = "project_title") + private String projectTitle; - @Column(nullable = false, name = "description") - private String description; + @Column(nullable = false, name = "project_description") + private String projectDescription; - public SubmissionDetails() { + @Column(columnDefinition = "jsonb", name = "metadata_json", nullable = false) + private JsonNode metadataJson; + public SubmissionDetails() { } - public SubmissionDetails(Submission submission) { - this.submission = submission; + public SubmissionDetails(String submissionId) { + this.submissionId = submissionId; } public String getSubmissionId() { @@ -41,19 +47,31 @@ public Submission getSubmission() { return submission; } - public String getProjectAlias() { - return projectAlias; + public void setSubmission(Submission submission) { + this.submission = submission; + } + + public String getProjectTitle() { + return projectTitle; + } + + public void setProjectTitle(String projectTitle) { + this.projectTitle = projectTitle; + } + + public String getProjectDescription() { + return projectDescription; } - public void setProjectAlias(String projectAlias) { - this.projectAlias = projectAlias; + public void setProjectDescription(String projectDescription) { + this.projectDescription = projectDescription; } - public String getDescription() { - return description; + public JsonNode getMetadataJson() { + return metadataJson; } - public void setDescription(String description) { - this.description = description; + public void setMetadataJson(JsonNode metadataJson) { + this.metadataJson = metadataJson; } } diff --git a/src/main/java/uk/ac/ebi/eva/submission/exception/RequiredFieldsMissingException.java b/src/main/java/uk/ac/ebi/eva/submission/exception/RequiredFieldsMissingException.java new file mode 100644 index 0000000..392dd30 --- /dev/null +++ b/src/main/java/uk/ac/ebi/eva/submission/exception/RequiredFieldsMissingException.java @@ -0,0 +1,7 @@ +package uk.ac.ebi.eva.submission.exception; + +public class RequiredFieldsMissingException extends RuntimeException { + public RequiredFieldsMissingException(String msg) { + super(msg); + } +} diff --git a/src/main/java/uk/ac/ebi/eva/submission/repository/SubmissionDetailsRepository.java b/src/main/java/uk/ac/ebi/eva/submission/repository/SubmissionDetailsRepository.java index 7fa4f1b..de85826 100644 --- a/src/main/java/uk/ac/ebi/eva/submission/repository/SubmissionDetailsRepository.java +++ b/src/main/java/uk/ac/ebi/eva/submission/repository/SubmissionDetailsRepository.java @@ -4,4 +4,5 @@ import uk.ac.ebi.eva.submission.entity.SubmissionDetails; public interface SubmissionDetailsRepository extends CrudRepository { + SubmissionDetails findBySubmissionId(String submissionId); } diff --git a/src/main/java/uk/ac/ebi/eva/submission/service/SubmissionService.java b/src/main/java/uk/ac/ebi/eva/submission/service/SubmissionService.java index b5fd2db..7b39764 100644 --- a/src/main/java/uk/ac/ebi/eva/submission/service/SubmissionService.java +++ b/src/main/java/uk/ac/ebi/eva/submission/service/SubmissionService.java @@ -1,16 +1,18 @@ package uk.ac.ebi.eva.submission.service; +import com.fasterxml.jackson.databind.JsonNode; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import uk.ac.ebi.eva.submission.entity.Submission; import uk.ac.ebi.eva.submission.entity.SubmissionAccount; +import uk.ac.ebi.eva.submission.entity.SubmissionDetails; +import uk.ac.ebi.eva.submission.exception.RequiredFieldsMissingException; import uk.ac.ebi.eva.submission.exception.SubmissionDoesNotExistException; import uk.ac.ebi.eva.submission.model.SubmissionStatus; import uk.ac.ebi.eva.submission.repository.SubmissionAccountRepository; import uk.ac.ebi.eva.submission.repository.SubmissionDetailsRepository; import uk.ac.ebi.eva.submission.repository.SubmissionRepository; import uk.ac.ebi.eva.submission.util.EmailNotificationHelper; -import uk.ac.ebi.eva.submission.util.HTMLHelper; import uk.ac.ebi.eva.submission.util.MailSender; import java.time.LocalDateTime; @@ -19,6 +21,9 @@ @Service public class SubmissionService { + private static final String PROJECT = "project"; + private static final String TITLE = "title"; + private static final String DESCRIPTION = "description"; private final SubmissionRepository submissionRepository; @@ -68,7 +73,23 @@ public Submission initiateSubmission(SubmissionAccount submissionAccount) { return submissionRepository.save(submission); } - public Submission markSubmissionUploaded(String submissionId) { + public Submission uploadMetadataJsonAndMarkUploaded(String submissionId, JsonNode metadataJson) { + SubmissionDetails submissionDetails = new SubmissionDetails(submissionId); + try { + JsonNode project = metadataJson.get(PROJECT); + String projectTitle = project.get(TITLE).asText(); + String projectDescription = project.get(DESCRIPTION).asText(); + + submissionDetails.setProjectTitle(projectTitle); + submissionDetails.setProjectDescription(projectDescription); + } catch (Exception e) { + throw new RequiredFieldsMissingException("Required fields project title and project description " + + "could not be found in metadata json"); + } + + submissionDetails.setMetadataJson(metadataJson); + submissionDetailsRepository.save(submissionDetails); + Submission submission = submissionRepository.findBySubmissionId(submissionId); submission.setStatus(SubmissionStatus.UPLOADED.toString()); submission.setUploadedTime(LocalDateTime.now()); diff --git a/src/test/java/uk/ac/ebi/eva/submission/integration/SubmissionWSIntegrationTest.java b/src/test/java/uk/ac/ebi/eva/submission/integration/SubmissionWSIntegrationTest.java index 51516ed..3722b45 100644 --- a/src/test/java/uk/ac/ebi/eva/submission/integration/SubmissionWSIntegrationTest.java +++ b/src/test/java/uk/ac/ebi/eva/submission/integration/SubmissionWSIntegrationTest.java @@ -18,8 +18,10 @@ import org.testcontainers.junit.jupiter.Testcontainers; import uk.ac.ebi.eva.submission.entity.Submission; import uk.ac.ebi.eva.submission.entity.SubmissionAccount; +import uk.ac.ebi.eva.submission.entity.SubmissionDetails; import uk.ac.ebi.eva.submission.model.SubmissionStatus; import uk.ac.ebi.eva.submission.repository.SubmissionAccountRepository; +import uk.ac.ebi.eva.submission.repository.SubmissionDetailsRepository; import uk.ac.ebi.eva.submission.repository.SubmissionRepository; import uk.ac.ebi.eva.submission.service.GlobusDirectoryProvisioner; import uk.ac.ebi.eva.submission.service.GlobusTokenRefreshService; @@ -65,6 +67,9 @@ public class SubmissionWSIntegrationTest { @Autowired private SubmissionAccountRepository submissionAccountRepository; + @Autowired + private SubmissionDetailsRepository submissionDetailsRepository; + @MockBean private WebinTokenService webinTokenService; @@ -230,18 +235,21 @@ public void testSubmissionGetStatus() throws Exception { @Test @Transactional - public void testMarkSubmissionUploaded() throws Exception { + public void testUploadMetadataJsonAndMarkUploadedd() throws Exception { String userToken = "webinUserToken"; SubmissionAccount submissionAccount = getWebinUserAccount(); when(webinTokenService.getWebinUserAccountFromToken(anyString())).thenReturn(submissionAccount); doNothing().when(mailSender).sendEmail(anyString(), anyString(), anyString()); String submissionId = createNewSubmissionEntry(submissionAccount); - + String projectTitle = "test_project_title"; + String projectDescription = "test_project_description"; + String metadataJson = "{\"project\": {\"title\":\"" + projectTitle + "\",\"description\":\"" + projectDescription + "\"}}"; HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setBearerAuth(userToken); mvc.perform(put("/v1/submission/" + submissionId + "/uploaded") .headers(httpHeaders) + .content(metadataJson) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); @@ -251,6 +259,38 @@ public void testMarkSubmissionUploaded() throws Exception { assertThat(submission.getStatus()).isEqualTo(SubmissionStatus.UPLOADED.toString()); assertThat(submission.getUploadedTime()).isNotNull(); assertThat(submission.getCompletionTime()).isNull(); + + SubmissionDetails submissionDetails = submissionDetailsRepository.findBySubmissionId(submissionId); + assertThat(submissionDetails).isNotNull(); + assertThat(submissionDetails.getSubmissionId()).isEqualTo(submissionId); + assertThat(submissionDetails.getProjectTitle()).isEqualTo(projectTitle); + assertThat(submissionDetails.getProjectDescription()).isEqualTo(projectDescription); + assertThat(submissionDetails.getMetadataJson()).isNotNull(); + assertThat(submissionDetails.getMetadataJson().get("project").get("title").asText()).isEqualTo(projectTitle); + assertThat(submissionDetails.getMetadataJson().get("project").get("title").asText()).isEqualTo(projectTitle); + } + + @Test + @Transactional + public void testRequiredMetadataFieldsNotProvided() throws Exception { + String userToken = "webinUserToken"; + SubmissionAccount submissionAccount = getWebinUserAccount(); + when(webinTokenService.getWebinUserAccountFromToken(anyString())).thenReturn(submissionAccount); + doNothing().when(mailSender).sendEmail(anyString(), anyString(), anyString()); + + String submissionId = createNewSubmissionEntry(submissionAccount); + String projectDescription = "test_project_description"; + String metadataJson = "{\"project\": {\"description\":\"" + projectDescription + "\"}}"; + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setBearerAuth(userToken); + + mvc.perform(put("/v1/submission/" + submissionId + "/uploaded") + .headers(httpHeaders) + .content(metadataJson) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()) + .andExpect(content().string("Required fields project title and project description " + + "could not be found in metadata json")); } @Test @@ -261,11 +301,15 @@ public void testSubmissionDoesNotExistException() throws Exception { when(webinTokenService.getWebinUserAccountFromToken(anyString())).thenReturn(submissionAccount); String submissionId = "wrong_submission_id"; + String projectTitle = "test_project_title"; + String projectDescription = "test_project_description"; + String metadataJson = "{\"project\": {\"title\":\"" + projectTitle + "\",\"description\":\"" + projectDescription + "\"}}"; HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setBearerAuth(userToken); mvc.perform(put("/v1/submission/" + submissionId + "/uploaded") .headers(httpHeaders) + .content(metadataJson) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()) .andExpect(content().string("Given submission with id " + submissionId + " does not exist")); @@ -274,7 +318,6 @@ public void testSubmissionDoesNotExistException() throws Exception { @Test @Transactional public void testMarkSubmissionStatusCorrect() throws Exception { - String userToken = "webinUserToken"; SubmissionAccount submissionAccount = getWebinUserAccount(); when(webinTokenService.getWebinUserAccountFromToken(anyString())).thenReturn(submissionAccount); @@ -298,7 +341,6 @@ public void testMarkSubmissionStatusCorrect() throws Exception { @Test @Transactional public void testMarkSubmissionStatusWrong() throws Exception { - String userToken = "webinUserToken"; SubmissionAccount submissionAccount = getWebinUserAccount(); when(webinTokenService.getWebinUserAccountFromToken(anyString())).thenReturn(submissionAccount);