diff --git a/pom.xml b/pom.xml
index 962d101a..a1e201c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,6 +20,7 @@
21
2.10.0
2.0.16
+ 2.18.1
@@ -73,28 +74,11 @@
io.jsonwebtoken
jjwt
0.9.1
-
-
- com.fasterxml.jackson.core
- jackson-databind
-
-
com.google.api-client
google-api-client
1.27.0
-
-
- com.fasterxml.jackson.core
- jackson-core
-
-
-
-
- com.fasterxml.jackson.core
- jackson-databind
- [2.9.9.1,)
io.springfox
@@ -106,11 +90,6 @@
springfox-swagger-ui
${springfox-version}
-
- com.github.joschi.jackson
- jackson-datatype-threetenbp
- 2.8.4
-
jakarta.annotation
jakarta.annotation-api
@@ -143,6 +122,18 @@
+
+
+
+ com.fasterxml.jackson
+ jackson-bom
+ ${jackson.version}
+ pom
+ import
+
+
+
+
@@ -161,7 +152,7 @@
org.springframework.boot
spring-boot-maven-plugin
- 2.7.5
+ ${spring.version}
@@ -173,21 +164,4 @@
-
-
- spring-releases
- https://repo.spring.io/libs-release
-
-
- spring-milestone
- https://repo.spring.io/libs-milestone
-
-
-
-
- spring-releases
- https://repo.spring.io/libs-release
-
-
-
diff --git a/src/main/java/io/swagger/model/FilterBy.java b/src/main/java/io/swagger/model/FilterBy.java
new file mode 100644
index 00000000..acbc03e7
--- /dev/null
+++ b/src/main/java/io/swagger/model/FilterBy.java
@@ -0,0 +1,24 @@
+package io.swagger.model;
+
+public class FilterBy {
+
+ private String filterOn;
+ private String value;
+
+ public String getFilterOn() {
+ return filterOn;
+ }
+
+ public void setFilterOn(String filterOn) {
+ this.filterOn = filterOn;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+}
diff --git a/src/main/java/io/swagger/model/SearchRequest.java b/src/main/java/io/swagger/model/SearchRequest.java
index 8ad217c4..aaad3b9a 100644
--- a/src/main/java/io/swagger/model/SearchRequest.java
+++ b/src/main/java/io/swagger/model/SearchRequest.java
@@ -2,9 +2,15 @@
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.model.sort.SortBy;
+import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException;
+import org.brapi.test.BrAPITestServer.model.dto.EntityColumnNameAndType;
+import org.brapi.test.BrAPITestServer.model.dto.EntityType;
+import org.springframework.http.HttpStatus;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
public abstract class SearchRequest {
@JsonIgnore
@@ -25,6 +31,20 @@ public abstract class SearchRequest {
@JsonProperty("externalReferenceSources")
protected List externalReferenceSources = null;
+ @JsonProperty("filterBy")
+ protected List filterBy = null;
+
+ @JsonProperty("sortBy")
+ protected List sortBy = null;
+
+ @JsonIgnore
+ protected Map sortFilterEntityColumnNamesByRequestName = null;
+
+ @JsonIgnore
+ public List getExternalReferenceIds() {
+ return externalReferenceIds;
+ }
+
final public SearchRequest page(Integer page) {
this.page = page;
return this;
@@ -119,4 +139,75 @@ public void addExternalReferenceItem(String externalReferenceId, String external
}
}
+
+ public List getFilterBy() {
+ return filterBy;
+ }
+
+ public void setFilterBy(List filterBy) throws BrAPIServerException {
+
+ if (filterBy == null || filterBy.isEmpty()) {
+ return;
+ }
+
+ Map allowedSortFilterNames = getEntityColAndTypeBySubmittedNameMap();
+
+ for (FilterBy filterByItem : filterBy) {
+
+ if (filterByItem.getFilterOn() == null || filterByItem.getFilterOn().isEmpty()) {
+ throw new BrAPIServerException(HttpStatus.BAD_REQUEST, "filterOn attribute not provided in element of filterBy list.");
+ }
+
+ if (filterByItem.getValue() == null || filterByItem.getValue().isEmpty()) {
+ throw new BrAPIServerException(HttpStatus.BAD_REQUEST, "value attribute not provided in element of filterBy list.");
+ }
+
+ EntityColumnNameAndType entityColumnNameAndType = allowedSortFilterNames.get(filterByItem.getFilterOn());
+
+ if (entityColumnNameAndType == null) {
+ throw new BrAPIServerException(HttpStatus.BAD_REQUEST,
+ String.format("Supplied filterColumn [%s] not available in allowed names [%s]", filterByItem.getFilterOn(), allowedSortFilterNames.keySet())
+ );
+ }
+
+ if (entityColumnNameAndType.getEntityType() == EntityType.BOOLEAN) {
+ // TODO: Add support for this when it becomes relevant for BI or when there is time.
+ throw new BrAPIServerException(HttpStatus.BAD_REQUEST, String.format("Filtering not implemented for column name [%s] with associated data type [%s]", entityColumnNameAndType.getEntityColumnName(), EntityType.BOOLEAN));
+ }
+ }
+ this.filterBy = filterBy;
+ }
+
+ public List getSortByElements() {
+ return sortBy;
+ }
+
+ public void setSortBy(List sortBy) throws BrAPIServerException {
+
+ if (sortBy == null || sortBy.isEmpty()) {
+ return;
+ }
+
+ Map allowedSortFilterNames = getEntityColAndTypeBySubmittedNameMap();
+
+ for (SortBy sortByItem : sortBy) {
+ if (sortByItem.getSortedOn() == null || sortByItem.getSortedOn().isEmpty()) {
+ throw new BrAPIServerException(HttpStatus.BAD_REQUEST, "sortedOn attribute not provided in element of sortBy list");
+ }
+
+ EntityColumnNameAndType sortColumnEntityNameAndType = getEntityColAndTypeBySubmittedNameMap().get(sortByItem.getSortedOn());
+
+ if (sortColumnEntityNameAndType == null) {
+ throw new BrAPIServerException(HttpStatus.BAD_REQUEST,
+ String.format("Supplied sortColumn [%s] not available in allowed names [%s]", sortByItem.getSortedOn(), allowedSortFilterNames.keySet())
+ );
+ }
+ }
+
+ this.sortBy = sortBy;
+ }
+
+ public Map getEntityColAndTypeBySubmittedNameMap() throws BrAPIServerException {
+ throw new BrAPIServerException(HttpStatus.BAD_REQUEST, String.format("Sort/Filtering not implemented for %s", this.getClass().getSimpleName()));
+ }
}
diff --git a/src/main/java/io/swagger/model/core/SortBy.java b/src/main/java/io/swagger/model/core/SortBy.java
deleted file mode 100644
index 8a132a3e..00000000
--- a/src/main/java/io/swagger/model/core/SortBy.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package io.swagger.model.core;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-
-public enum SortBy {
-
- STUDYDBID("studyDbId"),
-
- STARTDATE("startDate"),
-
- ENDDATE("endDate"),
-
- TRIALDBID("trialDbId"),
-
- TRIALNAME("trialName"),
-
- PROGRAMDBID("programDbId"),
-
- LOCATIONDBID("locationDbId"),
-
- SEASONDBID("seasonDbId"),
-
- STUDYTYPE("studyType"),
-
- STUDYNAME("studyName"),
-
- STUDYLOCATION("studyLocation"),
-
- PROGRAMNAME("programName"),
-
- GERMPLASMDBID("germplasmDbId"),
-
- OBSERVATIONVARIABLEDBID("observationVariableDbId");
-private String value;
-
- SortBy(String value) {
- this.value = value;
- }
-
- @Override
- @JsonValue
- public String toString() {
- return String.valueOf(value);
- }
-
- @JsonCreator
- public static SortBy fromValue(String text) {
- for (SortBy b : SortBy.values()) {
- if (String.valueOf(b.value).equals(text)) {
- return b;
- }
- }
- return null;
- }
-}
diff --git a/src/main/java/io/swagger/model/core/StudySearchRequest.java b/src/main/java/io/swagger/model/core/StudySearchRequest.java
index 0b26436b..94e760ff 100644
--- a/src/main/java/io/swagger/model/core/StudySearchRequest.java
+++ b/src/main/java/io/swagger/model/core/StudySearchRequest.java
@@ -1,14 +1,36 @@
package io.swagger.model.core;
+import java.util.Map;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.model.SearchRequest;
+import org.brapi.test.BrAPITestServer.model.dto.EntityColumnNameAndType;
+import org.brapi.test.BrAPITestServer.model.dto.EntityType;
+
import java.util.ArrayList;
import java.util.List;
public class StudySearchRequest extends SearchRequest {
+
+ // Key - allowed sort or field filter name for this entity
+ // Value = entity field name and type that represents the submitted field. Used later on in query building.
+ private static final Map ALLOWED_SORT_AND_FILTER_FIELDS =
+ Map.ofEntries(
+ Map.entry("germplasmDbId", new EntityColumnNameAndType("*obsunit.germplasm.id", EntityType.UUID)),
+ Map.entry("locationDbId", new EntityColumnNameAndType("location.id", EntityType.UUID)),
+ Map.entry("observationVariableDbId", new EntityColumnNameAndType("*observation.observationVariable.id", EntityType.UUID)),
+ Map.entry("programDbId", new EntityColumnNameAndType("trial.program.id", EntityType.UUID)),
+ Map.entry("programName", new EntityColumnNameAndType("trial.program.name", EntityType.TEXT)),
+ Map.entry("seasonDbId", new EntityColumnNameAndType("*season.id", EntityType.UUID)),
+ Map.entry("studyDbId", new EntityColumnNameAndType("id", EntityType.UUID)),
+ Map.entry("studyLocation", new EntityColumnNameAndType("location.id", EntityType.UUID)),
+ Map.entry("trialDbId", new EntityColumnNameAndType("trial.id", EntityType.UUID)),
+ Map.entry("studyType", new EntityColumnNameAndType("studyName", EntityType.TEXT)),
+ Map.entry("studyName", new EntityColumnNameAndType("studyName", EntityType.TEXT))
+ );
+
@JsonProperty("commonCropNames")
private List commonCropNames = null;
@@ -54,12 +76,6 @@ public class StudySearchRequest extends SearchRequest {
@JsonProperty("seasonDbIds")
private List seasonDbIds = null;
- @JsonProperty("sortBy")
- private SortBy sortBy = null;
-
- @JsonProperty("sortOrder")
- private SortOrder sortOrder = null;
-
@JsonProperty("studyCodes")
private List studyCodes = null;
@@ -376,32 +392,6 @@ public void setSeasonDbIds(List seasonDbIds) {
this.seasonDbIds = seasonDbIds;
}
- public StudySearchRequest sortBy(SortBy sortBy) {
- this.sortBy = sortBy;
- return this;
- }
-
- public SortBy getSortBy() {
- return sortBy;
- }
-
- public void setSortBy(SortBy sortBy) {
- this.sortBy = sortBy;
- }
-
- public StudySearchRequest sortOrder(SortOrder sortOrder) {
- this.sortOrder = sortOrder;
- return this;
- }
-
- public SortOrder getSortOrder() {
- return sortOrder;
- }
-
- public void setSortOrder(SortOrder sortOrder) {
- this.sortOrder = sortOrder;
- }
-
public StudySearchRequest studyCodes(List studyCodes) {
this.studyCodes = studyCodes;
return this;
@@ -492,7 +482,6 @@ public boolean equals(java.lang.Object o) {
&& Objects.equals(this.active, studySearchRequest.active)
&& Objects.equals(this.seasonDbIds, studySearchRequest.seasonDbIds)
&& Objects.equals(this.sortBy, studySearchRequest.sortBy)
- && Objects.equals(this.sortOrder, studySearchRequest.sortOrder)
&& Objects.equals(this.studyCodes, studySearchRequest.studyCodes)
&& Objects.equals(this.studyPUIs, studySearchRequest.studyPUIs)
&& Objects.equals(this.studyTypes, studySearchRequest.studyTypes) && super.equals(o);
@@ -503,7 +492,7 @@ public int hashCode() {
return Objects.hash(commonCropNames, programDbIds, programNames, trialDbIds, trialNames, studyDbIds, studyNames,
locationDbIds, locationNames, germplasmDbIds, germplasmNames, observationVariableDbIds,
observationVariableNames, externalReferenceIds, externalReferenceSources, active, seasonDbIds, sortBy,
- sortOrder, studyCodes, studyPUIs, studyTypes, super.hashCode());
+ studyCodes, studyPUIs, studyTypes, super.hashCode());
}
@Override
@@ -529,7 +518,6 @@ public String toString() {
sb.append(" active: ").append(toIndentedString(active)).append("\n");
sb.append(" seasonDbIds: ").append(toIndentedString(seasonDbIds)).append("\n");
sb.append(" sortBy: ").append(toIndentedString(sortBy)).append("\n");
- sb.append(" sortOrder: ").append(toIndentedString(sortOrder)).append("\n");
sb.append(" studyCodes: ").append(toIndentedString(studyCodes)).append("\n");
sb.append(" studyPUIs: ").append(toIndentedString(studyPUIs)).append("\n");
sb.append(" studyTypes: ").append(toIndentedString(studyTypes)).append("\n");
@@ -583,8 +571,6 @@ public Integer getTotalParameterCount() {
count += this.seasonDbIds.size();
if (this.sortBy != null)
count += 1;
- if (this.sortOrder != null)
- count += 1;
if (this.studyCodes != null)
count += this.studyCodes.size();
if (this.studyPUIs != null)
@@ -593,4 +579,9 @@ public Integer getTotalParameterCount() {
count += this.studyTypes.size();
return count;
}
+
+ @Override
+ public Map getEntityColAndTypeBySubmittedNameMap() {
+ return ALLOWED_SORT_AND_FILTER_FIELDS;
+ }
}
diff --git a/src/main/java/io/swagger/model/core/TrialSearchRequest.java b/src/main/java/io/swagger/model/core/TrialSearchRequest.java
index 830dde51..2760e5d5 100644
--- a/src/main/java/io/swagger/model/core/TrialSearchRequest.java
+++ b/src/main/java/io/swagger/model/core/TrialSearchRequest.java
@@ -1,13 +1,32 @@
package io.swagger.model.core;
-import java.util.Objects;
+import java.util.*;
+
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.model.SearchRequest;
-import java.util.ArrayList;
-import java.util.List;
+import org.brapi.test.BrAPITestServer.model.dto.EntityColumnNameAndType;
+import org.brapi.test.BrAPITestServer.model.dto.EntityType;
+
import java.time.LocalDate;
public class TrialSearchRequest extends SearchRequest {
+
+ // Key - allowed sort or field filter name for this entity
+ // Value = entity field name and type that represents the submitted field. Used later on in query building.
+ private static final Map ALLOWED_SORT_AND_FILTER_FIELDS =
+ Map.of(
+ "trialName", new EntityColumnNameAndType("trialName", EntityType.TEXT),
+ "createdDate", new EntityColumnNameAndType("createdDate", EntityType.TEXT),
+ "createdBy", new EntityColumnNameAndType("createdBy", EntityType.TEXT),
+ "trialDbId", new EntityColumnNameAndType("id", EntityType.UUID),
+ "programDbId",new EntityColumnNameAndType("program.id", EntityType.UUID),
+ "startDate", new EntityColumnNameAndType("startDate", EntityType.TEXT),
+ "endDate", new EntityColumnNameAndType("endDate", EntityType.TEXT),
+ "active", new EntityColumnNameAndType("active", EntityType.BOOLEAN),
+ "programName", new EntityColumnNameAndType("program.name", EntityType.TEXT),
+ "locationDbId", new EntityColumnNameAndType("*studies.location.id", EntityType.UUID)
+ );
+
@JsonProperty("commonCropNames")
private List commonCropNames = null;
@@ -50,28 +69,6 @@ public class TrialSearchRequest extends SearchRequest {
@JsonProperty("trialPUIs")
private List trialPUIs = null;
- @JsonProperty("sortBy")
- private SortBy sortBy = null;
-
- @JsonProperty("sortOrder")
- private SortOrder sortOrder = null;
-
- public SortBy getSortBy() {
- return sortBy;
- }
-
- public void setSortBy(SortBy sortBy) {
- this.sortBy = sortBy;
- }
-
- public SortOrder getSortOrder() {
- return sortOrder;
- }
-
- public void setSortOrder(SortOrder sortOrder) {
- this.sortOrder = sortOrder;
- }
-
public TrialSearchRequest commonCropNames(List commonCropNames) {
this.commonCropNames = commonCropNames;
return this;
@@ -445,4 +442,9 @@ public Integer getTotalParameterCount() {
count += this.trialPUIs.size();
return count;
}
+
+ @Override
+ public Map getEntityColAndTypeBySubmittedNameMap() {
+ return ALLOWED_SORT_AND_FILTER_FIELDS;
+ }
}
diff --git a/src/main/java/io/swagger/model/sort/SortBy.java b/src/main/java/io/swagger/model/sort/SortBy.java
new file mode 100644
index 00000000..bb286fa6
--- /dev/null
+++ b/src/main/java/io/swagger/model/sort/SortBy.java
@@ -0,0 +1,30 @@
+package io.swagger.model.sort;
+
+public class SortBy {
+ private String sortedOn;
+ private SortOrder sortOrder = SortOrder.ASC;
+
+ public SortBy(String sortedOn,
+ SortOrder sortOrder) {
+ this.sortedOn = sortedOn;
+ this.sortOrder = sortOrder;
+ }
+
+ public SortBy() {}
+
+ public String getSortedOn() {
+ return sortedOn;
+ }
+
+ public void setSortedOn(String sortedOn) {
+ this.sortedOn = sortedOn;
+ }
+
+ public SortOrder getSortOrder() {
+ return sortOrder;
+ }
+
+ public void setSortOrder(SortOrder sortOrder) {
+ this.sortOrder = sortOrder;
+ }
+}
diff --git a/src/main/java/io/swagger/model/core/SortOrder.java b/src/main/java/io/swagger/model/sort/SortOrder.java
similarity index 92%
rename from src/main/java/io/swagger/model/core/SortOrder.java
rename to src/main/java/io/swagger/model/sort/SortOrder.java
index 0e5b36bd..b8a85ebf 100644
--- a/src/main/java/io/swagger/model/core/SortOrder.java
+++ b/src/main/java/io/swagger/model/sort/SortOrder.java
@@ -1,4 +1,4 @@
-package io.swagger.model.core;
+package io.swagger.model.sort;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
@@ -26,6 +26,6 @@ public static SortOrder fromValue(String text) {
return b;
}
}
- return null;
+ return ASC;
}
}
diff --git a/src/main/java/org/brapi/test/BrAPITestServer/BrapiExceptionHandler.java b/src/main/java/org/brapi/test/BrAPITestServer/BrapiExceptionHandler.java
index 7ee15a60..fa6508f0 100644
--- a/src/main/java/org/brapi/test/BrAPITestServer/BrapiExceptionHandler.java
+++ b/src/main/java/org/brapi/test/BrAPITestServer/BrapiExceptionHandler.java
@@ -1,13 +1,12 @@
package org.brapi.test.BrAPITestServer;
import java.util.ArrayList;
+import java.util.Map;
import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.*;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.MissingServletRequestParameterException;
@@ -70,4 +69,36 @@ private ResponseEntity