diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..81bf9989 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,20 @@ +# Description +**Story:** _Please include a link to the story in Jira_ + +_Please include a summary of the change that was made._ + + + +# Dependencies +_Please include any dependencies to other code branches, testing configurations, scripts to be run, etc._ + +# Testing +_Please include any details needed for reviewers to test this code_ + + +# Checklist: + +- [ ] I have performed a self-review of my own code +- [ ] I have tested my code and ensured it meets the acceptance criteria of the story +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have either updated the source of truth or arranged for update with product owner if needed https://breedinginsight.atlassian.net/wiki/spaces/BI/pages/1559953409/Source+of+Truth diff --git a/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java b/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java new file mode 100644 index 00000000..0e79ab86 --- /dev/null +++ b/src/main/java/io/swagger/api/pheno/ObservationLevelNamesApi.java @@ -0,0 +1,68 @@ +package io.swagger.api.pheno; + +import io.swagger.annotations.*; +import io.swagger.model.pheno.*; +import jakarta.validation.Valid; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@javax.annotation.processing.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2024-05-21T16:32:22.556Z[GMT]") +@Api(value = "observationlevelnames", description = "the observationlevelnames API") +public interface ObservationLevelNamesApi { + @ApiOperation(value = "Get the Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to retrieve the list of supported observation level names", response = ObservationLevelListResponse.class, authorizations = { + @Authorization(value = "AuthorizationToken") }, tags = { "Observation level names", }) + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationLevelListResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = String.class), + @ApiResponse(code = 401, message = "Unauthorized", response = String.class), + @ApiResponse(code = 403, message = "Forbidden", response = String.class) }) + @RequestMapping(value = "/observationlevelnames", produces = { "application/json" }, method = RequestMethod.GET) + ResponseEntity observationlevelnamesGet( + @ApiParam(value = "programDbId") @Valid @RequestParam(value = "programDbId", required = false) String programDbId, + @ApiParam(value = "all") @Valid @RequestParam(value = "all", required = false) Boolean all, + @ApiParam(value = "page") @Valid @RequestParam(value = "page", required = false) Integer page, + @ApiParam(value = "pageSize") @Valid @RequestParam(value = "pageSize", required = false) Integer pageSize, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException; + + @ApiOperation(value = "Create Observation Level Names", nickname = "observationlevelnamesPost", notes = "Call to save a list of observation level names", response = ObservationLevelListResponse.class, authorizations = { + @Authorization(value = "AuthorizationToken") }, tags = { "Observation level names", }) + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationLevelListResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = String.class), + @ApiResponse(code = 401, message = "Unauthorized", response = String.class), + @ApiResponse(code = 403, message = "Forbidden", response = String.class) }) + @RequestMapping(value = "/observationlevelnames", produces = { "application/json" }, method = RequestMethod.POST) + ResponseEntity observationlevelnamesPost( + @ApiParam(value = "") @Valid @RequestBody List body, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException; + + @ApiOperation(value = "Delete Observation Level Names", nickname = "observationlevelnamesGet", notes = "Call to delete a list of observation level names", response = ObservationLevelListResponse.class, authorizations = { + @Authorization(value = "AuthorizationToken") }, tags = { "Observation level names", }) + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationLevelListResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = String.class), + @ApiResponse(code = 401, message = "Unauthorized", response = String.class), + @ApiResponse(code = 403, message = "Forbidden", response = String.class) }) + @RequestMapping(value = "/observationlevelnames/{observationlevelnameDbId}", produces = { "application/json" }, method = RequestMethod.DELETE) + ResponseEntity observationlevelnamesDelete( + @ApiParam(value = "The unique ID of this generic list", required = true) @PathVariable("observationlevelnameDbId") String observationLevelNameDbId, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException; + + @ApiOperation(value = "Update an existing Observation Level Name", nickname = "observationlevelnamesDbIdPut", notes = "Update an existing Observation Level Name", response = ObservationLevelListResponse.class, authorizations = { + @Authorization(value = "AuthorizationToken") }, tags = { "Observation Units", }) + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ObservationUnitHierarchyLevel.class), + @ApiResponse(code = 400, message = "Bad Request", response = String.class), + @ApiResponse(code = 401, message = "Unauthorized", response = String.class), + @ApiResponse(code = 403, message = "Forbidden", response = String.class) }) + @RequestMapping(value = "/observationlevelnames/{observationlevelnameDbId}", produces = { "application/json" }, consumes = { + "application/json" }, method = RequestMethod.PUT) + ResponseEntity observationlevelnamesDbIdPut( + @ApiParam(value = "The unique ID of the specific Observation Level Name", required = true) @PathVariable("observationlevelnameDbId") String observationlevelnameDbId, + @ApiParam(value = "") @Valid @RequestBody ObservationLevelNewRequest body, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException; +} + diff --git a/src/main/java/io/swagger/model/core/StudyNewRequest.java b/src/main/java/io/swagger/model/core/StudyNewRequest.java index 15a61bf9..36bc86c4 100644 --- a/src/main/java/io/swagger/model/core/StudyNewRequest.java +++ b/src/main/java/io/swagger/model/core/StudyNewRequest.java @@ -84,6 +84,9 @@ public class StudyNewRequest extends BrAPIDataModel{ @JsonProperty("trialDbId") private String trialDbId = null; + @JsonProperty("programDbId") + private String programDbId = null; + @JsonProperty("trialName") private String trialName = null; @@ -463,6 +466,14 @@ public void setTrialDbId(String trialDbId) { this.trialDbId = trialDbId; } + public String getProgramDbId() { + return programDbId; + } + + public void setProgramDbId(String programDbId) { + this.programDbId = programDbId; + } + public StudyNewRequest trialName(String trialName) { this.trialName = trialName; return this; diff --git a/src/main/java/io/swagger/model/pheno/ObservationLevelNewRequest.java b/src/main/java/io/swagger/model/pheno/ObservationLevelNewRequest.java new file mode 100644 index 00000000..ba3df50d --- /dev/null +++ b/src/main/java/io/swagger/model/pheno/ObservationLevelNewRequest.java @@ -0,0 +1,13 @@ +package io.swagger.model.pheno; + +public class ObservationLevelNewRequest extends ObservationUnitHierarchyLevel { + private Boolean global = null; + + public Boolean getGlobal() { + return global; + } + + public void setGlobal(Boolean value) { + this.global = value; + } +} diff --git a/src/main/java/io/swagger/model/pheno/ObservationLevelSingleResponse.java b/src/main/java/io/swagger/model/pheno/ObservationLevelSingleResponse.java new file mode 100644 index 00000000..5a4e9394 --- /dev/null +++ b/src/main/java/io/swagger/model/pheno/ObservationLevelSingleResponse.java @@ -0,0 +1,127 @@ +package io.swagger.model.pheno; + +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; + + +import io.swagger.annotations.ApiModelProperty; +import io.swagger.model.BrAPIResponse; +import io.swagger.model.Context; +import io.swagger.model.Metadata; + +import io.swagger.model.pheno.ObservationLevelListResponseResult; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; + + +/** + * ObservationLevelListResponse + */ +@Validated +@javax.annotation.processing.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2020-03-20T16:32:22.556Z[GMT]") +public class ObservationLevelSingleResponse implements BrAPIResponse { + @JsonProperty("@context") + private Context _atContext = null; + + @JsonProperty("metadata") + private Metadata metadata = null; + + @JsonProperty("result") + private ObservationUnitHierarchyLevel result = null; + + public ObservationLevelSingleResponse _atContext(Context _atContext) { + this._atContext = _atContext; + return this; + } + + + + public void set_atContext(Context _atContext) { + this._atContext = _atContext; + } + + public ObservationLevelSingleResponse metadata(Metadata metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @ApiModelProperty(required = true, value = "") + + + @Valid + public Metadata getMetadata() { + return metadata; + } + + public void setMetadata(Metadata metadata) { + this.metadata = metadata; + } + + public ObservationLevelSingleResponse result(ObservationUnitHierarchyLevel result) { + this.result = result; + return this; + } + + /** + * Get result + * @return result + **/ + @ApiModelProperty(required = true, value = "") + + + @Valid + public ObservationUnitHierarchyLevel getResult() { + return result; + } + + public void setResult(ObservationUnitHierarchyLevel result) { + this.result = result; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ObservationLevelSingleResponse observationLevelSingleResponse = (ObservationLevelSingleResponse) o; + return Objects.equals(this._atContext, observationLevelSingleResponse._atContext) && + Objects.equals(this.metadata, observationLevelSingleResponse.metadata) && + Objects.equals(this.result, observationLevelSingleResponse.result); + } + + @Override + public int hashCode() { + return Objects.hash(_atContext, metadata, result); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ObservationLevelListResponse {\n"); + + sb.append(" _atContext: ").append(toIndentedString(_atContext)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append(" result: ").append(toIndentedString(result)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/java/io/swagger/model/pheno/ObservationTableHeaderRowEnum.java b/src/main/java/io/swagger/model/pheno/ObservationTableHeaderRowEnum.java index 1cd1a92c..ccd7561d 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationTableHeaderRowEnum.java +++ b/src/main/java/io/swagger/model/pheno/ObservationTableHeaderRowEnum.java @@ -15,15 +15,7 @@ public enum ObservationTableHeaderRowEnum { GERMPLASMNAME("germplasmName"), POSITIONCOORDINATEX("positionCoordinateX"), POSITIONCOORDINATEY("positionCoordinateY"), - YEAR("year"), - FIELD("field"), - PLOT("plot"), - SUB_PLOT("sub-plot"), - PLANT("plant"), - POT("pot"), - BLOCK("block"), - ENTRY("entry"), - REP("rep"); + YEAR("year"); private String value; ObservationTableHeaderRowEnum(String value) { diff --git a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java index bbe589d4..4434e70b 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java +++ b/src/main/java/io/swagger/model/pheno/ObservationUnitHierarchyLevel.java @@ -2,26 +2,42 @@ import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; public class ObservationUnitHierarchyLevel { + @JsonProperty("levelNameDbId") + private String levelNameDbId = null; + @JsonProperty("levelName") - private ObservationUnitHierarchyLevelEnum levelName = null; + private String levelName = null; @JsonProperty("levelOrder") private Integer levelOrder = null; - public ObservationUnitHierarchyLevel levelName(ObservationUnitHierarchyLevelEnum levelName) { - this.levelName = levelName; - return this; + @JsonProperty("programDbId") + @JsonInclude(JsonInclude.Include.NON_NULL) + private String programDbId = null; + + // NOTE: This property is NOT used for lookups, only responses. + @JsonProperty("programName") + @JsonInclude(JsonInclude.Include.NON_NULL) + private String programName = null; + + public String getLevelNameDbId() { + return levelNameDbId; + } + + public void setLevelNameDbId(String value) { + this.levelNameDbId = value; } - public ObservationUnitHierarchyLevelEnum getLevelName() { + public String getLevelName() { return levelName; } - public void setLevelName(ObservationUnitHierarchyLevelEnum levelName) { + public void setLevelName(String levelName) { this.levelName = levelName; } @@ -38,6 +54,22 @@ public void setLevelOrder(Integer levelOrder) { this.levelOrder = levelOrder; } + public String getProgramDbId() { + return programDbId; + } + + public void setProgramDbId(String value) { + this.programDbId = value; + } + + public String getProgramName() { + return programName; + } + + public void setProgramName(String value) { + this.programName = value; + } + @Override public boolean equals(java.lang.Object o) { if (this == o) { @@ -47,13 +79,12 @@ public boolean equals(java.lang.Object o) { return false; } ObservationUnitHierarchyLevel observationUnitHierarchyLevel = (ObservationUnitHierarchyLevel) o; - return Objects.equals(this.levelName, observationUnitHierarchyLevel.levelName) - && Objects.equals(this.levelOrder, observationUnitHierarchyLevel.levelOrder); + return Objects.equals(this.levelNameDbId, observationUnitHierarchyLevel.levelNameDbId); } @Override public int hashCode() { - return Objects.hash(levelName, levelOrder); + return Objects.hash(levelNameDbId); } @Override @@ -63,7 +94,9 @@ public String toString() { sb.append(" levelName: ").append(toIndentedString(levelName)).append("\n"); sb.append(" levelOrder: ").append(toIndentedString(levelOrder)).append("\n"); - sb.append("}"); + sb.append(" levelNameDbId: ").append(toIndentedString(levelNameDbId)).append("\n"); + sb.append(" programDbId: ").append(toIndentedString(programDbId)).append("\n"); + sb.append(" programName: ").append(toIndentedString(programName)).append("\n"); return sb.toString(); } diff --git a/src/main/java/io/swagger/model/pheno/ObservationUnitLevel.java b/src/main/java/io/swagger/model/pheno/ObservationUnitLevel.java index a9dc0b7b..b39a960f 100644 --- a/src/main/java/io/swagger/model/pheno/ObservationUnitLevel.java +++ b/src/main/java/io/swagger/model/pheno/ObservationUnitLevel.java @@ -24,14 +24,14 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ObservationUnitLevel other = (ObservationUnitLevel) obj; - return Objects.equals(levelCode, other.levelCode); + return Objects.equals(getLevelNameDbId(), other.getLevelNameDbId()); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); - result = prime * result + Objects.hash(levelCode); + result = prime * result + Objects.hash(getLevelNameDbId()); return result; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/auth/BrapiTestServerAuthConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerAuthConfig.java similarity index 94% rename from src/main/java/org/brapi/test/BrAPITestServer/auth/BrapiTestServerAuthConfig.java rename to src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerAuthConfig.java index 1370f964..0584309b 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/auth/BrapiTestServerAuthConfig.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerAuthConfig.java @@ -1,5 +1,6 @@ -package org.brapi.test.BrAPITestServer.auth; +package org.brapi.test.BrAPITestServer.config; +import org.brapi.test.BrAPITestServer.auth.BrapiTestServerJWTAuthFilter; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerConfig.java similarity index 81% rename from src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java rename to src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerConfig.java index 2c9fa0a0..15019662 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/BrapiTestServerConfig.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/config/BrapiTestServerConfig.java @@ -1,6 +1,5 @@ -package org.brapi.test.BrAPITestServer; +package org.brapi.test.BrAPITestServer.config; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepositoryImpl; import org.brapi.test.BrAPITestServer.serializer.CustomDateSerializer; import org.brapi.test.BrAPITestServer.serializer.CustomGeoJSONDeserializer; import org.brapi.test.BrAPITestServer.serializer.CustomGermplasmStorageTypesDeserializer; @@ -8,10 +7,7 @@ import org.brapi.test.BrAPITestServer.serializer.CustomStringToEnumConverter; import org.brapi.test.BrAPITestServer.serializer.CustomTimeStampSerializer; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.context.annotation.*; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -22,7 +18,6 @@ import java.time.OffsetDateTime; @Configuration -@EnableJpaRepositories(basePackages = "org.brapi.test.BrAPITestServer.repository", repositoryBaseClass = BrAPIRepositoryImpl.class) @PropertySource(value = "classpath:properties/application.properties") public class BrapiTestServerConfig { @Bean diff --git a/src/main/java/org/brapi/test/BrAPITestServer/config/repos/BaseEntitiesConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/config/repos/BaseEntitiesConfig.java new file mode 100644 index 00000000..604e5ded --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/config/repos/BaseEntitiesConfig.java @@ -0,0 +1,18 @@ +package org.brapi.test.BrAPITestServer.config.repos; + +import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +/** + * Configures the repos of entities derived directly from BrAPIBaseEntity so + * basic JPA repos can be implemented to save and delete them. + */ +@Configuration +@EnableJpaRepositories( + basePackages = "org.brapi.test.BrAPITestServer.repository.baseEntities", + excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BrAPIPrimaryEntity.class)) +public class BaseEntitiesConfig { +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/config/repos/PrimaryEntitiesConfig.java b/src/main/java/org/brapi/test/BrAPITestServer/config/repos/PrimaryEntitiesConfig.java new file mode 100644 index 00000000..a5511e8b --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/config/repos/PrimaryEntitiesConfig.java @@ -0,0 +1,23 @@ +package org.brapi.test.BrAPITestServer.config.repos; + +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepositoryImpl; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +/** + * Configures the repos of entities derived directly from BrAPIPrimaryEntity so + * the custom repository implementation can be used to save entities, additional info, and external references + * the right way. + */ +@Configuration +@EnableJpaRepositories( + basePackages = "org.brapi.test.BrAPITestServer.repository.primaryEntities", + excludeFilters = @ComponentScan.Filter( + type = FilterType.REGEX, + pattern = "org\\.brapi\\.test\\.BrAPITestServer\\.repository\\.baseEntities\\..*" + ), + repositoryBaseClass = BrAPIRepositoryImpl.class) +public class PrimaryEntitiesConfig { +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java new file mode 100644 index 00000000..ef872d03 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationLevelNamesApiController.java @@ -0,0 +1,109 @@ +package org.brapi.test.BrAPITestServer.controller.pheno; + + +import io.swagger.annotations.ApiParam; +import io.swagger.api.pheno.ObservationLevelNamesApi; +import io.swagger.model.Metadata; +import io.swagger.model.pheno.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import org.brapi.test.BrAPITestServer.controller.core.BrAPIController; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.service.PagingUtility; +import org.brapi.test.BrAPITestServer.service.pheno.ObservationUnitLevelNameService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@javax.annotation.processing.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2025-05-21T16:32:22.556Z[GMT]") +@Controller +public class ObservationLevelNamesApiController extends BrAPIController + implements ObservationLevelNamesApi { + + private static final Logger log = LoggerFactory.getLogger(ObservationLevelNamesApiController.class); + private final HttpServletRequest request; + private final ObservationUnitLevelNameService observationUnitLevelNameService; + + @Autowired + public ObservationLevelNamesApiController(ObservationUnitLevelNameService observationUnitLevelNameService, + HttpServletRequest request) { + this.observationUnitLevelNameService = observationUnitLevelNameService; + this.request = request; + } + + @CrossOrigin + @Override + public ResponseEntity observationlevelnamesGet( + // If supplied, grabs all Observation Level Names for the given programDbId. + // If not supplied, grabs all global Observation Level Names. + @RequestParam(value = "programDbId", required = false) String programDbId, + // Used to grab all the Observation Level Names in the system, both global, and all level names for all params + @RequestParam(value = "all", required = false) Boolean all, + @RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "pageSize", required = false) Integer pageSize, + @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException { + + log.debug("Request: " + request.getRequestURI()); + validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); + validateAcceptHeader(request); + + Metadata metadata = generateMetaDataTemplate(page, pageSize); + + var foundLevelNames = observationUnitLevelNameService.findObservationUnitLevelNames(programDbId, all); + var data = observationUnitLevelNameService.convertFromEntitiesInBatch(foundLevelNames); + + data = PagingUtility.paginateSimpleList(data, metadata); + + return responseOK(new ObservationLevelListResponse(), new ObservationLevelListResponseResult(), data, metadata); + } + + @CrossOrigin + @Override + public ResponseEntity observationlevelnamesPost( + @RequestBody List body, + @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException { + + log.debug("Request: " + request.getRequestURI()); + validateSecurityContext(request, "ROLE_ANONYMOUS", "ROLE_USER"); + validateAcceptHeader(request); + var data = observationUnitLevelNameService.save(body); + return responseOK(new ObservationLevelListResponse(), new ObservationLevelListResponseResult(), data, generateEmptyMetadata()); + } + + @CrossOrigin + @Override + public ResponseEntity observationlevelnamesDelete( + @PathVariable("observationlevelnameDbId") String observationlevelnameDbId, + @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException { + + log.debug("Request: " + request.getRequestURI()); + validateSecurityContext(request, "ROLE_USER"); + validateAcceptHeader(request); + + observationUnitLevelNameService.deleteObservationLevelName(observationlevelnameDbId); + return responseNoContent(); + } + + @CrossOrigin + @Override + public ResponseEntity observationlevelnamesDbIdPut( + @ApiParam(value = "The unique ID of the specific Observation Level name", required = true) @PathVariable("observationlevelnameDbId") String observationlevelnameDbId, + @ApiParam(value = "") @Valid @RequestBody ObservationLevelNewRequest body, + @ApiParam(value = "HTTP HEADER - Token used for Authorization Bearer {token_string} ") @RequestHeader(value = "Authorization", required = false) String authorization) + throws BrAPIServerException { + log.debug("Request: " + request.getRequestURI()); + validateSecurityContext(request, "ROLE_USER"); + validateAcceptHeader(request); + + var data = observationUnitLevelNameService.update(observationlevelnameDbId, body); + return responseOK(new ObservationLevelSingleResponse(), data); + } +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationsApiController.java b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationsApiController.java index 81828e1f..ceda2df3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationsApiController.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/controller/pheno/ObservationsApiController.java @@ -121,7 +121,7 @@ public ResponseEntity observationsObservationDbIdPut( log.debug("Request: " + request.getRequestURI()); validateSecurityContext(request, "ROLE_USER"); validateAcceptHeader(request); - Observation data = observationService.updateObservation(observationDbId, body); + Observation data = observationService.updateObservationAndConvert(observationDbId, body); return responseOK(new ObservationSingleResponse(), data); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/exceptions/ExceptionUtils.java b/src/main/java/org/brapi/test/BrAPITestServer/exceptions/ExceptionUtils.java new file mode 100644 index 00000000..f249936a --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/exceptions/ExceptionUtils.java @@ -0,0 +1,47 @@ +package org.brapi.test.BrAPITestServer.exceptions; + +import org.postgresql.util.PSQLException; +import org.postgresql.util.ServerErrorMessage; +import org.springframework.http.HttpStatus; + +import java.util.Optional; + +public class ExceptionUtils { + private static final String SQL_CONFLICT_ERROR_CODE = "23505"; + + public static T findCause( + Throwable throwable, + Class targetType + ) { + Throwable t = throwable; + while (t != null) { + if (targetType.isInstance(t)) { + return targetType.cast(t); + } + t = t.getCause(); + } + return null; + } + + /** + * Throws a BrAPIServerException with status 409 (CONFLICT) if a duplicate is detected in the database. + * The offending table and key that failed will also be sent in the response. + */ + public static void checkForPSQLConflict(Throwable possibleConflict) throws BrAPIServerException { + PSQLException possibleConflictException = findCause(possibleConflict, PSQLException.class); + + String sqlState = Optional.ofNullable(possibleConflictException) + .map(PSQLException::getServerErrorMessage) + .map(ServerErrorMessage::getSQLState) + .orElse(null); + + if (sqlState != null && sqlState.equals(SQL_CONFLICT_ERROR_CODE)) { + String conflictDetailMessage = possibleConflictException.getServerErrorMessage().getDetail(); + String offendingTable = possibleConflictException.getServerErrorMessage().getTable(); + + String errorResponse = String.format("A duplicate of an existing record is trying be submitted on table %s.\n\n %s", offendingTable, conflictDetailMessage); + + throw new BrAPIServerException(HttpStatus.CONFLICT, errorResponse); + } + } +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/dto/ObservationUnitGermplasmData.java b/src/main/java/org/brapi/test/BrAPITestServer/model/dto/ObservationUnitGermplasmData.java new file mode 100644 index 00000000..fd090214 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/dto/ObservationUnitGermplasmData.java @@ -0,0 +1,30 @@ +package org.brapi.test.BrAPITestServer.model.dto; + +import java.util.UUID; + +public class ObservationUnitGermplasmData { + private String germplasmDbId; + private String germplasmName; + + public ObservationUnitGermplasmData(String germplasmDbId, + String germplasmName) { + this.germplasmDbId = germplasmDbId; + this.germplasmName = germplasmName; + } + + public String getGermplasmDbId() { + return germplasmDbId; + } + + public void setGermplasmDbId(String germplasmDbId) { + this.germplasmDbId = germplasmDbId; + } + + public String getGermplasmName() { + return germplasmName; + } + + public void setGermplasmName(String germplasmName) { + this.germplasmName = germplasmName; + } +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ExperimentalDesignEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ExperimentalDesignEntity.java index c9282ee5..ded46dde 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ExperimentalDesignEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ExperimentalDesignEntity.java @@ -3,23 +3,12 @@ import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; -@Entity -@Table(name = "study_experimental_design") -public class ExperimentalDesignEntity extends BrAPIBaseEntity { - @Column +@Embeddable +public class ExperimentalDesignEntity { + @Column(name = "pui", table = "study_experimental_design") private String PUI; - @Column + @Column(name = "description", table = "study_experimental_design") private String description; - @OneToOne(fetch = FetchType.LAZY) - private StudyEntity study; - - public StudyEntity getStudy() { - return study; - } - - public void setStudy(StudyEntity study) { - this.study = study; - } public String getPUI() { return PUI; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/GrowthFacilityEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/GrowthFacilityEntity.java index 4ed2900f..35cf3052 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/GrowthFacilityEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/GrowthFacilityEntity.java @@ -3,23 +3,12 @@ import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; -@Entity -@Table(name = "study_growth_facility") -public class GrowthFacilityEntity extends BrAPIBaseEntity { - @Column +@Embeddable +public class GrowthFacilityEntity { + @Column(name = "pui", table = "study_growth_facility") private String PUI; - @Column + @Column(name = "description", table = "study_growth_facility") private String description; - @OneToOne(fetch = FetchType.LAZY) - private StudyEntity study; - - public StudyEntity getStudy() { - return study; - } - - public void setStudy(StudyEntity study) { - this.study = study; - } public String getPUI() { return PUI; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java index 53a354bf..c92b0f68 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/ObservationLevelEntity.java @@ -2,27 +2,30 @@ import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; +import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; @Entity @Table(name = "study_observation_level") public class ObservationLevelEntity extends BrAPIBaseEntity { - @Column - private String levelName; - @Column - private Integer levelOrder; + + @ManyToOne + @JoinColumn(name = "level_name") + private ObservationUnitLevelNameEntity levelName; @ManyToOne(fetch = FetchType.LAZY) private StudyEntity study; - public String getLevelName() { + public ObservationUnitLevelNameEntity getLevelName() { return levelName; } - public void setLevelName(String levelName) { + public void setLevelName(ObservationUnitLevelNameEntity levelName) { this.levelName = levelName; } - public Integer getLevelOrder() { - return levelOrder; + + public StudyEntity getStudy() { + return study; } - public void setLevelOrder(Integer levelOrder) { - this.levelOrder = levelOrder; + + public void setStudy(StudyEntity study) { + this.study = study; } } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java index 107978b6..2197b3b0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyEntity.java @@ -12,6 +12,11 @@ @Entity @Table(name = "study") +@SecondaryTables({ + @SecondaryTable(name = "study_experimental_design", pkJoinColumns = @PrimaryKeyJoinColumn(name = "study_id")), + @SecondaryTable(name = "study_growth_facility", pkJoinColumns = @PrimaryKeyJoinColumn(name = "study_id")), + @SecondaryTable(name = "study_last_update", pkJoinColumns = @PrimaryKeyJoinColumn(name = "study_id")) +}) @Where(clause = "soft_deleted = false") public class StudyEntity extends BrAPIPrimaryEntity { @@ -32,17 +37,18 @@ public class StudyEntity extends BrAPIPrimaryEntity { private Date endDate; @OneToMany(mappedBy = "study") private List environmentParameters; - @OneToOne(mappedBy = "study", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @Embedded private ExperimentalDesignEntity experimentalDesign; - @OneToOne(mappedBy = "study", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @Embedded private GrowthFacilityEntity growthFacility; - @OneToOne(mappedBy = "study", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @Embedded private StudyLastUpdateEntity lastUpdate; @Column private String license; @OneToOne(fetch = FetchType.LAZY) private LocationEntity location; - @OneToMany(mappedBy = "study") + + @OneToMany(mappedBy = "study", cascade = CascadeType.ALL, orphanRemoval = true) private List observationLevels; @Column private String observationUnitsDescription; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyLastUpdateEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyLastUpdateEntity.java index e7b5baa4..9dd109b6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyLastUpdateEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/core/StudyLastUpdateEntity.java @@ -5,23 +5,12 @@ import java.util.Date; -@Entity -@Table(name = "study_last_update") -public class StudyLastUpdateEntity extends BrAPIBaseEntity { - @Column +@Embeddable +public class StudyLastUpdateEntity { + @Column(name = "timestamp", table = "study_last_update") private Date timestamp; - @Column + @Column(name = "version", table = "study_last_update") private String version; - @OneToOne(fetch = FetchType.LAZY) - private StudyEntity study; - - public StudyEntity getStudy() { - return study; - } - - public void setStudy(StudyEntity study) { - this.study = study; - } public Date getTimestamp() { return timestamp; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitEntity.java index b13b4f23..96064f23 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitEntity.java @@ -10,6 +10,7 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.CrossEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotEntity; +import org.hibernate.annotations.BatchSize; import org.hibernate.annotations.Where; import java.util.List; @@ -28,6 +29,7 @@ public class ObservationUnitEntity extends BrAPIPrimaryEntity { private String observationUnitPUI; @ManyToOne(fetch = FetchType.LAZY) private SeedLotEntity seedLot; + @BatchSize(size = 50) @OneToMany(mappedBy="observationUnit", cascade=CascadeType.ALL) private List treatments; @OneToOne(mappedBy="observationUnit", cascade=CascadeType.ALL, fetch = FetchType.LAZY) @@ -40,6 +42,7 @@ public class ObservationUnitEntity extends BrAPIPrimaryEntity { private TrialEntity trial; @ManyToOne(fetch = FetchType.LAZY) private StudyEntity study; + @BatchSize(size = 50) @OneToMany(mappedBy="observationUnit", cascade=CascadeType.ALL, fetch = FetchType.LAZY) private List observations; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelNameEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelNameEntity.java new file mode 100644 index 00000000..743b4638 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelNameEntity.java @@ -0,0 +1,44 @@ +package org.brapi.test.BrAPITestServer.model.entity.pheno; + + +import jakarta.persistence.*; +import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; +import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; + +@Entity +@Table(name = "observation_unit_level_name") +public class ObservationUnitLevelNameEntity extends BrAPIBaseEntity { + @Column(name = "level_name") + private String levelName; + + @Column(name = "level_order") + private Integer levelOrder; + + @ManyToOne + @JoinColumn(name = "program_id") + private ProgramEntity program; + + public String getLevelName() { + return levelName; + } + + public void setLevelName(String value) { + this.levelName = value; + } + + public ProgramEntity getProgram() { + return program; + } + + public void setProgram(ProgramEntity program) { + this.program = program; + } + + public Integer getLevelOrder() { + return levelOrder; + } + + public void setLevelOrder(Integer value) { + this.levelOrder = value; + } +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java index 5a080d4d..3ad859a1 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitLevelRelationshipEntity.java @@ -1,6 +1,5 @@ package org.brapi.test.BrAPITestServer.model.entity.pheno; -import io.swagger.model.pheno.ObservationUnitHierarchyLevelEnum; import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; @@ -9,10 +8,9 @@ public class ObservationUnitLevelRelationshipEntity extends BrAPIBaseEntity { @Column private String levelCode; - @Column - private ObservationUnitHierarchyLevelEnum levelName; - @Column - private Integer levelOrder; + @ManyToOne + @JoinColumn(name = "level_name") + private ObservationUnitLevelNameEntity levelName; @ManyToOne(fetch = FetchType.LAZY) private ObservationUnitEntity observationUnit; @ManyToOne(fetch = FetchType.LAZY) @@ -30,18 +28,12 @@ public String getLevelCode() { public void setLevelCode(String levelCode) { this.levelCode = levelCode; } - public ObservationUnitHierarchyLevelEnum getLevelName() { + public ObservationUnitLevelNameEntity getLevelName() { return levelName; } - public void setLevelName(ObservationUnitHierarchyLevelEnum levelName) { + public void setLevelName(ObservationUnitLevelNameEntity levelName) { this.levelName = levelName; } - public Integer getLevelOrder() { - return levelOrder; - } - public void setLevelOrder(Integer levelOrder) { - this.levelOrder = levelOrder; - } public ObservationUnitPositionEntity getPosition() { return position; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java index 38851b24..8fe5f373 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/model/entity/pheno/ObservationUnitPositionEntity.java @@ -1,7 +1,6 @@ package org.brapi.test.BrAPITestServer.model.entity.pheno; import io.swagger.model.pheno.EntryTypeEnum; -import io.swagger.model.pheno.ObservationUnitHierarchyLevelEnum; import io.swagger.model.pheno.PositionCoordinateTypeEnum; import jakarta.persistence.*; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; @@ -12,28 +11,27 @@ @Entity @Table(name = "observation_unit_position") public class ObservationUnitPositionEntity extends BrAPIBaseEntity { - @Column - private EntryTypeEnum entryType; - @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private GeoJSONEntity geoCoordinates; - @Column - private String levelCode; - @Column - private ObservationUnitHierarchyLevelEnum levelName; - @Column - private Integer levelOrder; - @OneToMany(mappedBy = "position", cascade = CascadeType.ALL) - private List observationLevelRelationships; - @Column - private String positionCoordinateX; - @Column - private PositionCoordinateTypeEnum positionCoordinateXType; - @Column - private String positionCoordinateY; - @Column - private PositionCoordinateTypeEnum positionCoordinateYType; - @OneToOne(fetch = FetchType.LAZY) - private ObservationUnitEntity observationUnit; + @Column + private EntryTypeEnum entryType; + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private GeoJSONEntity geoCoordinates; + @Column + private String levelCode; + @ManyToOne + @JoinColumn(name = "level_name") + private ObservationUnitLevelNameEntity levelName; + @OneToMany(mappedBy = "position", cascade = CascadeType.ALL) + private List observationLevelRelationships; + @Column + private String positionCoordinateX; + @Column + private PositionCoordinateTypeEnum positionCoordinateXType; + @Column + private String positionCoordinateY; + @Column + private PositionCoordinateTypeEnum positionCoordinateYType; + @OneToOne(fetch = FetchType.LAZY) + private ObservationUnitEntity observationUnit; public ObservationUnitEntity getObservationUnit() { return observationUnit; @@ -67,22 +65,14 @@ public void setLevelCode(String levelCode) { this.levelCode = levelCode; } - public ObservationUnitHierarchyLevelEnum getLevelName() { + public ObservationUnitLevelNameEntity getLevelName() { return levelName; } - public void setLevelName(ObservationUnitHierarchyLevelEnum levelName) { + public void setLevelName(ObservationUnitLevelNameEntity levelName) { this.levelName = levelName; } - public Integer getLevelOrder() { - return levelOrder; - } - - public void setLevelOrder(Integer levelOrder) { - this.levelOrder = levelOrder; - } - public List getObservationLevelRelationships() { return observationLevelRelationships; } @@ -123,41 +113,4 @@ public PositionCoordinateTypeEnum getPositionCoordinateYType() { public void setPositionCoordinateYType(PositionCoordinateTypeEnum positionCoordinateYType) { this.positionCoordinateYType = positionCoordinateYType; } - - public String getFieldCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.FIELD); - } - - public String getBlockCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.BLOCK); - } - - public String getEntryCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.ENTRY); - } - - public String getRepCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.REP); - } - - public String getPlotCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.PLOT); - } - - public String getPlantCode() { - return getRelationshipCode(ObservationUnitHierarchyLevelEnum.PLANT); - } - - private String getRelationshipCode(ObservationUnitHierarchyLevelEnum level) { - if (getLevelName() == level) { - return getLevelCode(); - } else { - for (ObservationUnitLevelRelationshipEntity rel : getObservationLevelRelationships()) { - if (rel.getLevelName() == level) { - return rel.getLevelCode(); - } - } - } - return null; - } } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/BaseEntityRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/BaseEntityRepository.java new file mode 100644 index 00000000..1a5c327d --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/BaseEntityRepository.java @@ -0,0 +1,10 @@ +package org.brapi.test.BrAPITestServer.repository.baseEntities; + +import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.io.Serializable; + +public interface BaseEntityRepository + extends JpaRepository { +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java new file mode 100644 index 00000000..9e452525 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/baseEntities/ObservationUnitLevelNameRepository.java @@ -0,0 +1,29 @@ +package org.brapi.test.BrAPITestServer.repository.baseEntities; + +import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.NativeQuery; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; +import java.util.UUID; + +public interface ObservationUnitLevelNameRepository extends BaseEntityRepository { + + + @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln " + + "WHERE ouln.program.id IN :programIds") + List findObservationUnitLevelNamesByProgram(@Param("programIds") List programDbIds); + + @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln " + + "WHERE ouln.program IS NULL") + List findDefaultObservationUnitLevelNames(); + + @NativeQuery("select * from a_table") + List botchedQuery(); + + @Query("SELECT ouln FROM ObservationUnitLevelNameEntity ouln") + List findAllObservationUnitLevelNames(); + +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java deleted file mode 100644 index c1572e6f..00000000 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationUnitRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; - -import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; - -import java.util.UUID; - -public interface ObservationUnitRepository extends BrAPIRepository { - -} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepository.java similarity index 85% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepository.java index 3a796a07..dd76d8f4 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepository.java @@ -1,8 +1,9 @@ -package org.brapi.test.BrAPITestServer.repository; +package org.brapi.test.BrAPITestServer.repository.primaryEntities; import java.io.Serializable; import java.util.List; import java.util.Optional; +import java.util.UUID; import org.brapi.test.BrAPITestServer.exceptions.InvalidPagingException; import org.brapi.test.BrAPITestServer.model.entity.BrAPIPrimaryEntity; @@ -10,7 +11,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.NoRepositoryBean; @NoRepositoryBean @@ -30,7 +30,7 @@ public interface BrAPIRepository void refresh(S entity); - public void fetchXrefs(Page page, Class searchClass) throws InvalidPagingException; + public void fetchXrefs(List page, Page pagedEntities, Class searchClass) throws InvalidPagingException; List findByIdIn(List ids); } \ No newline at end of file diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepositoryImpl.java similarity index 94% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepositoryImpl.java index 70ff40b1..583a28cf 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/BrAPIRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/BrAPIRepositoryImpl.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository; +package org.brapi.test.BrAPITestServer.repository.primaryEntities; import java.io.Serializable; import java.util.ArrayList; @@ -19,7 +19,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.JpaEntityInformation; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; @@ -141,17 +140,17 @@ public void refresh(S entity) { this.entityManager.refresh(entity); } - public void fetchXrefs(Page page, Class searchClass) throws InvalidPagingException { - SearchQueryBuilder searchQuery = new SearchQueryBuilder(searchClass); + public void fetchXrefs(List ids, Page pagedEntities, Class searchClass) { + SearchQueryBuilder searchQuery = new SearchQueryBuilder<>(searchClass); searchQuery.leftJoinFetch("externalReferences", "externalReferences") - .appendList(page.stream().map(p -> p.getId().toString()).collect(Collectors.toList()), "id"); + .appendIds(ids); - Page xrefs = findAllBySearchAndPaginate(searchQuery, PageRequest.of(0, page.getSize())); + List xrefs = findAllBySearch(searchQuery); Map> xrefByEntity = new HashMap<>(); xrefs.forEach(entity -> xrefByEntity.put(entity.getId(), entity.getExternalReferences())); - page.forEach(entity -> entity.setExternalReferences(xrefByEntity.get(entity.getId()))); + pagedEntities.forEach(entity -> entity.setExternalReferences(xrefByEntity.get(entity.getId()))); } private void applyUserId(SearchQueryBuilder searchQuery) { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/SearchRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/SearchRepository.java similarity index 73% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/SearchRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/SearchRepository.java index 25245f8a..691ea18d 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/SearchRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/SearchRepository.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository; +package org.brapi.test.BrAPITestServer.repository.primaryEntities; import org.brapi.test.BrAPITestServer.model.entity.SearchRequestEntity; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/BatchDeleteRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/BatchDeleteRepository.java similarity index 55% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/BatchDeleteRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/BatchDeleteRepository.java index 65ab887e..99acb4a5 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/BatchDeleteRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/BatchDeleteRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.BatchDeleteEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/CropRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/CropRepository.java similarity index 73% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/CropRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/CropRepository.java index 445cfed4..0096bbb5 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/CropRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/CropRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/ListRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ListRepository.java similarity index 85% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/ListRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ListRepository.java index bf0b88d1..206485b9 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/ListRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ListRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.ListEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/LocationRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/LocationRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/LocationRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/LocationRepository.java index 0413a18b..b73263c3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/LocationRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/LocationRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.LocationEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/PeopleRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/PeopleRepository.java similarity index 84% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/PeopleRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/PeopleRepository.java index 80f27e63..a5d7a2a0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/PeopleRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/PeopleRepository.java @@ -1,10 +1,10 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.repository.query.Param; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/ProgramRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ProgramRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/ProgramRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ProgramRepository.java index 9f6eafb8..7dbb78ff 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/ProgramRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/ProgramRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/SeasonRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/SeasonRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/SeasonRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/SeasonRepository.java index e2705d48..87d1bb25 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/SeasonRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/SeasonRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.SeasonEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/StudyRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/StudyRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/StudyRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/StudyRepository.java index 5baf625d..b11c113a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/StudyRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/StudyRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/TraitRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TraitRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/TraitRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TraitRepository.java index 602b0cef..f5c923f1 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/TraitRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TraitRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.brapi.test.BrAPITestServer.model.entity.pheno.TraitEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/TrialRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TrialRepository.java similarity index 91% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/core/TrialRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TrialRepository.java index f2b3a104..b370906a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/core/TrialRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/core/TrialRepository.java @@ -1,11 +1,11 @@ -package org.brapi.test.BrAPITestServer.repository.core; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.core; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallRepository.java similarity index 52% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallRepository.java index 8a073a21..1f6e3f96 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.CallEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallSetRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallSetRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallSetRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallSetRepository.java index 8536ba44..0b29f7c2 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/CallSetRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/CallSetRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.CallSetEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/GenomeMapRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/GenomeMapRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/GenomeMapRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/GenomeMapRepository.java index 09ee6379..1bd8e0fc 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/GenomeMapRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/GenomeMapRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.GenomeMapEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/LinkageGroupRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/LinkageGroupRepository.java similarity index 55% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/LinkageGroupRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/LinkageGroupRepository.java index 93c7c799..457b9568 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/LinkageGroupRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/LinkageGroupRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.LinkageGroupEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/MarkerPositionRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/MarkerPositionRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/MarkerPositionRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/MarkerPositionRepository.java index 80524003..8bb9123a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/MarkerPositionRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/MarkerPositionRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.MarkerPositionEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/PlateRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/PlateRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/PlateRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/PlateRepository.java index 85f54803..3a26c250 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/PlateRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/PlateRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.PlateEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceBaseRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceBaseRepository.java similarity index 73% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceBaseRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceBaseRepository.java index 0e496234..5e0a1699 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceBaseRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceBaseRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceBasesPageEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceRepository.java index 4ec3032a..90d6fc30 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceSetRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceSetRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceSetRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceSetRepository.java index 0ca5ed0e..22e74738 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/ReferenceSetRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/ReferenceSetRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceSetEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/SampleRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/SampleRepository.java similarity index 85% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/SampleRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/SampleRepository.java index d689a6a3..8907b4f6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/SampleRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/SampleRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.SampleEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantRepository.java index 0a6d6ec5..f77030f3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantSetRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantSetRepository.java similarity index 55% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantSetRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantSetRepository.java index c60a73ee..1520ecd6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VariantSetRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VariantSetRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantSetEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorOrderRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorOrderRepository.java similarity index 71% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorOrderRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorOrderRepository.java index a3aee996..06804e49 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorOrderRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorOrderRepository.java @@ -1,9 +1,9 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorOrderEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorPlateRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorPlateRepository.java similarity index 58% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorPlateRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorPlateRepository.java index 18d6fb6b..165b3586 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorPlateRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorPlateRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorPlateSubmissionEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorSpecRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorSpecRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorSpecRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorSpecRepository.java index d9955b73..8c1f295c 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/geno/VendorSpecRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/geno/VendorSpecRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.geno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.geno; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorSpecEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/BreedingMethodRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/BreedingMethodRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/BreedingMethodRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/BreedingMethodRepository.java index 0d47cd1f..4ec11058 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/BreedingMethodRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/BreedingMethodRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.BreedingMethodEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossRepository.java similarity index 61% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossRepository.java index b853184d..23372b7f 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossingProjectRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossingProjectRepository.java similarity index 57% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossingProjectRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossingProjectRepository.java index 1d623e6d..582c05f3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/CrossingProjectRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/CrossingProjectRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossingProjectEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeDefinitionRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeDefinitionRepository.java similarity index 61% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeDefinitionRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeDefinitionRepository.java index c2c40ffe..b8e68ccd 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeDefinitionRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeDefinitionRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmAttributeDefinitionEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeValueRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeValueRepository.java similarity index 59% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeValueRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeValueRepository.java index 5ee8a483..90ebd251 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmAttributeValueRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmAttributeValueRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmAttributeValueEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmDonorRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmDonorRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmDonorRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmDonorRepository.java index 6d2c6083..8717d0a6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmDonorRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmDonorRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.DonorEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepository.java similarity index 87% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepository.java index bdb8dc69..d5720e8b 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepositoryImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepositoryImpl.java similarity index 97% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepositoryImpl.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepositoryImpl.java index d0b9475e..fa426f22 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/GermplasmRepositoryImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/GermplasmRepositoryImpl.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeEdgeRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeEdgeRepository.java similarity index 56% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeEdgeRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeEdgeRepository.java index e5199ddd..c716a2ed 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeEdgeRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeEdgeRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.PedigreeEdgeEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepository.java similarity index 72% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepository.java index b9dd8e41..0dc5da86 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepository.java @@ -1,10 +1,10 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import java.util.List; import java.util.UUID; import org.brapi.test.BrAPITestServer.model.entity.germ.PedigreeNodeEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; public interface PedigreeRepository extends BrAPIRepository, PedigreeRepositoryCustom { public List findByGermplasm_Id(UUID germplasmDbId); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustom.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustom.java similarity index 76% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustom.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustom.java index 43ae5569..a53c81b7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustom.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustom.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import java.util.List; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustomImpl.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustomImpl.java similarity index 93% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustomImpl.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustomImpl.java index afef6d21..d67f41a5 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/PedigreeRepositoryCustomImpl.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/PedigreeRepositoryCustomImpl.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import java.util.List; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotRepository.java index a153d3b8..ae5e7f6a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotTransactionRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotTransactionRepository.java similarity index 58% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotTransactionRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotTransactionRepository.java index 68396c56..755a1ad7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/germ/SeedLotTransactionRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/germ/SeedLotTransactionRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.germ; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.germ; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotTransactionEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/EventRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/EventRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/EventRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/EventRepository.java index 0b4972f4..5025a405 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/EventRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/EventRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.EventEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ImageRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ImageRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ImageRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ImageRepository.java index bb25b47e..96838ff8 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ImageRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ImageRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.ImageEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/MethodRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/MethodRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/MethodRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/MethodRepository.java index 03ea81fd..d9048265 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/MethodRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/MethodRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.MethodEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationRepository.java similarity index 78% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationRepository.java index 2c33e4f9..1b19ac67 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationRepository.java @@ -1,4 +1,4 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import java.util.List; import java.util.UUID; @@ -6,7 +6,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; public interface ObservationRepository extends BrAPIRepository { diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java new file mode 100644 index 00000000..7f062079 --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationUnitRepository.java @@ -0,0 +1,47 @@ +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; + +import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; +import org.springframework.data.jpa.repository.NativeQuery; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; +import java.util.UUID; + +public interface ObservationUnitRepository extends BrAPIRepository { + @Query("SELECT ou from ObservationUnitEntity ou " + + "LEFT JOIN FETCH ou.position " + + "WHERE ou.id IN :ids") + List findByIds(@Param("ids") List ids); + + @NativeQuery( + "SELECT ou.id, g.id, g.germplasm_name " + + "FROM observation_unit ou " + + "JOIN germplasm g ON g.id = ou.germplasm_id " + + "WHERE ou.id IN :ouIds" + ) + List fetchGermplasmDataForOUs(@Param("ouIds") List ouIds); + + @NativeQuery( + "SELECT EXISTS(" + + "SELECT ou.id " + + "FROM observation_unit ou " + + "JOIN observation_unit_position oup ON ou.id = oup.observation_unit_id " + + "JOIN observation_unit_level_name ouln ON oup.level_name = ouln.id " + + "WHERE oup.level_name = :levelNameDbId AND ou.program_id = :programDbId " + + // The IS NULL checks allow for some moderate custom query generation based off of input params. + "AND (:trialDbId ::uuid IS NULL OR ou.trial_id = :trialDbId) AND (:studyDbId ::uuid IS NULL OR ou.study_id = :studyDbId) " + + ") OR EXISTS ( " + + "SELECT ou.id " + + "FROM observation_unit ou " + + "JOIN observation_unit_position oup ON oup.observation_unit_id = ou.id " + + "JOIN observation_unit_level oul ON oul.position_id = oup.id " + + "WHERE oul.level_name = :levelNameDbId AND ou.program_id = :programDbId " + + "AND (:trialDbId ::uuid IS NULL OR ou.trial_id = :trialDbId) AND (:studyDbId ::uuid IS NULL OR ou.study_id = :studyDbId))" + ) + Boolean existsOUsWithLevelNameAndProgramAndTrialAndStudy(@Param("levelNameDbId") String levelNameDbId, + @Param("programDbId") String programDbId, + @Param("trialDbId") String trialDbId, + @Param("studyDbId") String studyDbId); +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationVariableRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationVariableRepository.java similarity index 58% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationVariableRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationVariableRepository.java index 62476ddb..07fe0483 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ObservationVariableRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ObservationVariableRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationVariableEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/OntologyRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/OntologyRepository.java similarity index 54% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/OntologyRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/OntologyRepository.java index bf8c73d6..0dacc5de 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/OntologyRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/OntologyRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.OntologyEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ScaleRepository.java b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ScaleRepository.java similarity index 53% rename from src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ScaleRepository.java rename to src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ScaleRepository.java index 38f2dbc8..a30d8dff 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/repository/pheno/ScaleRepository.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/repository/primaryEntities/pheno/ScaleRepository.java @@ -1,7 +1,7 @@ -package org.brapi.test.BrAPITestServer.repository.pheno; +package org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno; import org.brapi.test.BrAPITestServer.model.entity.pheno.ScaleEntity; -import org.brapi.test.BrAPITestServer.repository.BrAPIRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.BrAPIRepository; import java.util.UUID; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchService.java index 88d87843..fb44a723 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/SearchService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/SearchService.java @@ -7,7 +7,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.SearchRequestEntity; import org.brapi.test.BrAPITestServer.model.entity.SearchRequestEntity.SearchRequestTypes; -import org.brapi.test.BrAPITestServer.repository.SearchRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.SearchRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/BatchService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/BatchService.java index 3b4464b0..1df37d48 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/BatchService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/BatchService.java @@ -9,7 +9,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.BatchDeleteEntity; import org.brapi.test.BrAPITestServer.model.entity.core.BatchDeleteItemEntity; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; -import org.brapi.test.BrAPITestServer.repository.core.BatchDeleteRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.BatchDeleteRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/CropService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/CropService.java index 3932e698..3fb535a7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/CropService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/CropService.java @@ -6,7 +6,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; -import org.brapi.test.BrAPITestServer.repository.core.CropRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.CropRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java index 174c5a86..4e66dbe6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ListService.java @@ -9,7 +9,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.ListEntity; import org.brapi.test.BrAPITestServer.model.entity.core.ListItemEntity; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; -import org.brapi.test.BrAPITestServer.repository.core.ListRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.ListRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java index a856f055..d6f28e18 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/LocationService.java @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.LocationEntity; -import org.brapi.test.BrAPITestServer.repository.core.LocationRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.LocationRepository; import org.brapi.test.BrAPITestServer.service.GeoJSONUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java index 762705c0..642b25c8 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/PeopleService.java @@ -8,7 +8,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; -import org.brapi.test.BrAPITestServer.repository.core.PeopleRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.PeopleRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.springframework.data.domain.Page; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ProgramService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ProgramService.java index a2fe65b2..720f731b 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ProgramService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ProgramService.java @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; import org.brapi.test.BrAPITestServer.model.entity.core.PersonEntity; import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; -import org.brapi.test.BrAPITestServer.repository.core.ProgramRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.ProgramRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; @@ -76,6 +76,16 @@ public List findPrograms(ProgramSearchRequest request, Metadata metadat return programs; } + public List findByIds(List programDbIds) { + var result = new ArrayList(); + + if (programDbIds.isEmpty()) { + return result; + } + + return programRepository.findByIdIn(programDbIds.stream().map(UUID::fromString).toList()); + } + public Program getProgram(String programDbId) throws BrAPIServerException { return convertFromEntity(getProgramEntity(programDbId, HttpStatus.NOT_FOUND)); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java index 2041f141..cc0d0b7a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/SeasonService.java @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.SeasonEntity; -import org.brapi.test.BrAPITestServer.repository.core.SeasonRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.SeasonRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.springframework.beans.factory.annotation.Autowired; @@ -109,6 +109,16 @@ public Season convertFromEntity(SeasonEntity entity) { return season; } + public List findByIds(List seasonIds) { + var result = new ArrayList(); + + if (!seasonIds.isEmpty()) { + return seasonRepository.findByIdIn(seasonIds.stream().map(UUID::fromString).toList()); + } + + return result; + } + private void updateEntity(SeasonEntity entity, Season request) { if (request.getSeasonName() != null) entity.setSeason(request.getSeasonName()); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java index 62730ce7..d6ea6614 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServerInfoService.java @@ -51,6 +51,7 @@ public static List buildServices(){ .setBase("observationunits").GET().POST().PUT().addPath("{observationUnitDbId}").GET().PUT().setPath("table").GET().withSearch() .setBase("observations").GET().POST().PUT().addPath("{observationDbId}").GET().PUT().setPath("table").GET().withSearch() .setBase("observationlevels").GET().build() + .setBase("observationlevelnames").GET().POST().addPath("{observationlevelnameDbId}").PUT().DELETE().build() //GENOTYPING .setBase("calls").GET().withSearch() .setBase("callsets").GET().addPath("{callSetDbId}").GET().addPath("calls").GET().withSearch() diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServiceBuilder.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServiceBuilder.java index 8a5cddd7..398006d3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServiceBuilder.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/ServiceBuilder.java @@ -53,6 +53,11 @@ public ServiceBuilder GET() { return this; } + public ServiceBuilder DELETE() { + methods.add(MethodsEnum.DELETE); + return this; + } + public ServiceBuilder versions(VersionsEnum ... versions) { this.versions = Arrays.asList(versions); return this; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java index 9ad8f0b9..1b6526ea 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/StudyService.java @@ -3,8 +3,10 @@ import java.util.*; import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; import org.brapi.test.BrAPITestServer.model.entity.core.DataLinkEntity; import org.brapi.test.BrAPITestServer.model.entity.core.EnvironmentParametersEntity; @@ -17,13 +19,15 @@ import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; import org.brapi.test.BrAPITestServer.model.entity.core.StudyLastUpdateEntity; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; +import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationVariableEntity; -import org.brapi.test.BrAPITestServer.repository.core.StudyRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.StudyRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; import org.brapi.test.BrAPITestServer.service.pheno.ObservationVariableService; +import org.brapi.test.BrAPITestServer.service.pheno.ObservationUnitLevelNameService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -43,7 +47,6 @@ import io.swagger.model.core.StudyLastUpdate; import io.swagger.model.core.StudySearchRequest; import io.swagger.model.pheno.ObservationUnitHierarchyLevel; -import io.swagger.model.pheno.ObservationUnitHierarchyLevelEnum; @Service public class StudyService { @@ -55,11 +58,12 @@ public class StudyService { private final PeopleService peopleService; private final SeasonService seasonService; private final ObservationVariableService variableService; + private final ObservationUnitLevelNameService observationUnitLevelNameService; @Autowired public StudyService(StudyRepository studyRepository, TrialService trialService, CropService cropService, LocationService locationService, PeopleService peopleService, SeasonService seasonService, - ObservationVariableService variableService) { + ObservationVariableService variableService, ObservationUnitLevelNameService observationUnitLevelNameService) { this.studyRepository = studyRepository; this.locationService = locationService; @@ -68,6 +72,7 @@ public StudyService(StudyRepository studyRepository, TrialService trialService, this.trialService = trialService; this.cropService = cropService; this.variableService = variableService; + this.observationUnitLevelNameService = observationUnitLevelNameService; } public List findStudies(String commonCropName, String studyType, String programDbId, String locationDbId, @@ -113,6 +118,16 @@ public List findStudies(String commonCropName, String studyType, String p return findStudies(request, metadata); } + public List findByIds(List studyDbIds) { + var result = new ArrayList(); + + if (studyDbIds.isEmpty()) { + return result; + } + + return studyRepository.findByIdIn(studyDbIds.stream().map(UUID::fromString).toList()); + } + public List findStudies(StudySearchRequest request, Metadata metaData) throws BrAPIServerException { @@ -245,11 +260,11 @@ private void updateEntity(StudyEntity entity, StudyNewRequest body) throws BrAPI body.getEnvironmentParameters().stream().map(this::convertToEntity).collect(Collectors.toList())); } if (body.getExperimentalDesign() != null) - entity.setExperimentalDesign(convertToEntity(body.getExperimentalDesign(), entity)); + entity.setExperimentalDesign(convertToEntity(body.getExperimentalDesign())); if (body.getGrowthFacility() != null) - entity.setGrowthFacility(convertToEntity(body.getGrowthFacility(), entity)); + entity.setGrowthFacility(convertToEntity(body.getGrowthFacility())); if (body.getLastUpdate() != null) - entity.setLastUpdate(convertToEntity(body.getLastUpdate(), entity)); + entity.setLastUpdate(convertToEntity(body.getLastUpdate())); if (body.getLicense() != null) entity.setLicense(body.getLicense()); if (body.getLocationDbId() != null) { @@ -257,8 +272,14 @@ private void updateEntity(StudyEntity entity, StudyNewRequest body) throws BrAPI entity.setLocation(location); } if (body.getObservationLevels() != null) { - entity.setObservationLevels( - body.getObservationLevels().stream().map(this::convertToEntity).collect(Collectors.toList())); + + List lvlEntities = convertToEntity(body.getObservationLevels(), body.getProgramDbId()); + + for(ObservationLevelEntity lvlEntity : lvlEntities) { + lvlEntity.setStudy(entity); + } + + entity.setObservationLevels(lvlEntities); } if (body.getObservationUnitsDescription() != null) entity.setObservationUnitsDescription(body.getObservationUnitsDescription()); @@ -386,20 +407,41 @@ private ObservationUnitHierarchyLevel convertFromEntity(ObservationLevelEntity e ObservationUnitHierarchyLevel level = null; if (entity != null) { level = new ObservationUnitHierarchyLevel(); - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(entity.getLevelName())); - level.setLevelOrder(entity.getLevelOrder()); + level.setLevelName(entity.getLevelName().getLevelName()); + level.setLevelOrder(entity.getLevelName().getLevelOrder()); + level.setLevelNameDbId(entity.getLevelName().getId().toString()); + + if (entity.getLevelName().getProgram() != null) { + level.setProgramDbId(entity.getLevelName().getProgram().getId().toString()); + level.setProgramName(entity.getLevelName().getProgram().getName()); + } } return level; } - private ObservationLevelEntity convertToEntity(ObservationUnitHierarchyLevel level) { - ObservationLevelEntity entity = null; - if (level != null) { - entity = new ObservationLevelEntity(); - entity.setLevelName(level.getLevelName().toString()); - entity.setLevelOrder(level.getLevelOrder()); + private List convertToEntity(List levels, String programDbId) + throws BrAPIServerException { + List entities = new ArrayList<>(); + + List submittedLevelNameDbIds = levels.stream() + .map(ObservationUnitHierarchyLevel::getLevelNameDbId) + .toList(); + + if (submittedLevelNameDbIds.isEmpty() && StringUtils.isEmpty(programDbId)) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, "No levelNameDbIds or programDbId available in request. levelNameDbIds can be found using /observationlevelnames GET."); } - return entity; + + Map foundLevelNames = observationUnitLevelNameService.findObservationUnitLevelNames(Arrays.asList(programDbId), submittedLevelNameDbIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + for (String lnDbId : submittedLevelNameDbIds) { + var entity = new ObservationLevelEntity(); + + entity.setLevelName(foundLevelNames.get(lnDbId)); + entities.add(entity); + } + return entities; } private StudyLastUpdate convertFromEntity(StudyLastUpdateEntity entity) { @@ -412,13 +454,12 @@ private StudyLastUpdate convertFromEntity(StudyLastUpdateEntity entity) { return update; } - private StudyLastUpdateEntity convertToEntity(StudyLastUpdate update, StudyEntity study) { + private StudyLastUpdateEntity convertToEntity(StudyLastUpdate update) { StudyLastUpdateEntity entity = null; if (update != null) { entity = new StudyLastUpdateEntity(); entity.setTimestamp(DateUtility.toDate(update.getTimestamp())); entity.setVersion(update.getVersion()); - entity.setStudy(study); } return entity; } @@ -433,13 +474,12 @@ private StudyGrowthFacility convertFromEntity(GrowthFacilityEntity entity) { return gf; } - private GrowthFacilityEntity convertToEntity(StudyGrowthFacility facility, StudyEntity study) { + private GrowthFacilityEntity convertToEntity(StudyGrowthFacility facility) { GrowthFacilityEntity entity = null; if (facility != null) { entity = new GrowthFacilityEntity(); entity.setDescription(facility.getDescription()); entity.setPUI(facility.getPUI()); - entity.setStudy(study); } return entity; } @@ -454,13 +494,12 @@ private StudyExperimentalDesign convertFromEntity(ExperimentalDesignEntity entit return ed; } - private ExperimentalDesignEntity convertToEntity(StudyExperimentalDesign design, StudyEntity study) { + private ExperimentalDesignEntity convertToEntity(StudyExperimentalDesign design) { ExperimentalDesignEntity entity = null; if (design != null) { entity = new ExperimentalDesignEntity(); entity.setDescription(design.getDescription()); entity.setPUI(design.getPUI()); - entity.setStudy(study); } return entity; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java index e99921e7..fb798a5b 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/core/TrialService.java @@ -15,7 +15,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; import org.brapi.test.BrAPITestServer.model.entity.core.PublicationEntity; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; -import org.brapi.test.BrAPITestServer.repository.core.TrialRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.TrialRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; @@ -135,6 +135,16 @@ public List findTrials(@Valid TrialSearchRequest request, Metadata metada return trials; } + public List findByIds(List trialDbIds) { + var result = new ArrayList(); + + if (trialDbIds.isEmpty()) { + return result; + } + + return trialRepository.findByIdIn(trialDbIds.stream().map(UUID::fromString).toList()); + } + public Trial getTrial(String trialDbId) throws BrAPIServerException { return convertFromEntity(getTrialEntity(trialDbId, HttpStatus.NOT_FOUND)); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java index 3ca47af3..cc973ec8 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallService.java @@ -10,7 +10,7 @@ import org.apache.commons.lang3.math.NumberUtils; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.CallEntity; -import org.brapi.test.BrAPITestServer.repository.geno.CallRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.CallRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.springframework.data.domain.Page; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java index 4049bf43..c259db52 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/CallSetService.java @@ -8,7 +8,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.CallSetEntity; -import org.brapi.test.BrAPITestServer.repository.geno.CallSetRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.CallSetRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java index f9a872df..14ffd3bc 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/GenomeMapService.java @@ -8,8 +8,8 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.GenomeMapEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.LinkageGroupEntity; -import org.brapi.test.BrAPITestServer.repository.geno.GenomeMapRepository; -import org.brapi.test.BrAPITestServer.repository.geno.LinkageGroupRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.GenomeMapRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.LinkageGroupRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java index 508715f1..ce4d3187 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/MarkerPositionService.java @@ -4,7 +4,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.MarkerPositionEntity; -import org.brapi.test.BrAPITestServer.repository.geno.MarkerPositionRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.MarkerPositionRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.springframework.data.domain.Page; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java index f83c8236..83bc9dcf 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/PlateService.java @@ -9,7 +9,7 @@ import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; import org.brapi.test.BrAPITestServer.model.entity.core.TrialEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.PlateEntity; -import org.brapi.test.BrAPITestServer.repository.geno.PlateRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.PlateRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java index 73586995..d1384e54 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceService.java @@ -13,8 +13,8 @@ import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceBasesPageEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceSetEntity; -import org.brapi.test.BrAPITestServer.repository.geno.ReferenceBaseRepository; -import org.brapi.test.BrAPITestServer.repository.geno.ReferenceRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.ReferenceBaseRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.ReferenceRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java index f6b9e55e..a4d37c41 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/ReferenceSetService.java @@ -8,7 +8,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.ReferenceSetEntity; -import org.brapi.test.BrAPITestServer.repository.geno.ReferenceSetRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.ReferenceSetRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java index 82645f50..f1c7ecbb 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/SampleService.java @@ -16,7 +16,7 @@ import org.brapi.test.BrAPITestServer.model.entity.geno.PlateEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.SampleEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; -import org.brapi.test.BrAPITestServer.repository.geno.SampleRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.SampleRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java index aabd107d..55fdd89a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantService.java @@ -9,7 +9,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantEntity; -import org.brapi.test.BrAPITestServer.repository.geno.VariantRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VariantRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java index 869bc55b..8c7b1d89 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VariantSetService.java @@ -11,7 +11,7 @@ import org.brapi.test.BrAPITestServer.model.entity.geno.VariantSetAnalysisEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantSetAvailableFormatEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.VariantSetEntity; -import org.brapi.test.BrAPITestServer.repository.geno.VariantSetRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VariantSetRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VendorSampleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VendorSampleService.java index f6089e26..08503652 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VendorSampleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/geno/VendorSampleService.java @@ -4,7 +4,6 @@ import java.util.*; import java.util.stream.Collectors; -import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import jakarta.validation.Valid; @@ -15,9 +14,9 @@ import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorOrderEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorPlateSubmissionEntity; import org.brapi.test.BrAPITestServer.model.entity.geno.vendor.VendorSpecEntity; -import org.brapi.test.BrAPITestServer.repository.geno.VendorOrderRepository; -import org.brapi.test.BrAPITestServer.repository.geno.VendorPlateRepository; -import org.brapi.test.BrAPITestServer.repository.geno.VendorSpecRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VendorOrderRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VendorPlateRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.geno.VendorSpecRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -26,7 +25,6 @@ import org.springframework.stereotype.Service; import io.swagger.model.Metadata; -import io.swagger.model.OntologyReference; import io.swagger.model.geno.Measurement; import io.swagger.model.geno.VendorContact; import io.swagger.model.geno.VendorOrder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/BreedingMethodService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/BreedingMethodService.java index 509efe59..190eafca 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/BreedingMethodService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/BreedingMethodService.java @@ -7,7 +7,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.germ.BreedingMethodEntity; -import org.brapi.test.BrAPITestServer.repository.germ.BreedingMethodRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.BreedingMethodRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossParentService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossParentService.java index e09df763..6df6e7a6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossParentService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossParentService.java @@ -11,8 +11,8 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.CrossingProjectEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmRepository; -import org.brapi.test.BrAPITestServer.repository.pheno.ObservationUnitRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ObservationUnitRepository; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java index 6d3e4849..cffa532a 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossService.java @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.CrossEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossPollinationEventEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossingProjectEntity; -import org.brapi.test.BrAPITestServer.repository.germ.CrossRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.CrossRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; @@ -63,6 +63,16 @@ public List findPlannedCrosses(String crossingProjectDbId, String return crosses; } + public List findByIds(List crossDbIds) { + var result = new ArrayList(); + + if (crossDbIds.isEmpty()) { + return result; + } + + return crossRepository.findByIdIn(crossDbIds.stream().map(UUID::fromString).toList()); + } + public Page findCrossEntities(String crossingProjectDbId, String crossingProjectName, String crossDbId, String crossName, String status, String commonCropName, String programDbId, String externalReferenceId, String externalReferenceID, String externalReferenceSource, Boolean plannedCross, Metadata metadata) diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java index e647ab30..6aecfce6 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/CrossingProjectService.java @@ -2,14 +2,13 @@ import java.util.*; -import io.swagger.model.IndexPagination; import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.CrossingProjectEntity; -import org.brapi.test.BrAPITestServer.repository.germ.CrossingProjectRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.CrossingProjectRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java index 174b8c8b..f96b8e50 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeService.java @@ -7,7 +7,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmAttributeDefinitionEntity; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmAttributeDefinitionRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmAttributeDefinitionRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.pheno.ObservationVariableService; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java index 7b1da280..d3824689 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmAttributeValueService.java @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmAttributeValueEntity; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmAttributeValueRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmAttributeValueRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java index d3a4b184..2946fd58 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/GermplasmService.java @@ -15,8 +15,8 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.*; import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmInstituteEntity.InstituteTypeEnum; import org.brapi.test.BrAPITestServer.model.entity.pheno.TaxonEntity; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmDonorRepository; -import org.brapi.test.BrAPITestServer.repository.germ.GermplasmRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmDonorRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.GermplasmRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.GeoJSONUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; @@ -791,14 +791,16 @@ public List findByIds(List germplasmDbIds) return result; } - List germIdsAsUUIDs = germplasmDbIds.stream().map(UUID::fromString).toList(); - List germsFoundInDb = germplasmRepository.findByIdIn(germIdsAsUUIDs); + var searchRq = new GermplasmSearchRequest(); + searchRq.setGermplasmDbIds(germplasmDbIds); + + List germsFoundInDb = findGermplasmEntitiesWithoutPaging(searchRq); Set germIdsFoundInDB = germsFoundInDb.stream() .map(BrAPIBaseEntity::getId) .collect(Collectors.toSet()); - if (!germIdsFoundInDB.containsAll(germIdsAsUUIDs)) { + if (!germIdsFoundInDB.containsAll(germplasmDbIds.stream().map(UUID::fromString).toList())) { throw new BrAPIServerDbIdNotFoundException("Germplasm Ids passed to findByIds were not found in the DB", HttpStatus.BAD_REQUEST); } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java index 91ccd5a4..f6e270b0 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/PedigreeService.java @@ -14,8 +14,8 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.PedigreeEdgeEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.PedigreeNodeEntity; -import org.brapi.test.BrAPITestServer.repository.germ.PedigreeEdgeRepository; -import org.brapi.test.BrAPITestServer.repository.germ.PedigreeRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.PedigreeEdgeRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.PedigreeRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java index 886ece3b..eee19d98 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/germ/SeedLotService.java @@ -14,8 +14,8 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotContentMixtureEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotTransactionEntity; -import org.brapi.test.BrAPITestServer.repository.germ.SeedLotRepository; -import org.brapi.test.BrAPITestServer.repository.germ.SeedLotTransactionRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.SeedLotRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.germ.SeedLotTransactionRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; @@ -143,6 +143,16 @@ public List findSeedLotTransactions(String seedLotDbId, Stri return null; } + public List findByIds(List seedLotsIds) { + var result = new ArrayList(); + + if (seedLotsIds.isEmpty()) { + return result; + } + + return seedLotRepository.findByIdIn(seedLotsIds.stream().map(UUID::fromString).toList()); + } + public List findSeedLotTransactions(String transactionDbId, String seedLotDbId, String germplasmDbId, String germplasmName, String crossDbId, String crossName, String commonCropName, String programDbId, String externalReferenceId, String externalReferenceID, String externalReferenceSource, diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java index 167d2b3a..a22024a7 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/EventService.java @@ -6,7 +6,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.EventEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.EventRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.EventRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java index b13e34d0..38d42b0e 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ImageService.java @@ -13,7 +13,7 @@ import org.brapi.test.BrAPITestServer.model.entity.pheno.ImageEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.ImageRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ImageRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.GeoJSONUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java index ba43ea1f..453d7cdb 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/MethodService.java @@ -8,7 +8,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.MethodEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.MethodRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.MethodRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java index c0f5791d..6cb448bd 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationService.java @@ -5,15 +5,18 @@ import jakarta.validation.Valid; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.model.dto.ObservationUnitGermplasmData; +import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; import org.brapi.test.BrAPITestServer.model.entity.core.SeasonEntity; import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationVariableEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.ObservationRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ObservationRepository; import org.brapi.test.BrAPITestServer.service.*; import org.brapi.test.BrAPITestServer.service.core.SeasonService; import org.brapi.test.BrAPITestServer.service.core.StudyService; +import org.brapi.test.BrAPITestServer.service.germ.GermplasmService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; @@ -36,15 +39,17 @@ public class ObservationService { private final ObservationUnitService observationUnitService; private final StudyService studyService; private final ObservationVariableService observationVariableService; + private final GermplasmService germplasmService; public ObservationService(ObservationRepository observationRepository, SeasonService seasonService, - @Lazy ObservationUnitService observationUnitService, StudyService studyService, - ObservationVariableService observationVariableService) { + @Lazy ObservationUnitService observationUnitService, StudyService studyService, + ObservationVariableService observationVariableService, GermplasmService germplasmService) { this.observationRepository = observationRepository; this.seasonService = seasonService; this.observationUnitService = observationUnitService; this.studyService = studyService; this.observationVariableService = observationVariableService; + this.germplasmService = germplasmService; } public List findObservations(String observationDbId, String observationUnitDbId, String germplasmDbId, @@ -98,7 +103,7 @@ private ObservationSearchRequest buildObservationsSearchRequest(String observati if (observationUnitLevelName != null || observationUnitLevelOrder != null || observationUnitLevelCode != null) { ObservationUnitLevel level = new ObservationUnitLevel(); if (observationUnitLevelName != null) - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(observationUnitLevelName)); + level.setLevelName(observationUnitLevelName); if (observationUnitLevelOrder != null) level.setLevelOrder(Integer.decode(observationUnitLevelOrder)); if (observationUnitLevelCode != null) @@ -109,7 +114,7 @@ private ObservationSearchRequest buildObservationsSearchRequest(String observati || observationUnitLevelRelationshipCode != null) { ObservationUnitLevelRelationship level = new ObservationUnitLevelRelationship(); if (observationUnitLevelRelationshipName != null) - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(observationUnitLevelRelationshipName)); + level.setLevelName(observationUnitLevelRelationshipName); if (observationUnitLevelRelationshipOrder != null) level.setLevelOrder(Integer.decode(observationUnitLevelRelationshipOrder)); if (observationUnitLevelRelationshipCode != null) @@ -154,6 +159,7 @@ public ObservationTable findObservationsTable(ObservationSearchRequest obsReques .filter(Objects::nonNull).distinct().collect(Collectors.toList()); ObservationTable table = new ObservationTable(); + // TODO: Add support for dynamic observation unit level names for ouPosition in both buildDataMatrix() and buildHeaderRow(), using rq as input table.setData(buildDataMatrix(page, variables)); table.setHeaderRow(buildHeaderRow()); table.setObservationVariables(variables.stream().map(this::convertVariables).collect(Collectors.toList())); @@ -166,7 +172,7 @@ public List findObservations(@Valid ObservationSearchRequest reques throws BrAPIServerException { Page page = findObservationEntities(request, metadata); log.debug("converting "+page.getSize()+" entities"); - List observations = page.map(this::convertFromEntity).getContent(); + List observations = convertFromEntitiesInBatch(page.getContent()); log.debug("done converting entities"); PagingUtility.calculateMetaData(metadata, page); return observations; @@ -193,13 +199,11 @@ public Page findObservationEntities(@Valid ObservationSearchR .leftJoinFetch("*observationUnit.germplasm", "ouGermplasm") .leftJoinFetch("*ouGermplasm.pedigree", "pedigree") .leftJoinFetch("*observationUnit.study", "ouStudy") - .leftJoinFetch("study", "study") - .leftJoinFetch("*study.experimentalDesign", "experimentalDesign") - .leftJoinFetch("*study.growthFacility", "growthFacility") - .leftJoinFetch("*study.lastUpdate", "lastUpdate"); + .leftJoinFetch("study", "study"); if (request.getObservationLevels() != null) { searchQuery = searchQuery - .appendEnumList( + // TODO: This will likely need to be updated so the search works by program and with globally available level names + .appendList( request.getObservationLevels().stream().filter(r -> r.getLevelName() != null) .map(r -> r.getLevelName()).collect(Collectors.toList()), "observationUnit.position.level.levelName") @@ -214,7 +218,8 @@ public Page findObservationEntities(@Valid ObservationSearchR } if (request.getObservationLevelRelationships() != null) { searchQuery = searchQuery.join("observationUnit.position.levelRelationships", "levelRelationship") - .appendEnumList( + // TODO: This will likely need to be updated so the search works by program and with globally available level names + .appendList( request.getObservationLevelRelationships().stream().filter(r -> r.getLevelName() != null) .map(r -> r.getLevelName()).collect(Collectors.toList()), "levelRelationship.levelName") @@ -245,13 +250,15 @@ public Page findObservationEntities(@Valid ObservationSearchR .appendList(request.getTrialDbIds(), "trial.id").appendList(request.getTrialNames(), "trial.trialName"); log.debug("starting search"); - Page page = observationRepository.findAllBySearchAndPaginate(searchQuery, pageReq); + Page observations = observationRepository.findAllBySearchPaginatingWithFetches(searchQuery, pageReq); + + List ids = observations.map(BrAPIBaseEntity::getId).toList(); log.debug("search complete"); - if(!page.isEmpty()) { - observationRepository.fetchXrefs(page, ObservationEntity.class); + if(!observations.isEmpty()) { + observationRepository.fetchXrefs(ids, observations, ObservationEntity.class); } - return page; + return observations; } public Observation getObservation(String observationDbId) throws BrAPIServerException { @@ -274,29 +281,24 @@ public ObservationEntity getObservationEntity(String observationDbId, HttpStatus return observation; } - public List saveObservations(@Valid List requests) throws BrAPIServerException { - List toSave = new ArrayList<>(); - for (ObservationNewRequest request : requests) { - ObservationEntity entity = new ObservationEntity(); - updateEntity(entity, request); // TODO: does updateEntity need to hit the database? - toSave.add(entity); - } - return observationRepository.saveAllAndFlush(toSave) - .stream() - .map(this::convertFromEntity) - .collect(Collectors.toList()); + public List saveObservations(@Valid List requests) { + List toSave = createEntitiesInBatch(requests); + + var savedEntities = observationRepository.saveAll(toSave); + + return convertFromEntitiesInBatch(savedEntities); } public List updateObservations(@Valid Map requests) throws BrAPIServerException { - List savedObservations = new ArrayList<>(); + List savedObservationEntities = new ArrayList<>(); for (Entry entry : requests.entrySet()) { - Observation saved = updateObservation(entry.getKey(), entry.getValue()); - savedObservations.add(saved); + ObservationEntity saved = updateObservation(entry.getKey(), entry.getValue()); + savedObservationEntities.add(saved); } - return savedObservations; + return convertFromEntitiesInBatch(savedObservationEntities); } public List deleteObservations(ObservationSearchRequest body, Metadata metadata) @@ -312,19 +314,51 @@ public List deleteObservations(ObservationSearchRequest body, Metadata m return deletedObservationDbIds; } - public Observation updateObservation(String observationDbId, ObservationNewRequest request) + public ObservationEntity updateObservation(String observationDbId, ObservationNewRequest request) throws BrAPIServerException { ObservationEntity entity = getObservationEntity(observationDbId, HttpStatus.NOT_FOUND); updateEntity(entity, request); - ObservationEntity savedEntity = observationRepository.save(entity); + return observationRepository.save(entity); + } - return convertFromEntity(savedEntity); + public Observation updateObservationAndConvert(String observationDbId, ObservationNewRequest request) + throws BrAPIServerException { + ObservationEntity updatedEntity = updateObservation(observationDbId, request); + + return convertFromEntity(updatedEntity); } + // For single entity conversion use case public Observation convertFromEntity(ObservationEntity entity) { - log.trace("converting obs: " + entity.getId().toString()); - Observation observation = new Observation(); - if (entity != null) { + return convertFromEntitiesInBatch(List.of(entity)).getFirst(); + } + + public List convertFromEntitiesInBatch(List entities) { + return convertFromEntitiesInBatch(entities, null); + } + + public List convertFromEntitiesInBatch(List entities, + Map germplasmDataByOUId) { + var result = new ArrayList(); + + if (entities.isEmpty()) { + return result; + } + + if (germplasmDataByOUId == null) { + germplasmDataByOUId + = observationUnitService.fetchObservationUnitGermplasmData( + entities.stream() + .filter(obs -> obs.getObservationUnit() != null) + .map(obs -> obs.getObservationUnit().getId()) + .distinct() + .toList() + ); + } + + for (ObservationEntity entity : entities) { + log.trace("converting obs: " + entity.getId().toString()); + Observation observation = new Observation(); UpdateUtility.convertFromEntity(entity, observation); observation.setCollector(entity.getCollector()); @@ -343,11 +377,15 @@ public Observation convertFromEntity(ObservationEntity entity) { observation.setValue(entity.getValue()); if (entity.getObservationUnit() != null) { + observation.setObservationUnitDbId(entity.getObservationUnit().getId().toString()); observation.setObservationUnitName(entity.getObservationUnit().getObservationUnitName()); - if (entity.getObservationUnit().getGermplasm() != null) { - observation.setGermplasmDbId(entity.getObservationUnit().getGermplasm().getId().toString()); - observation.setGermplasmName(entity.getObservationUnit().getGermplasm().getGermplasmName()); + + var germplasmData = germplasmDataByOUId.get(entity.getObservationUnit().getId()); + + if (germplasmData != null) { + observation.setGermplasmDbId(germplasmData.getGermplasmDbId()); + observation.setGermplasmName(germplasmData.getGermplasmName()); } if (entity.getObservationUnit().getStudy() != null) { observation.setStudyDbId(entity.getObservationUnit().getStudy().getId().toString()); @@ -356,9 +394,10 @@ public Observation convertFromEntity(ObservationEntity entity) { observation.setStudyDbId(entity.getStudy().getId().toString()); } + result.add(observation); } - return observation; + return result; } private void updateEntity(ObservationEntity entity, ObservationNewRequest observation) throws BrAPIServerException { @@ -394,6 +433,90 @@ private void updateEntity(ObservationEntity entity, ObservationNewRequest observ } } + private List createEntitiesInBatch(List observations) { + + List observationVarIds = observations.stream() + .map(ObservationNewRequest::getObservationVariableDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List seasonIds = observations.stream() + .map(obs -> { + if (obs.getSeason() != null && obs.getSeason().getSeasonDbId() != null) { + return obs.getSeason().getSeasonDbId(); + } + + return null; + }) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List observationUnitIds = observations.stream() + .map(ObservationNewRequest::getObservationUnitDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List studyIds = observations.stream() + .map(ObservationNewRequest::getStudyDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + Map foundObsVarsById = observationVariableService.findByIds(observationVarIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundSeasonsById = seasonService.findByIds(seasonIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundObsUnitsById = observationUnitService.findByIds(observationUnitIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundStudiesById = studyService.findByIds(studyIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + var result = new ArrayList(); + + for (ObservationNewRequest observation : observations) { + var entity = new ObservationEntity(); + + UpdateUtility.updateEntity(observation, entity); + + if (observation.getCollector() != null) + entity.setCollector(observation.getCollector()); + if (observation.getGeoCoordinates() != null) + entity.setGeoCoordinates(GeoJSONUtility.convertToEntity(observation.getGeoCoordinates())); + if (observation.getObservationTimeStamp() != null) + entity.setObservationTimeStamp(DateUtility.toDate(observation.getObservationTimeStamp())); + if (observation.getObservationVariableDbId() != null) { + entity.setObservationVariable(foundObsVarsById.get(observation.getObservationVariableDbId())); + } + if (observation.getSeason() != null && observation.getSeason().getSeasonDbId() != null) { + entity.setSeason(foundSeasonsById.get(observation.getSeason().getSeasonDbId())); + } + if (observation.getUploadedBy() != null) + entity.setUploadedBy(observation.getUploadedBy()); + if (observation.getValue() != null) + entity.setValue(observation.getValue()); + + if (observation.getObservationUnitDbId() != null) { + entity.setObservationUnit(foundObsUnitsById.get(observation.getObservationUnitDbId())); + } else if (observation.getStudyDbId() != null) { + entity.setStudy(foundStudiesById.get(observation.getStudyDbId())); + } + + result.add(entity); + } + + return result; + } + private List> buildDataMatrix(Page observations, List variables) { List> data = new ArrayList<>(); @@ -443,21 +566,9 @@ private List> buildDataMatrix(Page observations, if (obsUnit.getPosition() != null) { row.add(printIfNotNull(obsUnit.getPosition().getPositionCoordinateX())); // POSITIONCOORDINATEX row.add(printIfNotNull(obsUnit.getPosition().getPositionCoordinateY())); // POSITIONCOORDINATEY - row.add(printIfNotNull(obsUnit.getPosition().getFieldCode())); // FIELD - row.add(printIfNotNull(obsUnit.getPosition().getBlockCode())); // BLOCK - row.add(printIfNotNull(obsUnit.getPosition().getEntryCode())); // ENTRY - row.add(printIfNotNull(obsUnit.getPosition().getRepCode())); // REP - row.add(printIfNotNull(obsUnit.getPosition().getPlotCode())); // PLOT - row.add(printIfNotNull(obsUnit.getPosition().getPlantCode())); // PLANT } else { row.add(""); // POSITIONCOORDINATEX row.add(""); // POSITIONCOORDINATEY - row.add(""); // FIELD - row.add(""); // BLOCK - row.add(""); // ENTRY - row.add(""); // REP - row.add(""); // PLOT - row.add(""); // PLANT } } else { @@ -498,12 +609,6 @@ private List buildHeaderRow() { headers.add(ObservationTableHeaderRowEnum.OBSERVATIONUNITNAME); headers.add(ObservationTableHeaderRowEnum.POSITIONCOORDINATEX); headers.add(ObservationTableHeaderRowEnum.POSITIONCOORDINATEY); - headers.add(ObservationTableHeaderRowEnum.FIELD); - headers.add(ObservationTableHeaderRowEnum.BLOCK); - headers.add(ObservationTableHeaderRowEnum.ENTRY); - headers.add(ObservationTableHeaderRowEnum.REP); - headers.add(ObservationTableHeaderRowEnum.PLOT); - headers.add(ObservationTableHeaderRowEnum.PLANT); headers.add(ObservationTableHeaderRowEnum.OBSERVATIONTIMESTAMP); return headers; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java new file mode 100644 index 00000000..1d918e1a --- /dev/null +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitLevelNameService.java @@ -0,0 +1,319 @@ +package org.brapi.test.BrAPITestServer.service.pheno; + +import io.swagger.model.pheno.ObservationLevelNewRequest; +import io.swagger.model.pheno.ObservationUnitHierarchyLevel; +import org.apache.commons.lang3.StringUtils; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; +import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.exceptions.ExceptionUtils; +import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; +import org.brapi.test.BrAPITestServer.model.entity.pheno.ObservationUnitLevelNameEntity; +import org.brapi.test.BrAPITestServer.repository.baseEntities.ObservationUnitLevelNameRepository; +import org.brapi.test.BrAPITestServer.service.core.ProgramService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class ObservationUnitLevelNameService { + private final ObservationUnitLevelNameRepository observationUnitLevelNameRepository; + private final ProgramService programService; + + private final static String GLOBAL_NOT_SET_MSG = "No observation level names were found for the programDbId provided, nor are any global level" + + " names available. Please add via endpoint to attach level names to a program or define " + + "without a program to make them globally accessible."; + + private final static String GLOBAL_AND_PROGRAMMATIC_SET_MSG = "Both programDbId and global=true attributes are set. " + + "A level name cannot be both related to a program and be globally accessible. Choose one."; + + private final static String GLOBAL_KEY_FOR_FOUND_ENTITIES = "global"; + + @Autowired + public ObservationUnitLevelNameService(ObservationUnitLevelNameRepository observationUnitLevelNameRepository, + ProgramService programService) { + this.observationUnitLevelNameRepository = observationUnitLevelNameRepository; + this.programService = programService; + } + + /** + * Returns the verified level name entity. Should only be used with a list of size 1. + */ + public ObservationUnitLevelNameEntity verifyObservationUnitLevelName(String parentProgramDbId, + List submittedLevelName, + Map foundLevelEntitiesByDbId, + Map> foundLevelEntitiesGroupedByProgramId) + throws BrAPIServerException { + + return verifyObservationUnitLevelNames(parentProgramDbId, submittedLevelName, + foundLevelEntitiesByDbId, + foundLevelEntitiesGroupedByProgramId).get(submittedLevelName.getFirst().getLevelName()); + } + + public Map verifyObservationUnitLevelNames(String parentProgramDbId, + List submittedLevelNames, + Map foundLevelEntitiesByDbId, + Map> foundLevelEntitiesGroupedByProgramId) + throws BrAPIServerException { + + Map verifiedEntitiesByLevelName = new HashMap<>(); + List levelNamesNotFound = new ArrayList<>(); + + submittedLevelNames.forEach(sln -> { + + var verifiedLevelNamesCurrentSize = verifiedEntitiesByLevelName.size(); + + if (StringUtils.isNotBlank(sln.getLevelNameDbId()) && foundLevelEntitiesByDbId.containsKey(sln.getLevelNameDbId())) { + ObservationUnitLevelNameEntity entity = foundLevelEntitiesByDbId.get(sln.getLevelNameDbId()); + verifiedEntitiesByLevelName.put(entity.getLevelName(), entity); + } else if (StringUtils.isNotBlank(parentProgramDbId) && StringUtils.isNotBlank(sln.getLevelName()) && foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId) != null) { + List entities = foundLevelEntitiesGroupedByProgramId.get(parentProgramDbId); + + entities.stream() + .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) + .findFirst() + .ifPresent(ouln -> verifiedEntitiesByLevelName.put(ouln.getLevelName(), ouln)); + } else if (StringUtils.isNotBlank(sln.getProgramDbId()) && StringUtils.isNotBlank(sln.getLevelName()) && foundLevelEntitiesGroupedByProgramId.get(sln.getProgramDbId()) != null) { + List entities = foundLevelEntitiesGroupedByProgramId.get(sln.getProgramDbId()); + + entities.stream() + .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) + .findFirst() + .ifPresent(ouln -> verifiedEntitiesByLevelName.put(ouln.getLevelName(), ouln)); + } + + if (verifiedLevelNamesCurrentSize == verifiedEntitiesByLevelName.size() && foundLevelEntitiesGroupedByProgramId.get(GLOBAL_KEY_FOR_FOUND_ENTITIES) != null) { + // All other ways of detecting the level name have failed so far, try the global ones as a last-ditch effort + List globalEntities = foundLevelEntitiesGroupedByProgramId.get(GLOBAL_KEY_FOR_FOUND_ENTITIES); + + globalEntities.stream() + .filter(ouln -> ouln.getLevelName().equals(sln.getLevelName())) + .findFirst() + .ifPresent(ouln -> verifiedEntitiesByLevelName.put(ouln.getLevelName(), ouln)); + } + + if (verifiedLevelNamesCurrentSize == verifiedEntitiesByLevelName.size()) { + // This level name was not found. Add it to the list to notify user which level names are invalid. + levelNamesNotFound.add(sln); + } + }); + + if (!levelNamesNotFound.isEmpty()) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, String.format("The following submitted level names were not found: [%s]. " + + " Please check that these level names exist in the DB by using the /observationlevelnames endpoints. If they do not exist, they can be added there.", + levelNamesNotFound)); + } + + return verifiedEntitiesByLevelName; + } + + /** + * This allows for all found level names to be successfully grouped by programId, because in the case of global level names, + * no programId is allowed. This placeholder returned in this function can be used for global level names. Useful for batching operations. + * + * Example usage: + * + * var foundLevelNamesGroupedByProgramDbId = observationUnitLevelNames.stream() + * .collect(Collectors.groupingBy(ouln -> + * Optional.ofNullable(ouln.getProgram()) + * .map(p -> p.getId().toString()) + * .orElse(observationUnitLevelNameService.getGlobalKeyForFoundEntities()))); + */ + public String getGlobalKeyForFoundEntities() { + return GLOBAL_KEY_FOR_FOUND_ENTITIES; + } + + public List convertFromEntitiesInBatch(List entities) { + List result = new ArrayList<>(); + + for (ObservationUnitLevelNameEntity entity : entities) { + var level = new ObservationUnitHierarchyLevel(); + + level.setLevelNameDbId(entity.getId().toString()); + level.setLevelName(entity.getLevelName()); + level.setLevelOrder(entity.getLevelOrder()); + + if (entity.getProgram() != null) { + level.setProgramDbId(entity.getProgram().getId().toString()); + level.setProgramName(entity.getProgram().getName()); + } + + result.add(level); + } + return result; + } + + public List convertToEntitiesInBatch(List levels) + throws BrAPIServerException { + List result = new ArrayList<>(); + + List programDbIds = levels.stream() + .map(ObservationUnitHierarchyLevel::getProgramDbId) + .filter(Objects::nonNull) + .toList(); + + Map programEntitiesById = programService.findByIds(programDbIds).stream() + .collect(Collectors.toMap(p -> p.getId().toString(), p -> p)); + + for (ObservationLevelNewRequest level : levels) { + var entity = new ObservationUnitLevelNameEntity(); + + entity.setLevelName(level.getLevelName()); + entity.setLevelOrder(level.getLevelOrder()); + + if (level.getProgramDbId() != null) { + ProgramEntity foundProgram = programEntitiesById.get(level.getProgramDbId()); + if (foundProgram != null) { + entity.setProgram(foundProgram); + } else { + throw new BrAPIServerDbIdNotFoundException("program", level.getProgramDbId(), HttpStatus.BAD_REQUEST); + } + } else if (level.getGlobal() == null || !level.getGlobal()){ + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, GLOBAL_NOT_SET_MSG); + } + + result.add(entity); + } + + return result; + } + + public ObservationUnitHierarchyLevel update(String observationLevelNameDbId, + ObservationLevelNewRequest level) + throws BrAPIServerException { + Optional entityOpt = observationUnitLevelNameRepository.findById(UUID.fromString(observationLevelNameDbId)); + + if (entityOpt.isEmpty()) { + throw new BrAPIServerDbIdNotFoundException("ObservationUnitLevelName", observationLevelNameDbId, HttpStatus.BAD_REQUEST); + } + + ObservationUnitLevelNameEntity entity = entityOpt.get(); + + if (level.getLevelName() != null) { + entity.setLevelName(level.getLevelName()); + } + + if (level.getLevelOrder() != null) { + entity.setLevelOrder(level.getLevelOrder()); + } + + if (level.getProgramDbId() != null && level.getGlobal() != null && level.getGlobal()) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, GLOBAL_AND_PROGRAMMATIC_SET_MSG); + } + + if (level.getProgramDbId() != null) { + var program = programService.getProgramEntity(level.getProgramDbId()); + entity.setProgram(program); + } + + if (level.getGlobal() != null && level.getGlobal()) { + // The user sent in a request to make this observation level name global for the system. + // In the DB impl, this simply means it doesn't belong to any program. + entity.setProgram(null); + } + + ObservationUnitLevelNameEntity savedEntity = observationUnitLevelNameRepository.save(entity); + + return convertFromEntitiesInBatch(List.of(savedEntity)).getFirst(); + } + + public List save(List request) + throws BrAPIServerException { + List entities = convertToEntitiesInBatch(request); + + List savedEntities = null; + + try { + savedEntities = observationUnitLevelNameRepository.saveAll(entities); + } catch (DataIntegrityViolationException e) { + ExceptionUtils.checkForPSQLConflict(e.getMostSpecificCause()); + + // If a conflict didn't occur, something else happened on the DB server. Throw a 500 and attach the root cause to the message. + throw new BrAPIServerException(HttpStatus.INTERNAL_SERVER_ERROR, String.format("An DB error occurred while processing level names %s\n\n%s", request, e.getMostSpecificCause())); + } + + return convertFromEntitiesInBatch(savedEntities); + } + + public void deleteObservationLevelName(String observationLevelNameDbId) { + observationUnitLevelNameRepository.deleteById(UUID.fromString(observationLevelNameDbId)); + } + + public List findObservationUnitLevelNames(String programDbId, + Boolean all) + throws BrAPIServerException { + + if (programDbId == null) { + return findObservationUnitLevelNames(Collections.emptyList(), + Collections.emptyList(), + all); + } else { + return findObservationUnitLevelNames(List.of(programDbId), + Collections.emptyList(), + all); + } + } + + public List findObservationUnitLevelNames(List programDbIds, + List levelNameDbIds) + throws BrAPIServerException { + return findObservationUnitLevelNames(programDbIds, levelNameDbIds, null); + } + + // Finds observation unit level names by programDbIds, or if not available, globally (no associated program). + // If all is true, find every observation unit level name in the system. + private List findObservationUnitLevelNames(List programDbIds, + List levelNameDbIds, + Boolean all) + throws BrAPIServerException { + List foundOULevelNames = new ArrayList<>(); + + if (all != null && all) { + return observationUnitLevelNameRepository.findAllObservationUnitLevelNames(); + } + + if (levelNameDbIds != null && !levelNameDbIds.isEmpty()) { + + List result = observationUnitLevelNameRepository.findAllById(levelNameDbIds.stream().map(UUID::fromString).toList()); + + if (result.size() != levelNameDbIds.size()) { + + List foundDbIds = result.stream() + .map(ouln -> ouln.getId().toString()) + .toList(); + List levelNameDbIdsNotFound = levelNameDbIds.stream() + .filter(lnId -> !foundDbIds.contains(lnId)) + .toList(); + + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, + String.format("Level name DB Ids supplied [%s] were not found in the database. " + + "Utilize the /observationlevelnames GET method to find the level name DB Ids you would like to search, " + + "or forgo supplying level name dbIds and try looking up on a programDbId.", levelNameDbIdsNotFound)); + } + + return result; + } + + if (programDbIds != null && !programDbIds.isEmpty()) { + // First look up all level names related to submitted programs if available + foundOULevelNames = observationUnitLevelNameRepository.findObservationUnitLevelNamesByProgram(programDbIds); + } + + if (foundOULevelNames.isEmpty()) { + // None were found. Now try to see if there are globally available level names. + foundOULevelNames = observationUnitLevelNameRepository.findDefaultObservationUnitLevelNames(); + } + + if (foundOULevelNames.isEmpty()) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, + "No observation level names were found for the programDbId provided, nor are any global level" + + " names available. Please add via endpoint to attach level names to a program or define " + + "without a program to make them globally accessible."); + } + + return foundOULevelNames; + } +} diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java index d6356d57..5a7ba02d 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationUnitService.java @@ -4,8 +4,10 @@ import io.swagger.model.Metadata; import io.swagger.model.pheno.*; import jakarta.validation.Valid; +import org.apache.commons.lang3.StringUtils; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; +import org.brapi.test.BrAPITestServer.model.dto.ObservationUnitGermplasmData; import org.brapi.test.BrAPITestServer.model.entity.BrAPIBaseEntity; import org.brapi.test.BrAPITestServer.model.entity.core.ProgramEntity; import org.brapi.test.BrAPITestServer.model.entity.core.StudyEntity; @@ -14,7 +16,7 @@ import org.brapi.test.BrAPITestServer.model.entity.germ.GermplasmEntity; import org.brapi.test.BrAPITestServer.model.entity.germ.SeedLotEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.*; -import org.brapi.test.BrAPITestServer.repository.pheno.ObservationUnitRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ObservationUnitRepository; import org.brapi.test.BrAPITestServer.service.GeoJSONUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; @@ -29,10 +31,10 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.util.*; import java.util.Map.Entry; @@ -51,12 +53,13 @@ public class ObservationUnitService { private final ProgramService programService; private final SeedLotService seedLotService; private final ObservationVariableService observationVariableService; + private final ObservationUnitLevelNameService observationUnitLevelNameService; @Autowired public ObservationUnitService(ObservationUnitRepository observationUnitRepository, StudyService studyService, TrialService trialService, ProgramService programService, ObservationService observationService, GermplasmService germplasmService, SeedLotService seedLotService, CrossService crossService, - ObservationVariableService observationVariableService) { + ObservationVariableService observationVariableService, ObservationUnitLevelNameService observationUnitLevelNameService) { this.observationUnitRepository = observationUnitRepository; this.studyService = studyService; @@ -67,6 +70,7 @@ public ObservationUnitService(ObservationUnitRepository observationUnitRepositor this.observationService = observationService; this.seedLotService = seedLotService; this.observationVariableService = observationVariableService; + this.observationUnitLevelNameService = observationUnitLevelNameService; } public List findObservationUnits(String observationUnitDbId, String observationUnitName, @@ -116,7 +120,7 @@ private ObservationUnitSearchRequest buildObservationUnitsSearchRequest(String o if (observationUnitLevelName != null || observationUnitLevelOrder != null || observationUnitLevelCode != null) { ObservationUnitLevel level = new ObservationUnitLevel(); if (observationUnitLevelName != null) - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(observationUnitLevelName)); + level.setLevelName(observationUnitLevelName); if (observationUnitLevelOrder != null) level.setLevelOrder(Integer.decode(observationUnitLevelOrder)); if (observationUnitLevelCode != null) @@ -127,7 +131,7 @@ private ObservationUnitSearchRequest buildObservationUnitsSearchRequest(String o || observationUnitLevelRelationshipCode != null) { ObservationUnitLevelRelationship level = new ObservationUnitLevelRelationship(); if (observationUnitLevelRelationshipName != null) - level.setLevelName(ObservationUnitHierarchyLevelEnum.fromValue(observationUnitLevelRelationshipName)); + level.setLevelName(observationUnitLevelRelationshipName); if (observationUnitLevelRelationshipOrder != null) level.setLevelOrder(Integer.decode(observationUnitLevelRelationshipOrder)); if (observationUnitLevelRelationshipCode != null) @@ -165,6 +169,7 @@ public ObservationUnitTable findObservationUnitsTable(String observationUnitDbId List variables = observationVariableService.findObservationVariables(varRequest, null); ObservationUnitTable table = new ObservationUnitTable(); + // TODO: Add support for dynamic observation unit level names for ouPosition in both buildDataMatrix() and buildHeaderRow(), using rq as input table.setData(buildDataMatrix(observationUnits, variables)); table.setHeaderRow(buildHeaderRow()); table.setObservationVariables(variables.stream().map(this::convertVariables).collect(Collectors.toList())); @@ -193,6 +198,16 @@ public List findObservationUnits(@Valid ObservationUnitSearchRe return observationUnits; } + public List findByIds(List observationUnitIds) { + var result = new ArrayList(); + + if (!observationUnitIds.isEmpty()) { + return observationUnitRepository.findByIds(observationUnitIds); + } + + return result; + } + public Page findObservationUnitEntities(@Valid ObservationUnitSearchRequest request, Metadata metadata) throws BrAPIServerException { @@ -218,29 +233,33 @@ public Page findObservationUnitEntities(@Valid Observatio if (request.getObservationVariableDbIds() != null || request.getObservationVariableNames() != null) { searchQuery = searchQuery.join("observations", "observation") - .appendList(request.getObservationVariableDbIds(), "*observation.variable.id") - .appendList(request.getObservationVariableNames(), "*observation.variable.name"); + .appendList(request.getObservationVariableDbIds(), "*observation.observationVariable.id") + .appendList(request.getObservationVariableNames(), "*observation.observationVariable.name"); } if (request.getSeasonDbIds() != null) { searchQuery = searchQuery.join("study.seasons", "season").appendList(request.getSeasonDbIds(), "*season.id"); } + if (request.getObservationLevels() != null) { + searchQuery = searchQuery - .appendEnumList(request.getObservationLevels().stream().filter(r -> r.getLevelName() != null) - .map(r -> r.getLevelName()).collect(Collectors.toList()), "position.levelName") + // TODO: This will likely need to be updated so the search works by program and with globally available level names + .appendIds(request.getObservationLevels().stream().filter(r -> r.getLevelName() != null) + .map(ouhl -> UUID.fromString(ouhl.getLevelNameDbId())).toList(), "position.levelName.id") .appendList(request.getObservationLevels().stream().filter(r -> r.getLevelCode() != null) - .map(r -> r.getLevelCode()).collect(Collectors.toList()), "position.levelCode") + .map(ObservationUnitLevel::getLevelCode).collect(Collectors.toList()), "position.levelCode") .appendIntList(request.getObservationLevels().stream().filter(r -> r.getLevelOrder() != null) - .map(r -> r.getLevelOrder()).collect(Collectors.toList()), "position.levelOrder"); + .map(ObservationUnitHierarchyLevel::getLevelOrder).collect(Collectors.toList()), "position.levelOrder"); } if (request.getObservationLevelRelationships() != null) { searchQuery = searchQuery.join("position.observationLevelRelationships", "levelRelationship") - .appendEnumList( + // TODO: This will likely need to be updated so the search works by program and with globally available level names + .appendList( request.getObservationLevelRelationships().stream().filter(r -> r.getLevelName() != null) - .map(r -> r.getLevelName()).collect(Collectors.toList()), - "*levelRelationship.levelName") + .map(ObservationUnitHierarchyLevel::getLevelNameDbId).collect(Collectors.toList()), + "*levelRelationship.levelName.id") .appendList( request.getObservationLevelRelationships().stream().filter(r -> r.getLevelCode() != null) .map(r -> r.getLevelCode()).collect(Collectors.toList()), @@ -265,41 +284,41 @@ public Page findObservationUnitEntities(@Valid Observatio .appendList(request.getTrialNames(), "trial.trailName"); log.debug("Starting search"); - Page page = observationUnitRepository.findAllBySearchAndPaginate(searchQuery, pageReq); + Page observationsUnits = observationUnitRepository.findAllBySearchPaginatingWithFetches(searchQuery, pageReq); + + List ids = observationsUnits.map(BrAPIBaseEntity::getId).toList(); log.debug("Search complete"); - if(!page.isEmpty()) { - observationUnitRepository.fetchXrefs(page, ObservationUnitEntity.class); - fetchTreatments(page); - fetchObsUnitLevelRelationships(page); + if(!observationsUnits.isEmpty()) { + observationUnitRepository.fetchXrefs(ids, observationsUnits, ObservationUnitEntity.class); + fetchTreatments(ids, observationsUnits); + fetchObsUnitLevelRelationships(ids, observationsUnits); } - return page; + return observationsUnits; } - private void fetchTreatments(Page page) - throws BrAPIServerException { + private void fetchTreatments(List ids, Page pagedOUs) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( ObservationUnitEntity.class); searchQuery.leftJoinFetch("treatments", "treatments") - .appendList(page.stream().map(oue -> oue.getId().toString()).collect(Collectors.toList()), "id"); + .appendIds(ids); - Page treatments = observationUnitRepository.findAllBySearchAndPaginate(searchQuery, PageRequest.of(0, page.getSize())); + List treatments = observationUnitRepository.findAllBySearch(searchQuery); Map> treatmentsByOu = new HashMap<>(); treatments.forEach(ou -> treatmentsByOu.put(ou.getId().toString(), ou.getTreatments())); - page.forEach(ou -> ou.setTreatments(treatmentsByOu.get(ou.getId().toString()))); + pagedOUs.forEach(ou -> ou.setTreatments(treatmentsByOu.get(ou.getId().toString()))); } - private void fetchObsUnitLevelRelationships(Page page) - throws BrAPIServerException { + private void fetchObsUnitLevelRelationships(List ids, Page page) { SearchQueryBuilder searchQuery = new SearchQueryBuilder( ObservationUnitEntity.class); searchQuery.leftJoinFetch("position", "position") .leftJoinFetch("*position.observationLevelRelationships", "observationLevelRelationships") - .appendList(page.stream().map(oue -> oue.getId().toString()).collect(Collectors.toList()), "id"); + .appendIds(ids); - Page positions = observationUnitRepository.findAllBySearchAndPaginate(searchQuery, PageRequest.of(0, page.getSize())); + List positions = observationUnitRepository.findAllBySearch(searchQuery); Map positionByOu = new HashMap<>(); positions.forEach(ou -> positionByOu.put(ou.getId().toString(), ou.getPosition())); @@ -336,16 +355,58 @@ public ObservationUnitEntity getObservationUnitEntity(String observationUnitDbId return observationUnit; } - public List saveObservationUnits(@Valid List requests) + /** + * Retrieves all submitted observation units in bulk by their dbId, + * returning a map of each found entity to its original request for fastest access speed in batch updating. + * + * Throws an error if there are any requests not found. + */ + public Map getObservationUnitEntities(Map oURequestByDbId, HttpStatus errorStatus) throws BrAPIServerException { - List toSave = new ArrayList<>(); - for (ObservationUnitNewRequest request : requests) { - ObservationUnitEntity entity = new ObservationUnitEntity(); - updateEntity(entity, request); // TODO: does updateEntity need to hit the database? - toSave.add(entity); + + if (CollectionUtils.isEmpty(oURequestByDbId)) { + throw new BrAPIServerDbIdNotFoundException("observationUnit", "null", errorStatus); + } + + List submittedDbIds = oURequestByDbId.keySet().stream().toList(); + + var searchRq = new ObservationUnitSearchRequest(); + searchRq.observationUnitDbIds(submittedDbIds); + + var metadata = new Metadata(); + var pagination = new IndexPagination(); + + pagination.setPageSize(submittedDbIds.size()); + metadata.setPagination(pagination); + + Page foundEntities = findObservationUnitEntities(searchRq, metadata); + + Map foundEntitiesByDbId = foundEntities.stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + // Use a set here to improve performance of .removeAll() + Set submittedIdsNotFound = new HashSet<>(submittedDbIds); + + submittedIdsNotFound.removeAll(foundEntitiesByDbId.keySet()); + + if (!submittedIdsNotFound.isEmpty()) { + throw new BrAPIServerDbIdNotFoundException(String.format("The following submitted observation unit db ids were not found: [%s]", submittedIdsNotFound), errorStatus); + } + + var result = new HashMap(); + + for (String dbId : foundEntitiesByDbId.keySet()) { + result.put(foundEntitiesByDbId.get(dbId), oURequestByDbId.get(dbId)); } - return observationUnitRepository.saveAllAndFlush(toSave) + return result; + } + + public List saveObservationUnits(@Valid List requests) + throws BrAPIServerException { + List toSave = createEntitiesInBatch(requests); + + return observationUnitRepository.saveAll(toSave) .stream() .map(this::convertFromEntity) .collect(Collectors.toList()); @@ -353,78 +414,104 @@ public List saveObservationUnits(@Valid List updateObservationUnits(@Valid Map requests) throws BrAPIServerException { - List savedObservationUnits = new ArrayList<>(); - for (Entry entry : requests.entrySet()) { - ObservationUnit saved = updateObservationUnit(entry.getKey(), entry.getValue()); - savedObservationUnits.add(saved); - } + Map foundOUEntities = getObservationUnitEntities(requests, HttpStatus.BAD_REQUEST); - return savedObservationUnits; + List toSave = updateEntitiesInBatch(foundOUEntities); + + List saved = observationUnitRepository.saveAll(toSave); + + return saved.stream() + .map(this::convertFromEntity) + .toList(); } public ObservationUnit updateObservationUnit(String observationUnitDbId, @Valid ObservationUnitNewRequest request) throws BrAPIServerException { - ObservationUnitEntity entity = getObservationUnitEntity(observationUnitDbId, HttpStatus.NOT_FOUND); - updateEntity(entity, request); - ObservationUnitEntity savedEntity = observationUnitRepository.save(entity); + ObservationUnitEntity entityToUpdate = getObservationUnitEntity(observationUnitDbId, HttpStatus.NOT_FOUND); + updateEntity(entityToUpdate, request); + ObservationUnitEntity savedEntity = observationUnitRepository.save(entityToUpdate); return convertFromEntity(savedEntity); } + // Grabs the programDbId from an associated trial or study + private String getProgramDbId(String trialDbId, + String studyDbId) throws BrAPIServerException { + TrialEntity trial = null; + StudyEntity study = null; + + if (!StringUtils.isEmpty(trialDbId)) { + trial = trialService.getTrialEntity(trialDbId); + } + + if (trial != null) { + return trial.getProgram().getId().toString(); + } + + if (!StringUtils.isEmpty(studyDbId)) { + study = studyService.getStudyEntity(studyDbId); + } + + if (study != null) { + return study.getProgram().getId().toString(); + } + + return null; + } + public List findObservationLevels(String studyDbId, String trialDbId, String programDbId, Metadata metadata) throws BrAPIServerException { - List allLevels = Arrays.asList(ObservationUnitHierarchyLevelEnum.values()).stream() - .map(levelEnum -> { - ObservationUnitLevel rel = new ObservationUnitLevel(); - rel.setLevelName(levelEnum); - return rel; - }).collect(Collectors.toList()); - - ObservationUnitSearchRequest levelsSearch = buildObservationUnitsSearchRequest(null, null, null, studyDbId, - null, trialDbId, programDbId, null, null, null, null, null, null, null, null, null, false, null, null, - null); - - levelsSearch.setObservationLevels(allLevels); - List units = new ArrayList<>(); - List someunits = findObservationUnits(levelsSearch, - new Metadata().pagination(new IndexPagination())); - units.addAll(someunits); - - levelsSearch.setObservationLevelRelationships(allLevels.stream().map(lvl -> { - ObservationUnitLevelRelationship rel = new ObservationUnitLevelRelationship(); - rel.setLevelCode(lvl.getLevelCode()); - rel.setLevelName(lvl.getLevelName()); - rel.setLevelOrder(lvl.getLevelOrder()); - return rel; - }).collect(Collectors.toList())); - levelsSearch.setObservationLevels(null); - List moreUnits = findObservationUnits(levelsSearch, - new Metadata().pagination(new IndexPagination())); - units.addAll(moreUnits); - - List levels = units.stream() - .filter(unit -> unit.getObservationUnitPosition() != null) - .filter(unit -> unit.getObservationUnitPosition().getObservationLevelRelationships() != null) - .filter(unit -> unit.getObservationUnitPosition().getObservationLevel() != null) - .filter(unit -> unit.getObservationUnitPosition().getObservationLevel().getLevelName() != null) - .map(unit -> { - List list = new ArrayList<>(); - for (ObservationUnitLevel level : unit.getObservationUnitPosition() - .getObservationLevelRelationships()) { - list.add(level); - } - list.add(unit.getObservationUnitPosition().getObservationLevel()); - return list; - }).flatMap(list -> list.stream()).map(level -> level.getLevelName()).distinct().sorted() - .map(levelName -> { + if (StringUtils.isEmpty(studyDbId) && StringUtils.isEmpty(trialDbId) && StringUtils.isEmpty(programDbId)) { + throw new BrAPIServerException(HttpStatus.BAD_REQUEST, "No trialDbId, studyDbId, or programDbId was detected. " + + "Please provide at least one of these to find observation units related to level names."); + } + + // First, if there is no programDbId available, try to grab it from a study or trial + if (StringUtils.isEmpty(programDbId)) { + programDbId = getProgramDbId(trialDbId, studyDbId); + } + + // First, grab all global level names that are not tied to any programs + List foundObsLevelNameEntities = observationUnitLevelNameService.findObservationUnitLevelNames(null, false); + + if (!StringUtils.isEmpty(programDbId)) { + // If programDbId is present, try to grab the level names related to the program submitted. + var levelNamesFoundByProgram = observationUnitLevelNameService.findObservationUnitLevelNames(programDbId, false); + + if (!foundObsLevelNameEntities.containsAll(levelNamesFoundByProgram)) { + foundObsLevelNameEntities.addAll(levelNamesFoundByProgram); + } + } + + List levelNamesRelatedToOUs = new ArrayList<>(); + + for (ObservationUnitLevelNameEntity lnEntity : foundObsLevelNameEntities) { + if (observationUnitRepository.existsOUsWithLevelNameAndProgramAndTrialAndStudy(lnEntity.getId().toString(), + programDbId, + trialDbId, + studyDbId)) { + levelNamesRelatedToOUs.add(lnEntity); + } + } + + List levels = levelNamesRelatedToOUs.stream() + .map(lne -> { ObservationUnitHierarchyLevel level = new ObservationUnitHierarchyLevel(); - level.setLevelName(levelName); - level.setLevelOrder(levelName.ordinal()); + level.setLevelNameDbId(lne.getId().toString()); + level.setLevelName(lne.getLevelName()); + level.setLevelOrder(lne.getLevelOrder()); + + if (lne.getProgram() != null) { + level.setProgramDbId(lne.getProgram().getId().toString()); + level.setProgramName(lne.getProgram().getName()); + } + return level; - }).collect(Collectors.toList()); + }) + .toList(); return PagingUtility.paginateSimpleList(levels, metadata); } @@ -452,7 +539,7 @@ private ObservationUnit convertFromEntity(ObservationUnitEntity entity, boolean } unit.setObservationUnitDbId(entity.getId().toString()); unit.setObservationUnitName(entity.getObservationUnitName()); - unit.setObservationUnitPosition(convertFromEntity(entity.getPosition(), entity.getId().toString())); + unit.setObservationUnitPosition(convertFromEntity(entity.getPosition())); unit.setObservationUnitPUI(entity.getObservationUnitPUI()); if (entity.getSeedLot() != null) { unit.setSeedLotDbId(entity.getSeedLot().getId().toString()); @@ -495,20 +582,20 @@ private ObservationUnit convertFromEntity(ObservationUnitEntity entity, boolean } - private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity entity, String ouDbId) { + private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity entity) { ObservationUnitPosition position = null; if (entity != null) { position = new ObservationUnitPosition(); position.setEntryType(entity.getEntryType()); position.setGeoCoordinates(GeoJSONUtility.convertFromEntity(entity.getGeoCoordinates())); - ObservationUnitLevel level = new ObservationUnitLevel(); - level.setLevelCode(entity.getLevelCode()); - level.setLevelName(entity.getLevelName()); - level.setLevelOrder(entity.getLevelOrder()); - position.setObservationLevel(level); + + if (entity.getLevelName() != null) { + position.setObservationLevel(convertFromEntity(entity.getLevelName(), entity.getLevelCode())); + } if (entity.getObservationLevelRelationships() != null) { + position.setObservationLevelRelationships(entity.getObservationLevelRelationships().stream() - .map(rel -> this.convertFromEntity(rel, ouDbId)).collect(Collectors.toList())); + .map(rel -> this.convertFromEntity(rel)).collect(Collectors.toList())); } position.setPositionCoordinateX(entity.getPositionCoordinateX()); position.setPositionCoordinateXType(entity.getPositionCoordinateXType()); @@ -518,6 +605,25 @@ private ObservationUnitPosition convertFromEntity(ObservationUnitPositionEntity return position; } + private ObservationUnitLevel convertFromEntity(ObservationUnitLevelNameEntity entity, String levelCode) { + ObservationUnitLevel level = null; + + if (entity.getLevelName() != null) { + level = new ObservationUnitLevel(); + level.setLevelCode(levelCode); + level.setLevelName(entity.getLevelName()); + level.setLevelOrder(entity.getLevelOrder()); + level.setLevelNameDbId(entity.getId().toString()); + // If the program is null, then this is a globally scoped level name. + if (entity.getProgram() != null) { + level.setProgramDbId(entity.getProgram().getId().toString()); + level.setProgramName(entity.getProgram().getName()); + } + } + + return level; + } + private ObservationTreatment convertFromEntity(TreatmentEntity entity) { ObservationTreatment treatment = new ObservationTreatment(); treatment.setFactor(entity.getFactor()); @@ -525,107 +631,401 @@ private ObservationTreatment convertFromEntity(TreatmentEntity entity) { return treatment; } - private ObservationUnitLevelRelationship convertFromEntity(ObservationUnitLevelRelationshipEntity entity, String ouDbId) { + private ObservationUnitLevelRelationship convertFromEntity(ObservationUnitLevelRelationshipEntity entity) { ObservationUnitLevelRelationship level = new ObservationUnitLevelRelationship(); level.setLevelCode(entity.getLevelCode()); - level.setLevelName(entity.getLevelName()); - level.setLevelOrder(entity.getLevelOrder()); - if (ouDbId != null) - level.setObservationUnitDbId(ouDbId); + + if (entity.getLevelName() != null) { + level.setLevelName(entity.getLevelName().getLevelName()); + level.setLevelOrder(entity.getLevelName().getLevelOrder()); + level.setLevelNameDbId(entity.getLevelName().getId().toString()); + + // If the program is null, this level name is global. + if (entity.getLevelName().getProgram() != null) { + level.setProgramDbId(entity.getLevelName().getProgram().getId().toString()); + level.setProgramName(entity.getLevelName().getProgram().getName()); + } + } + + if (entity.getObservationUnit() != null) { + level.setObservationUnitDbId(entity.getObservationUnit().getId().toString()); + } + + return level; } private ObservationUnitEntity updateEntity(ObservationUnitEntity entity, ObservationUnitNewRequest unit) + throws BrAPIServerException { + return updateEntitiesInBatch(Map.of(entity, unit)).getFirst(); + } + + private List updateEntitiesInBatch(Map entitiesByRq) throws BrAPIServerException { - UpdateUtility.updateEntity(unit, entity); - - if (unit.getGermplasmDbId() != null) { - GermplasmEntity germplasm = germplasmService.getGermplasmEntity(unit.getGermplasmDbId()); - entity.setGermplasm(germplasm); - } - if (unit.getCrossDbId() != null) { - CrossEntity cross = crossService.getCrossEntity(unit.getCrossDbId(), false); - entity.setCross(cross); - } - if (unit.getObservationUnitName() != null) - entity.setObservationUnitName(unit.getObservationUnitName()); - if (unit.getObservationUnitPUI() != null) - entity.setObservationUnitPUI(unit.getObservationUnitPUI()); - if (unit.getObservationUnitPosition() != null) { - if (entity.getPosition() == null) - entity.setPosition(new ObservationUnitPositionEntity()); - ObservationUnitPositionEntity position = entity.getPosition(); - updateEntity(position, unit.getObservationUnitPosition()); - position.setObservationUnit(entity); - entity.setPosition(position); - } - if (unit.getSeedLotDbId() != null) { - SeedLotEntity seedLot = seedLotService.getSeedLotEntity(unit.getSeedLotDbId()); - entity.setSeedLot(seedLot); - } - if (unit.getTreatments() != null) - entity.setTreatments(unit.getTreatments().stream().map(t -> { - TreatmentEntity e = new TreatmentEntity(); - e.setFactor(t.getFactor()); - e.setModality(t.getModality()); - e.setObservationUnit(entity); - return e; - }).collect(Collectors.toList())); - - if (unit.getStudyDbId() != null) { - StudyEntity study = studyService.getStudyEntity(unit.getStudyDbId()); - entity.setStudy(study); - } else if (unit.getTrialDbId() != null) { - TrialEntity trial = trialService.getTrialEntity(unit.getTrialDbId()); - entity.setTrial(trial); - } else if (unit.getProgramDbId() != null) { - ProgramEntity program = programService.getProgramEntity(unit.getProgramDbId()); - entity.setProgram(program); - } - - return entity; - } - - private void updateEntity(ObservationUnitPositionEntity entity, ObservationUnitPosition position) { + + var oURqs = entitiesByRq.values(); + + // Gather all IDs we want to look up in a bulk lookup. + List germplasmIds = oURqs.stream() + .map(ObservationUnitNewRequest::getGermplasmDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List crossIds = oURqs.stream() + .map(ObservationUnitNewRequest::getCrossDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List seedLotIds = oURqs.stream() + .map(ObservationUnitNewRequest::getSeedLotDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List studyIds = oURqs.stream() + .map(ObservationUnitNewRequest::getStudyDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List trialIds = oURqs.stream() + .map(ObservationUnitNewRequest::getTrialDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List programIds = oURqs.stream() + .map(ObservationUnitNewRequest::getProgramDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + // Now lookup all the IDs in bulk, creating a Map of the ID to the entity so the entities are easily + // retrievable by IDs in the bulk creating of entities later. + Map foundGermsById = germplasmService.findByIds(germplasmIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundCrossesById = crossService.findByIds(crossIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundSeedLotsById = seedLotService.findByIds(seedLotIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundStudiesById = studyService.findByIds(studyIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundTrialsById = trialService.findByIds(trialIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundProgramsById = programService.findByIds(programIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + var observationUnitLevelNames = observationUnitLevelNameService.findObservationUnitLevelNames(null, true); + + var foundLevelNamesByDbId = observationUnitLevelNames.stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + var foundLevelNamesGroupedByProgramDbId = observationUnitLevelNames.stream() + .collect(Collectors.groupingBy(ouln -> + Optional.ofNullable(ouln.getProgram()) + .map(p -> p.getId().toString()) + .orElse(observationUnitLevelNameService.getGlobalKeyForFoundEntities()))); + + List result = new ArrayList<>(); + + for (Entry entry : entitiesByRq.entrySet()) { + + var entity = entry.getKey(); + var oU = entry.getValue(); + + UpdateUtility.updateEntity(entry.getValue(), entry.getKey()); + + if (oU.getGermplasmDbId() != null) { + entity.setGermplasm(foundGermsById.get(oU.getGermplasmDbId())); + } + if (oU.getCrossDbId() != null) { + CrossEntity cross = foundCrossesById.get(oU.getCrossDbId()); + + if (!cross.getPlanned()) { + entity.setCross(cross); + } + } + + if (oU.getObservationUnitName() != null) + entity.setObservationUnitName(oU.getObservationUnitName()); + if (oU.getObservationUnitPUI() != null) + entity.setObservationUnitPUI(oU.getObservationUnitPUI()); + if (oU.getSeedLotDbId() != null) { + SeedLotEntity seedLot = foundSeedLotsById.get(oU.getSeedLotDbId()); + entity.setSeedLot(seedLot); + } + if (oU.getTreatments() != null) + entity.setTreatments(oU.getTreatments().stream().map(t -> { + TreatmentEntity e = new TreatmentEntity(); + e.setFactor(t.getFactor()); + e.setModality(t.getModality()); + e.setObservationUnit(entity); + return e; + }).collect(Collectors.toList())); + + if (oU.getStudyDbId() != null) { + StudyEntity study = foundStudiesById.get(oU.getStudyDbId()); + entity.setStudy(study); + } else if (oU.getTrialDbId() != null) { + TrialEntity trial = foundTrialsById.get(oU.getTrialDbId()); + entity.setTrial(trial); + } else if (oU.getProgramDbId() != null) { + ProgramEntity program = foundProgramsById.get(oU.getProgramDbId()); + entity.setProgram(program); + } + + if (oU.getObservationUnitPosition() != null) { + if (entity.getPosition() == null) + entity.setPosition(new ObservationUnitPositionEntity()); + ObservationUnitPositionEntity position = entity.getPosition(); + updateOUPosition(oU.getObservationUnitPosition(), + entity, + foundLevelNamesByDbId, + foundLevelNamesGroupedByProgramDbId); + position.setObservationUnit(entity); + entity.setPosition(position); + } + + result.add(entity); + } + + return result; + } + + private void updateOUPosition(ObservationUnitPosition position, + ObservationUnitEntity ouEntity, + Map foundLevelNameEntitiesByDbId, + Map> foundLevelNamesGroupedByProgramId) throws BrAPIServerException { + var pEntity = ouEntity.getPosition(); if (position.getEntryType() != null) - entity.setEntryType(position.getEntryType()); + pEntity.setEntryType(position.getEntryType()); if (position.getGeoCoordinates() != null) - entity.setGeoCoordinates(GeoJSONUtility.convertToEntity(position.getGeoCoordinates())); + pEntity.setGeoCoordinates(GeoJSONUtility.convertToEntity(position.getGeoCoordinates())); if (position.getObservationLevel() != null) { if (position.getObservationLevel().getLevelCode() != null) - entity.setLevelCode(position.getObservationLevel().getLevelCode()); - if (position.getObservationLevel().getLevelName() != null) - entity.setLevelName(position.getObservationLevel().getLevelName()); - if (position.getObservationLevel().getLevelOrder() != null) - entity.setLevelOrder(position.getObservationLevel().getLevelOrder()); + pEntity.setLevelCode(position.getObservationLevel().getLevelCode()); + if (position.getObservationLevel().getLevelName() != null) { + var parentProgramDbId = Optional.ofNullable(ouEntity.getProgram()) + .map(p -> p.getId().toString()) + .orElse(null); + + var foundLevelName = observationUnitLevelNameService.verifyObservationUnitLevelName( + parentProgramDbId, + List.of(position.getObservationLevel()), + foundLevelNameEntitiesByDbId, + foundLevelNamesGroupedByProgramId + ); + pEntity.setLevelName(foundLevelName); + } } if (position.getObservationLevelRelationships() != null) - entity.setObservationLevelRelationships(position.getObservationLevelRelationships().stream().map(level -> { - ObservationUnitLevelRelationshipEntity relationshipEntity = new ObservationUnitLevelRelationshipEntity(); - try { - relationshipEntity.setLevelCode(level.getLevelCode()); - relationshipEntity.setLevelName(level.getLevelName()); - relationshipEntity.setLevelOrder(level.getLevelOrder()); - if (level.getObservationUnitDbId() != null) { - ObservationUnitEntity parentEntity = getObservationUnitEntity(level.getObservationUnitDbId()); - relationshipEntity.setObservationUnit(parentEntity); - } - relationshipEntity.setPosition(entity); - } catch (BrAPIServerException e) { - e.printStackTrace(); - } - return relationshipEntity; - }).collect(Collectors.toList())); + updateOULevelRelationships(ouEntity, + position, + foundLevelNameEntitiesByDbId, + foundLevelNamesGroupedByProgramId); if (position.getPositionCoordinateX() != null) - entity.setPositionCoordinateX(position.getPositionCoordinateX()); + pEntity.setPositionCoordinateX(position.getPositionCoordinateX()); if (position.getPositionCoordinateXType() != null) - entity.setPositionCoordinateXType(position.getPositionCoordinateXType()); + pEntity.setPositionCoordinateXType(position.getPositionCoordinateXType()); if (position.getPositionCoordinateY() != null) - entity.setPositionCoordinateY(position.getPositionCoordinateY()); + pEntity.setPositionCoordinateY(position.getPositionCoordinateY()); if (position.getPositionCoordinateYType() != null) - entity.setPositionCoordinateYType(position.getPositionCoordinateYType()); + pEntity.setPositionCoordinateYType(position.getPositionCoordinateYType()); + + } + + private void updateOULevelRelationships(ObservationUnitEntity ouEntity, + ObservationUnitPosition position, + Map foundLevelNameEntitiesByDbId, + Map> foundLevelNamesGroupedByProgramId) + throws BrAPIServerException { + + var pEntity = ouEntity.getPosition(); + + var programDbId = Optional.ofNullable(ouEntity.getProgram()) + .map(p -> p.getId().toString()) + .orElse(null); + + var foundOULevelNames = observationUnitLevelNameService.verifyObservationUnitLevelNames(programDbId, + position.getObservationLevelRelationships(), + foundLevelNameEntitiesByDbId, + foundLevelNamesGroupedByProgramId); + + var relationshipEntities = new ArrayList(); + + for (ObservationUnitLevelRelationship level : position.getObservationLevelRelationships()) { + ObservationUnitLevelRelationshipEntity relationshipEntity = new ObservationUnitLevelRelationshipEntity(); + relationshipEntity.setLevelCode(level.getLevelCode()); + relationshipEntity.setLevelName(foundOULevelNames.get(level.getLevelName())); + if (level.getObservationUnitDbId() != null) { + ObservationUnitEntity parentEntity = getObservationUnitEntity(level.getObservationUnitDbId()); + relationshipEntity.setObservationUnit(parentEntity); + } + relationshipEntity.setPosition(pEntity); + relationshipEntities.add(relationshipEntity); + } + + pEntity.setObservationLevelRelationships(relationshipEntities); + } + + private List createEntitiesInBatch(List oURqs) + throws BrAPIServerException { + // Gather all IDs we want to look up in a bulk lookup. + List germplasmIds = oURqs.stream() + .map(ObservationUnitNewRequest::getGermplasmDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List crossIds = oURqs.stream() + .map(ObservationUnitNewRequest::getCrossDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List seedLotIds = oURqs.stream() + .map(ObservationUnitNewRequest::getSeedLotDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List studyIds = oURqs.stream() + .map(ObservationUnitNewRequest::getStudyDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List trialIds = oURqs.stream() + .map(ObservationUnitNewRequest::getTrialDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + List programIds = oURqs.stream() + .map(ObservationUnitNewRequest::getProgramDbId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + // Now lookup all the IDs in bulk, creating a Map of the ID to the entity so the entities are easily + // retrievable by IDs in the bulk creating of entities later. + Map foundGermsById = germplasmService.findByIds(germplasmIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundCrossesById = crossService.findByIds(crossIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundSeedLotsById = seedLotService.findByIds(seedLotIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundStudiesById = studyService.findByIds(studyIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundTrialsById = trialService.findByIds(trialIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map foundProgramsById = programService.findByIds(programIds) + .stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + List observationUnitLevelNames = observationUnitLevelNameService.findObservationUnitLevelNames(null, true); + + Map foundLevelNamesByDbId = observationUnitLevelNames.stream() + .collect(Collectors.toMap(e -> e.getId().toString(), e -> e)); + + Map> foundLevelNamesGroupedByProgramDbId = observationUnitLevelNames.stream() + .collect(Collectors.groupingBy(ouln -> + Optional.ofNullable(ouln.getProgram()) + .map(p -> p.getId().toString()) + .orElse(observationUnitLevelNameService.getGlobalKeyForFoundEntities()))); + + List result = new ArrayList<>(); + + for (ObservationUnitNewRequest obsUnit : oURqs) { + var entity = new ObservationUnitEntity(); + + UpdateUtility.updateEntity(obsUnit, entity); + + if (obsUnit.getGermplasmDbId() != null) { + entity.setGermplasm(foundGermsById.get(obsUnit.getGermplasmDbId())); + } + if (obsUnit.getCrossDbId() != null) { + entity.setCross(foundCrossesById.get(obsUnit.getCrossDbId())); + } + if (obsUnit.getObservationUnitName() != null) + entity.setObservationUnitName(obsUnit.getObservationUnitName()); + if (obsUnit.getObservationUnitPUI() != null) + entity.setObservationUnitPUI(obsUnit.getObservationUnitPUI()); + if (obsUnit.getSeedLotDbId() != null) { + entity.setSeedLot(foundSeedLotsById.get(obsUnit.getSeedLotDbId())); + } + if (obsUnit.getTreatments() != null) + entity.setTreatments(obsUnit.getTreatments().stream().map(t -> { + TreatmentEntity e = new TreatmentEntity(); + e.setFactor(t.getFactor()); + e.setModality(t.getModality()); + e.setObservationUnit(entity); + return e; + }).collect(Collectors.toList())); + + if (obsUnit.getStudyDbId() != null) { + entity.setStudy(foundStudiesById.get(obsUnit.getStudyDbId())); + } else if (obsUnit.getTrialDbId() != null) { + entity.setTrial(foundTrialsById.get(obsUnit.getTrialDbId())); + } else if (obsUnit.getProgramDbId() != null) { + entity.setProgram(foundProgramsById.get(obsUnit.getProgramDbId())); + } + + if (obsUnit.getObservationUnitPosition() != null) { + if (entity.getPosition() == null) + entity.setPosition(new ObservationUnitPositionEntity()); + ObservationUnitPositionEntity position = entity.getPosition(); + updateOUPosition(obsUnit.getObservationUnitPosition(), + entity, + foundLevelNamesByDbId, + foundLevelNamesGroupedByProgramDbId); + position.setObservationUnit(entity); + entity.setPosition(position); + } + + result.add(entity); + } + + return result; + } + + public Map fetchObservationUnitGermplasmData(List ouIds) { + + if (ouIds.isEmpty()) { + return new HashMap<>(); + } + + var databaseResults = observationUnitRepository.fetchGermplasmDataForOUs(ouIds); + return databaseResults.stream() + .collect((Collectors.toMap( + rs -> (UUID) rs[0], + rs -> new ObservationUnitGermplasmData(rs[1].toString(), rs[2].toString())) + )); } private List> buildDataMatrix(Page observationUnits, @@ -675,21 +1075,9 @@ private List> buildDataMatrix(Page observati if (obsUnit.getPosition() != null) { row.add(printIfNotNull(obsUnit.getPosition().getPositionCoordinateX())); // POSITIONCOORDINATEX row.add(printIfNotNull(obsUnit.getPosition().getPositionCoordinateY())); // POSITIONCOORDINATEY - row.add(printIfNotNull(obsUnit.getPosition().getFieldCode())); // FIELD - row.add(printIfNotNull(obsUnit.getPosition().getBlockCode())); // BLOCK - row.add(printIfNotNull(obsUnit.getPosition().getEntryCode())); // ENTRY - row.add(printIfNotNull(obsUnit.getPosition().getRepCode())); // REP - row.add(printIfNotNull(obsUnit.getPosition().getPlotCode())); // PLOT - row.add(printIfNotNull(obsUnit.getPosition().getPlantCode())); // PLANT } else { row.add(""); // POSITIONCOORDINATEX row.add(""); // POSITIONCOORDINATEY - row.add(""); // FIELD - row.add(""); // BLOCK - row.add(""); // ENTRY - row.add(""); // REP - row.add(""); // PLOT - row.add(""); // PLANT } for (ObservationVariable var : variables) { @@ -727,12 +1115,6 @@ private List buildHeaderRow() { headers.add(ObservationTableHeaderRowEnum.OBSERVATIONUNITNAME); headers.add(ObservationTableHeaderRowEnum.POSITIONCOORDINATEX); headers.add(ObservationTableHeaderRowEnum.POSITIONCOORDINATEY); - headers.add(ObservationTableHeaderRowEnum.FIELD); - headers.add(ObservationTableHeaderRowEnum.BLOCK); - headers.add(ObservationTableHeaderRowEnum.ENTRY); - headers.add(ObservationTableHeaderRowEnum.REP); - headers.add(ObservationTableHeaderRowEnum.PLOT); - headers.add(ObservationTableHeaderRowEnum.PLANT); return headers; } diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java index d953390a..42944b47 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ObservationVariableService.java @@ -8,10 +8,10 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.core.CropEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.*; -import org.brapi.test.BrAPITestServer.repository.core.TraitRepository; -import org.brapi.test.BrAPITestServer.repository.pheno.MethodRepository; -import org.brapi.test.BrAPITestServer.repository.pheno.ObservationVariableRepository; -import org.brapi.test.BrAPITestServer.repository.pheno.ScaleRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.TraitRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.MethodRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ObservationVariableRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ScaleRepository; import org.brapi.test.BrAPITestServer.service.DateUtility; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; @@ -226,6 +226,16 @@ public void convertFromBaseEntity(VariableBaseEntity entity, VariableBaseClass v var.setTrait(traitService.convertFromEntity(entity.getTrait())); } + public List findByIds(List obsVarIds) { + var result = new ArrayList(); + + if (!obsVarIds.isEmpty()) { + return observationVariableRepository.findByIdIn(obsVarIds.stream().map(UUID::fromString).toList()); + } + + return result; + } + private void updateEntity(ObservationVariableEntity entity, ObservationVariableNewRequest request) throws BrAPIServerException { updateBaseEntity(entity, request); diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/OntologyService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/OntologyService.java index a6746129..c9a1e193 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/OntologyService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/OntologyService.java @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.model.entity.pheno.OntologyEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.OntologyReferenceEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.OntologyReferenceHolder; -import org.brapi.test.BrAPITestServer.repository.pheno.OntologyRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.OntologyRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.UpdateUtility; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java index 84d92d37..34448bc3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/ScaleService.java @@ -11,7 +11,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.ScaleEntity; import org.brapi.test.BrAPITestServer.model.entity.pheno.ScaleValidValueCategoryEntity; -import org.brapi.test.BrAPITestServer.repository.pheno.ScaleRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.pheno.ScaleRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; diff --git a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java index 9b8d101d..49bb92a3 100644 --- a/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java +++ b/src/main/java/org/brapi/test/BrAPITestServer/service/pheno/TraitService.java @@ -10,7 +10,7 @@ import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerDbIdNotFoundException; import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException; import org.brapi.test.BrAPITestServer.model.entity.pheno.TraitEntity; -import org.brapi.test.BrAPITestServer.repository.core.TraitRepository; +import org.brapi.test.BrAPITestServer.repository.primaryEntities.core.TraitRepository; import org.brapi.test.BrAPITestServer.service.PagingUtility; import org.brapi.test.BrAPITestServer.service.SearchQueryBuilder; import org.brapi.test.BrAPITestServer.service.UpdateUtility; diff --git a/src/main/resources/db/migration/U004__add_ids_to_study_join_tables.sql b/src/main/resources/db/migration/U004__add_ids_to_study_join_tables.sql new file mode 100644 index 00000000..c2470af6 --- /dev/null +++ b/src/main/resources/db/migration/U004__add_ids_to_study_join_tables.sql @@ -0,0 +1,21 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; +ALTER TABLE study_growth_facility DROP CONSTRAINT study_growth_facility_pkey; +ALTER TABLE study_growth_facility ADD COLUMN id UUID NOT NULL DEFAULT uuid_generate_v4(); +ALTER TABLE study_growth_facility ADD PRIMARY KEY (id); +ALTER TABLE study_growth_facility ALTER COLUMN study_id DROP NOT NULL; +ALTER TABLE study_growth_facility ALTER COLUMN study_id DROP DEFAULT; +ALTER TABLE study_growth_facility ALTER COLUMN id DROP DEFAULT; + +ALTER TABLE study_experimental_design DROP CONSTRAINT study_experimental_design_pkey; +ALTER TABLE study_experimental_design ADD COLUMN id UUID NOT NULL DEFAULT uuid_generate_v4(); +ALTER TABLE study_experimental_design ADD PRIMARY KEY (id); +ALTER TABLE study_experimental_design ALTER COLUMN study_id DROP NOT NULL; +ALTER TABLE study_experimental_design ALTER COLUMN study_id DROP DEFAULT; +ALTER TABLE study_experimental_design ALTER COLUMN id DROP DEFAULT; + +ALTER TABLE study_last_update DROP CONSTRAINT study_last_update_pkey; +ALTER TABLE study_last_update ADD COLUMN id UUID NOT NULL DEFAULT uuid_generate_v4(); +ALTER TABLE study_last_update ADD PRIMARY KEY (id); +ALTER TABLE study_last_update ALTER COLUMN study_id DROP NOT NULL; +ALTER TABLE study_last_update ALTER COLUMN study_id DROP DEFAULT; +ALTER TABLE study_last_update ALTER COLUMN id DROP DEFAULT; \ No newline at end of file diff --git a/src/main/resources/db/migration/U005.001__add_treatments_back_to_ou_addinfo.sql b/src/main/resources/db/migration/U005.001__add_treatments_back_to_ou_addinfo.sql new file mode 100644 index 00000000..af79b9d2 --- /dev/null +++ b/src/main/resources/db/migration/U005.001__add_treatments_back_to_ou_addinfo.sql @@ -0,0 +1,18 @@ +WITH treatment_json AS (SELECT + observation_unit_id, + jsonb_agg( + jsonb_build_object('factor', factor) + ) AS treatments + FROM observation_unit_treatment + GROUP BY observation_unit_id) + +UPDATE observation_unit ou +SET additional_info = + jsonb_set( + COALESCE(ou.additional_info, '{}'::jsonb), + '{treatments}', + tj.treatments, + true + ) + FROM treatment_json tj +WHERE ou.id = tj.observation_unit_id; \ No newline at end of file diff --git a/src/main/resources/db/migration/U005__drop_observation_level_name.sql b/src/main/resources/db/migration/U005__drop_observation_level_name.sql new file mode 100644 index 00000000..08753a7a --- /dev/null +++ b/src/main/resources/db/migration/U005__drop_observation_level_name.sql @@ -0,0 +1,16 @@ +ALTER TABLE observation_unit_level + DROP COLUMN level_name, + ADD COLUMN level_name INTEGER, + ADD COLUMN level_order INTEGER; + +ALTER TABLE observation_unit_position + DROP COLUMN level_name, + ADD COLUMN level_name INTEGER, + ADD COLUMN level_order INTEGER; + +ALTER TABLE study_observation_level + DROP COLUMN level_name, + ADD COLUMN level_name TEXT, + ADD COLUMN level_order INTEGER; + +DROP TABLE observation_unit_level_name; \ No newline at end of file diff --git a/src/main/resources/db/migration/V004__drop_study_join_ids.sql b/src/main/resources/db/migration/V004__drop_study_join_ids.sql new file mode 100644 index 00000000..9a190fe6 --- /dev/null +++ b/src/main/resources/db/migration/V004__drop_study_join_ids.sql @@ -0,0 +1,11 @@ +ALTER TABLE study_growth_facility DROP CONSTRAINT study_growth_facility_pkey; +ALTER TABLE study_growth_facility DROP COLUMN id; +ALTER TABLE study_growth_facility ADD PRIMARY KEY (study_id); + +ALTER TABLE study_experimental_design DROP CONSTRAINT study_experimental_design_pkey; +ALTER TABLE study_experimental_design DROP COLUMN id; +ALTER TABLE study_experimental_design ADD PRIMARY KEY (study_id); + +ALTER TABLE study_last_update DROP CONSTRAINT study_last_update_pkey; +ALTER TABLE study_last_update DROP COLUMN id; +ALTER TABLE study_last_update ADD PRIMARY KEY (study_id); \ No newline at end of file diff --git a/src/main/resources/db/migration/V005.001__remove_treatments_from_ou_addinfo.sql b/src/main/resources/db/migration/V005.001__remove_treatments_from_ou_addinfo.sql new file mode 100644 index 00000000..f2ad3294 --- /dev/null +++ b/src/main/resources/db/migration/V005.001__remove_treatments_from_ou_addinfo.sql @@ -0,0 +1 @@ +UPDATE observation_unit SET additional_info = additional_info - 'treatments'; \ No newline at end of file diff --git a/src/main/resources/db/migration/V005.002__migrate_observation_levels.sql b/src/main/resources/db/migration/V005.002__migrate_observation_levels.sql new file mode 100644 index 00000000..47346b7e --- /dev/null +++ b/src/main/resources/db/migration/V005.002__migrate_observation_levels.sql @@ -0,0 +1,116 @@ +-- Create new observation level names for each unique observationLevel in +-- the additional_info column of the observation_unit table +-- +-- Assumption: all observation_unit.program_id have ids which is true for our +-- usage. Database allows NULLs but we don't have to handle that +-- +-- * The level order will be 0 for all of these indicating Exp Unit +-- * All level names should be converted to lower case and combined +-- in the case of different cases to reference the same level +-- * Level names should be created for the program the observation unit is in, not globally +INSERT INTO observation_unit_level_name (level_name, level_order, program_id) +SELECT DISTINCT + lower(btrim(ou.additional_info ->> 'observationLevel')) AS level_name, + 0 AS level_order, + ou.program_id +FROM observation_unit ou +WHERE NULLIF(btrim(ou.additional_info ->> 'observationLevel'), '') IS NOT NULL + AND ou.program_id IS NOT NULL + ON CONFLICT (level_name, program_id) DO NOTHING; +-- on conflict only relevant for test servers, won't have conflicts on prod because +-- no additional observationlevelnames have been created other than global defaults from migration + +-- Update global level references to newly created program scoped levels +-- For prod, these will be: +-- * plot +-- * plant +-- * fish +-- * bine +-- * tree +-- There will be multiple instances as some levels are reused in different programs +-- +-- Need to handle observation_unit_position, but can skip & observation_unit_level and +-- study_observation_level. bi-api has never written study_observation_level and no records exist +-- in prod. observation_unit_level only has rep and block global references and those were already +-- updated in a previous migration. + +-- Updates observation_unit_position.level_name to point to the program-scoped +-- observation_unit_level_name record that matches the observation unit's +-- additional_info.observationLevel value. +-- +-- Only updates rows where: +-- * additional_info.observationLevel is present and not blank +-- * observation_unit.program_id is present +-- * the current linked level is null or does not already match the target +-- * some data like tree will point to plot due to how old data was written and will be fixed by this +-- * some data has null levels due to how it was written and will be fixed by this +WITH rows_to_update AS ( + SELECT + oup.id AS observation_unit_position_id, + target.id AS target_level_id + FROM observation_unit_position oup + JOIN observation_unit ou + ON ou.id = oup.observation_unit_id + JOIN observation_unit_level_name target + ON target.program_id = ou.program_id + AND target.level_name = lower(btrim(ou.additional_info ->> 'observationLevel')) + WHERE NULLIF(btrim(ou.additional_info ->> 'observationLevel'), '') IS NOT NULL + AND ou.program_id IS NOT NULL + AND oup.level_name IS DISTINCT FROM target.id + ) +UPDATE observation_unit_position oup +SET level_name = rows_to_update.target_level_id + FROM rows_to_update +WHERE oup.id = rows_to_update.observation_unit_position_id; + +-- Assertion to assure we don't remove additional_info.observationLevel where +-- references can't be updated. For our prod data, shouldn't be any. +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM observation_unit ou + WHERE NULLIF(btrim(ou.additional_info ->> 'observationLevel'), '') IS NOT NULL + AND ( + ou.program_id IS NULL + OR NOT EXISTS ( + SELECT 1 + FROM observation_unit_level_name ouln + WHERE ouln.program_id = ou.program_id + AND ouln.level_name = lower(btrim(ou.additional_info ->> 'observationLevel')) + ) + ) + ) THEN + RAISE EXCEPTION + 'V005.002 cannot remove observationLevel from observation_unit.additional_info because some rows could not be + mapped'; +END IF; +END $$; + +-- Remove observationLevel from additional_info in observation_unit table as it is no longer needed +UPDATE observation_unit +SET additional_info = additional_info - 'observationLevel'; + +-- Remove unused global level names (will exclude rep & block). On prod, these will be removed: +-- * entry +-- * field +-- * pot +-- * sample +-- * study +-- * sub-block +-- * sub-plot +-- Level is unused if not referenced in tables: +-- * observation_unit_position +-- * observation_unit_level +-- * study_observation_level has no existing data in prod but included +DELETE FROM observation_unit_level_name ouln +WHERE ouln.program_id IS NULL + AND NOT EXISTS ( + SELECT 1 FROM observation_unit_position oup WHERE oup.level_name = ouln.id + ) + AND NOT EXISTS ( + SELECT 1 FROM observation_unit_level oul WHERE oul.level_name = ouln.id + ) + AND NOT EXISTS ( + SELECT 1 FROM study_observation_level sol WHERE sol.level_name = ouln.id + ); diff --git a/src/main/resources/db/migration/V005__create_observation_level_name.sql b/src/main/resources/db/migration/V005__create_observation_level_name.sql new file mode 100644 index 00000000..bba997b3 --- /dev/null +++ b/src/main/resources/db/migration/V005__create_observation_level_name.sql @@ -0,0 +1,553 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + +CREATE TABLE observation_unit_level_name ( + id UUID DEFAULT uuid_generate_v4(), + CONSTRAINT observation_unit_level_name_pk PRIMARY KEY(id), + level_name VARCHAR(64) NOT NULL, + level_order INTEGER, + program_id UUID, + CONSTRAINT observation_unit_level_name_program_fk FOREIGN KEY(program_id) REFERENCES program(id) +); + +CREATE UNIQUE INDEX lvl_name_global_unique_idx + ON observation_unit_level_name (level_name) + WHERE program_id IS NULL; + +CREATE UNIQUE INDEX lvl_name_program_id_idx ON observation_unit_level_name (level_name, program_id); + +-- Set legacy level names +INSERT INTO observation_unit_level_name (level_name, level_order) + VALUES + ('study', 0), + ('field', 1), + ('entry', 2), + ('rep', 3), + ('block', 4), + ('sub-block', 5), + ('plot', 6), + ('sub-plot', 7), + ('plant', 8), + ('pot', 9), + ('sample', 10); + +ALTER TABLE observation_unit_level + ADD COLUMN level_name_new UUID, + ADD CONSTRAINT observation_unit_level_name_fk FOREIGN KEY (level_name_new) REFERENCES observation_unit_level_name(id); + +-- Now migrate legacy enum data to use newly create entries in observation_unit_level_name table. + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'study') subquery +WHERE + observation_unit_level.level_name = 0; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'field') subquery +WHERE + observation_unit_level.level_name = 1; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'entry') subquery +WHERE + observation_unit_level.level_name = 2; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'rep') subquery +WHERE + observation_unit_level.level_name = 3; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'block') subquery +WHERE + observation_unit_level.level_name = 4; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-block') subquery +WHERE + observation_unit_level.level_name = 5; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plot') subquery +WHERE + observation_unit_level.level_name = 6; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-plot') subquery +WHERE + observation_unit_level.level_name = 7; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plant') subquery +WHERE + observation_unit_level.level_name = 8; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'pot') subquery +WHERE + observation_unit_level.level_name = 9; + +UPDATE + observation_unit_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sample') subquery +WHERE + observation_unit_level.level_name = 10; + +ALTER TABLE observation_unit_position + ADD COLUMN level_name_new UUID, + ADD CONSTRAINT observation_unit_position_level_name_fk FOREIGN KEY (level_name_new) REFERENCES observation_unit_level_name(id); + +-- Now migrate legacy enum data to use newly create entries in observation_unit_level_name table. + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'study') subquery +WHERE + observation_unit_position.level_name = 0; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'field') subquery +WHERE + observation_unit_position.level_name = 1; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'entry') subquery +WHERE + observation_unit_position.level_name = 2; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'rep') subquery +WHERE + observation_unit_position.level_name = 3; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'block') subquery +WHERE + observation_unit_position.level_name = 4; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-block') subquery +WHERE + observation_unit_position.level_name = 5; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plot') subquery +WHERE + observation_unit_position.level_name = 6; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-plot') subquery +WHERE + observation_unit_position.level_name = 7; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plant') subquery +WHERE + observation_unit_position.level_name = 8; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'pot') subquery +WHERE + observation_unit_position.level_name = 9; + +UPDATE + observation_unit_position +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sample') subquery +WHERE + observation_unit_position.level_name = 10; + +ALTER TABLE study_observation_level + ADD COLUMN level_name_new UUID, + ADD CONSTRAINT study_observation_level_name_fk FOREIGN KEY (level_name_new) REFERENCES observation_unit_level_name(id); + +-- Now migrate legacy enum data to use newly create entries in observation_unit_level_name table. + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'study') subquery +WHERE + study_observation_level.level_name = 'study'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'field') subquery +WHERE + study_observation_level.level_name = 'field'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'entry') subquery +WHERE + study_observation_level.level_name = 'entry'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'rep') subquery +WHERE + study_observation_level.level_name = 'rep'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'block') subquery +WHERE + study_observation_level.level_name = 'block'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-block') subquery +WHERE + study_observation_level.level_name = 'sub-block'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plot') subquery +WHERE + study_observation_level.level_name = 'plot'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sub-plot') subquery +WHERE + study_observation_level.level_name = 'sub-plot'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'plant') subquery +WHERE + study_observation_level.level_name = 'plant'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'pot') subquery +WHERE + study_observation_level.level_name = 'pot'; + +UPDATE + study_observation_level +SET + level_name_new = subquery.id +FROM + ( + SELECT + id + FROM + observation_unit_level_name ouln + WHERE + ouln.level_name = 'sample') subquery +WHERE + study_observation_level.level_name = 'sample'; + +ALTER TABLE observation_unit_position DROP COLUMN level_name, DROP COLUMN level_order; +ALTER TABLE observation_unit_position RENAME COLUMN level_name_new TO level_name; + +ALTER TABLE observation_unit_level DROP COLUMN level_name, DROP COLUMN level_order; +ALTER TABLE observation_unit_level RENAME COLUMN level_name_new TO level_name; + +ALTER TABLE study_observation_level DROP COLUMN level_name, DROP COLUMN level_order; +ALTER TABLE study_observation_level RENAME COLUMN level_name_new TO level_name;