Skip to content
This repository has been archived by the owner on Nov 11, 2024. It is now read-only.

Commit

Permalink
Add cursor-based pagination to /ras/runs (#623)
Browse files Browse the repository at this point in the history
* Refactor sorting logic in /ras/runs, pass max runs limit when getting runs

Signed-off-by: Eamonn Mansour <[email protected]>

* Add flag to use cursor-based pagination in /ras/runs

Signed-off-by: Eamonn Mansour <[email protected]>

* Use primary sort for queries to couchdb, update OpenAPI spec

Signed-off-by: Eamonn Mansour <[email protected]>

* Add missing javadoc, minor refactoring

Signed-off-by: Eamonn Mansour <[email protected]>

* Clean up

Signed-off-by: Eamonn Mansour <[email protected]>

* Empty commit to kick off build

Signed-off-by: Eamonn Mansour <[email protected]>

---------

Signed-off-by: Eamonn Mansour <[email protected]>
  • Loading branch information
eamansour authored Aug 21, 2024
1 parent 9e0fc4a commit 0070969
Show file tree
Hide file tree
Showing 13 changed files with 819 additions and 512 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,28 @@ public int getSingleInt(String queryParameterName, int defaultValue) throws Inte
return returnedValue;
}

/**
* @param queryParameterName the query parameter to retrieve the value of
* @param defaultValue Returned if there are no occurrances of the query parameter.
* @return the value of the given query parameter as a boolean
* @throws InternalServletException when there are multiple values of this query parameter
*/
public boolean getSingleBoolean(String queryParameterName, boolean defaultValue) throws InternalServletException {
boolean returnedValue = defaultValue;
String paramValueStr = getSingleString(queryParameterName, Boolean.toString(defaultValue));

if (paramValueStr != null) {
String trimmedParamValue = paramValueStr.trim();
if (!trimmedParamValue.equalsIgnoreCase("true") && !trimmedParamValue.equalsIgnoreCase("false")) {
ServletError error = new ServletError(GAL5090_INVALID_QUERY_PARAM_NOT_BOOLEAN, queryParameterName, paramValueStr);
throw new InternalServletException(error, HttpServletResponse.SC_BAD_REQUEST);
} else {
returnedValue = Boolean.parseBoolean(trimmedParamValue);
}
}
return returnedValue;
}

/**
* @param queryParameterName
* @param defaultValue Returned if there are no occurrances of the query parameter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public enum ServletErrorMessage {
GAL5004_ERROR_RETRIEVING_PAGE (5004,"E: Error retrieving page. Report the problem to your Galasa Ecosystem owner."),
GAL5005_INVALID_QUERY_PARAM_NOT_INTEGER (5005,"E: Error parsing the query parameter ''{0}'' in the request URL. Invalid value ''{1}''. Expecting an integer."),
GAL5006_INVALID_QUERY_PARAM_DUPLICATES (5006,"E: Error parsing the query parameters. Duplicate instances of query parameter ''{0}'' found in the request URL. Expecting only one."),
GAL5090_INVALID_QUERY_PARAM_NOT_BOOLEAN (5090,"E: Error parsing the query parameter ''{0}'' in the request URL. Invalid value ''{1}''. Expecting a boolean."),

GAL5010_FROM_DATE_IS_REQUIRED (5010,"E: Error parsing the query parameters. 'from' time is a mandatory field if no 'runname' is supplied."),
GAL5011_SORT_VALUE_NOT_RECOGNIZED (5011,"E: Error parsing the query parameters. 'sort' value ''{0}'' not recognised. Expected query parameter in the format 'sort={fieldName}:{order}' where order is 'asc' for ascending or 'desc' for descending."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1095,10 +1095,6 @@ paths:
Use '{FIELD-NAME}:asc' to sort in ascending order.
Use '{FIELD-NAME}:desc' to sort in descending order.
You can use multiple instances of this query parameter, or specify
multiple sort orders using one query parameter, and a comma-separated
list of sort orders.
required: true
schema:
type: string
Expand Down Expand Up @@ -1199,6 +1195,26 @@ paths:
schema:
type: string
example: U1578

# Temporary feature flag to enable cursor-based pagination
- name: includeCursor
in: query
description: |
A boolean flag to enable cursor-based pagination and return the next page cursor
in the response. If omitted, it will default to false.
schema:
type: string
example: 'true'
- name: cursor
in: query
description: |
The cursor representing the page of runs to be retrieved. This is a unique value that is specific
to a query and is included in responses, allowing you to navigate through pages of runs.
If omitted, the first page of runs for the given query will be returned and the response
will display the cursor for the next page of runs.
schema:
type: string
example: g2wAAAACaAJkAA5zdGFydG
responses:
'200':
description: Array of Run Objects
Expand Down Expand Up @@ -2035,6 +2051,8 @@ components:
type: integer
amountOfRuns:
type: integer
nextCursor:
type: string
runs:
type: array
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import dev.galasa.framework.api.common.InternalServletException;
import dev.galasa.framework.api.common.QueryParameters;
import dev.galasa.framework.api.common.ServletError;
import dev.galasa.framework.spi.ras.RasSortField;

import static dev.galasa.framework.api.common.ServletErrorMessage.*;


Expand Down Expand Up @@ -96,18 +98,40 @@ public String getRunName() throws InternalServletException {
return generalQueryParams.getSingleString("runname", null);
}

public String getSortValue() throws InternalServletException {
public String getPageCursor() throws InternalServletException {
return generalQueryParams.getSingleString("cursor", null);
}

public boolean getIncludeCursor() throws InternalServletException {
return generalQueryParams.getSingleBoolean("includeCursor", false);
}

public RasSortField getSortValue() throws InternalServletException {
return getSortValue(null);
}

public String getSortValue(String defaultValue) throws InternalServletException {
return generalQueryParams.getSingleString("sort",defaultValue);
public RasSortField getSortValue(String defaultSortValue) throws InternalServletException {
String sortValue = generalQueryParams.getSingleString("sort", defaultSortValue);
RasSortField rasSortValue = null;
if (sortValue != null) {
rasSortValue = getValidatedSortValue(sortValue);
}
return rasSortValue;
}
public List<String> getRunIds( ) {

public RasSortField getSortValueByName(String sortFieldName) throws InternalServletException {
RasSortField sortValue = getSortValue();
if (sortValue != null && !sortValue.getFieldName().equals(sortFieldName)) {
sortValue = null;
}
return sortValue;
}

public List<String> getRunIds() {
return generalQueryParams.getMultipleString("runId", new ArrayList<String>());
}

public boolean checkFromTimeOrRunNamePresent() throws InternalServletException {
public boolean isFromTimeOrRunNamePresent() throws InternalServletException {
return generalQueryParams.checkAtLeastOneQueryParameterPresent("from", "runname");
}

Expand Down Expand Up @@ -145,45 +169,27 @@ public QueryParameters getGeneralQueryParameters() {
return this.generalQueryParams;
}

public boolean isAscending(String fieldToSortBy) throws InternalServletException{
String sortValue = generalQueryParams.getSingleString("sort", null);
boolean isAscending = false;
if (sortValue != null){
try{
if(sortIsValidFormat(sortValue)) {
isAscending = getSortDirection(fieldToSortBy,sortValue);
}else{
throw new Exception();
}
}catch (Exception e) {
ServletError error = new ServletError(GAL5011_SORT_VALUE_NOT_RECOGNIZED,sortValue);
throw new InternalServletException(error, HttpServletResponse.SC_BAD_REQUEST, e);
}
public boolean isAscending(String sortFieldName) throws InternalServletException {
RasSortField sortField = getSortValueByName(sortFieldName);
boolean isAscending = false;
if (sortField != null) {
isAscending = sortDirectionMap.get(sortField.getSortDirection());
}
return isAscending;
return isAscending;
}

// note asc = true, desc = false
private boolean getSortDirection(String fieldToSortBy, String sortValue) {
boolean isAscending = false;
String[] split = sortValue.split(":");
isAscending = sortDirectionMap.get(split[1].toLowerCase());
return isAscending;
}
public boolean isAscending(RasSortField sortField) throws InternalServletException {
return sortDirectionMap.get(sortField.getSortDirection());
}

private RasSortField getValidatedSortValue(String sortValue) throws InternalServletException {
String[] sortValueParts = sortValue.split(":");

// check if sort value has right formatting
private boolean sortIsValidFormat(String sortValue){
boolean isValid = false;
if(sortValue.contains(":")) {
if(sortValue.split(":").length == 2){
isValid = true;
}
if (sortValueParts.length != 2 || !sortDirectionMap.containsKey(sortValueParts[1].toLowerCase())) {
ServletError error = new ServletError(GAL5011_SORT_VALUE_NOT_RECOGNIZED, sortValue);
throw new InternalServletException(error, HttpServletResponse.SC_BAD_REQUEST);
}
return isValid;
return new RasSortField(sortValueParts[0].toLowerCase(), sortValueParts[1].toLowerCase());
}

public boolean validateSortValue() throws InternalServletException{
return isAscending(null);
}

}
Loading

0 comments on commit 0070969

Please sign in to comment.