Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow header accept field as a source of format type #495

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
Expand Down Expand Up @@ -101,6 +102,7 @@ public abstract class ApiRequest {
* Parses the API request URL and generates the API request object.
*
* @param format response data format JSON or CSV. Default is JSON.
* @param headerFormat The accept field from http request header
* @param asyncAfter How long the user is willing to wait for a synchronous request in milliseconds, if null
* defaults to the system config {@code default_asyncAfter}
* @param perPage number of rows to display per page of results. If present in the original request, must be a
Expand All @@ -113,13 +115,14 @@ public abstract class ApiRequest {
*/
public ApiRequest(
String format,
String headerFormat,
String asyncAfter,
@NotNull String perPage,
@NotNull String page,
UriInfo uriInfo
) throws BadApiRequestException {
this.uriInfo = uriInfo;
this.format = generateAcceptFormat(format);
this.format = generateAcceptFormat(format, headerFormat);
this.paginationParameters = generatePaginationParameters(perPage, page);
this.builder = Response.status(Response.Status.OK);
this.asyncAfter = generateAsyncAfter(
Expand All @@ -134,6 +137,7 @@ public ApiRequest(
* Parses the API request URL and generates the API request object. Defaults asyncAfter to never.
*
* @param format response data format JSON or CSV. Default is JSON.
* @param headerFormat The accept field from http request header
* @param perPage number of rows to display per page of results. If present in the original request, must be a
* positive integer. If not present, must be the empty string.
* @param page desired page of results. If present in the original request, must be a positive integer. If not
Expand All @@ -144,11 +148,12 @@ public ApiRequest(
*/
public ApiRequest(
String format,
final String headerFormat,
@NotNull String perPage,
@NotNull String page,
UriInfo uriInfo
) throws BadApiRequestException {
this(format, SYNCHRONOUS_REQUEST_FLAG, perPage, page, uriInfo);
this(format, headerFormat , SYNCHRONOUS_REQUEST_FLAG, perPage, page, uriInfo);
}

/**
Expand Down Expand Up @@ -588,15 +593,37 @@ protected Map<Dimension, Set<ApiFilter>> generateFilters(
* Generates the format in which the response data is expected.
*
* @param format Expects a URL format query String.
* @param headerFormatString The accept field from http request header
*
* @return Response format type (CSV or JSON).
* @throws BadApiRequestException if the requested format is not found.
*/
protected ResponseFormatType generateAcceptFormat(String format) throws BadApiRequestException {
protected ResponseFormatType generateAcceptFormat(
String format,
final String headerFormatString
) throws BadApiRequestException {
try {
return format == null ?
ResponseFormatType.JSON :
ResponseFormatType.valueOf(format.toUpperCase(Locale.ENGLISH));
String headerFormat = null;
if (headerFormatString != null) {
Map<String, String> acceptFormats = new HashMap<>();
acceptFormats.put("application/json", "json");
acceptFormats.put("application/vnd.api+json", "jsonapi");
acceptFormats.put("text/csv", "csv");
for (String acceptFormat : acceptFormats.keySet()) {
if (headerFormatString.contains(acceptFormat)) {
headerFormat = acceptFormats.get(acceptFormat);
break;
}
}
}

if (format != null) {
return ResponseFormatType.valueOf(format.toUpperCase(Locale.ENGLISH));
} else if (headerFormat != null) {
return ResponseFormatType.valueOf(headerFormat.toUpperCase(Locale.ENGLISH));
} else {
return ResponseFormatType.JSON;
}
} catch (IllegalArgumentException e) {
LOG.error(ACCEPT_FORMAT_INVALID.logFormat(format), e);
throw new BadApiRequestException(ACCEPT_FORMAT_INVALID.format(format));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ public class DataApiRequest extends ApiRequest {
* @param count count of number of records to be returned in the response
* @param topN number of first records per time bucket to be returned in the response
* @param format response data format JSON or CSV. Default is JSON.
* @param headerFormat The accept field from http request header
* @param timeZoneId a joda time zone id
* @param asyncAfter How long the user is willing to wait for a synchronous request in milliseconds
* @param perPage number of rows to display per page of results. If present in the original request,
Expand Down Expand Up @@ -162,14 +163,15 @@ public DataApiRequest(
String count,
String topN,
String format,
String headerFormat,
String timeZoneId,
String asyncAfter,
@NotNull String perPage,
@NotNull String page,
UriInfo uriInfo,
BardConfigResources bardConfigResources
) throws BadApiRequestException {
super(format, asyncAfter, perPage, page, uriInfo);
super(format, headerFormat, asyncAfter, perPage, page, uriInfo);

GranularityParser granularityParser = bardConfigResources.getGranularityParser();
DimensionDictionary dimensionDictionary = bardConfigResources.getDimensionDictionary();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class DimensionsApiRequest extends ApiRequest {
* ((field name and operation):((multiple values bounded by [])or(single value))))(followed by , or end of string)
* }</pre>
* @param format response data format JSON or CSV. Default is JSON.
* @param headerFormat The accept field from http request header
* @param perPage number of rows to display per page of results. If present in the original request,
* must be a positive integer. If not present, must be the empty string.
* @param page desired page of results. If present in the original request, must be a positive
Expand All @@ -64,12 +65,13 @@ public DimensionsApiRequest(
String dimension,
String filters,
String format,
String headerFormat,
@NotNull String perPage,
@NotNull String page,
DimensionDictionary dimensionDictionary,
UriInfo uriInfo
) throws BadApiRequestException {
super(format, perPage, page, uriInfo);
super(format, headerFormat, perPage, page, uriInfo);

// Zero or more grouping dimensions may be specified
this.dimensions = generateDimensions(dimension, dimensionDictionary);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class JobsApiRequest extends ApiRequest {
* Parses the API request URL and generates the Api Request object.
*
* @param format response data format JSON or CSV. Default is JSON.
* @param headerFormat The accept field from http request header
* @param asyncAfter How long the user is willing to wait for a synchronous request in milliseconds
* @param perPage number of rows to display per page of results. If present in the original request,
* must be a positive integer. If not present, must be the empty string.
Expand All @@ -51,6 +52,7 @@ public class JobsApiRequest extends ApiRequest {
*/
public JobsApiRequest(
String format,
String headerFormat,
String asyncAfter,
@NotNull String perPage,
@NotNull String page,
Expand All @@ -59,7 +61,7 @@ public JobsApiRequest(
JobPayloadBuilder jobPayloadBuilder,
ApiJobStore apiJobStore
) {
super(format, asyncAfter, perPage, page, uriInfo);
super(format, headerFormat, asyncAfter, perPage, page, uriInfo);
this.jobPayloadBuilder = jobPayloadBuilder;
this.apiJobStore = apiJobStore;
this.filters = filters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class MetricsApiRequest extends ApiRequest {
* ((field name and operation):((multiple values bounded by [])or(single value))))(followed by , or end of string)
* }</pre>
* @param format response data format JSON or CSV. Default is JSON.
* @param headerFormat The accept field from http request header
* @param perPage number of rows to display per page of results. If present in the original request,
* must be a positive integer. If not present, must be the empty string.
* @param page desired page of results. If present in the original request, must be a positive
Expand All @@ -51,12 +52,13 @@ public class MetricsApiRequest extends ApiRequest {
public MetricsApiRequest(
String metricName,
String format,
final String headerFormat,
@NotNull String perPage,
@NotNull String page,
MetricDictionary metricDictionary,
UriInfo uriInfo
) throws BadApiRequestException {
super(format, perPage, page, uriInfo);
super(format, headerFormat, perPage, page, uriInfo);

this.metrics = generateMetrics(metricName, metricDictionary);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class SlicesApiRequest extends ApiRequest {
* ((field name and operation):((multiple values bounded by [])or(single value))))(followed by , or end of string)
* }</pre>
* @param format response data format JSON or CSV. Default is JSON.
* @param headerFormat The accept field from http request header
* @param perPage number of rows to display per page of results. If present in the original request,
* must be a positive integer. If not present, must be the empty string.
* @param page desired page of results. If present in the original request, must be a positive
Expand All @@ -66,13 +67,14 @@ public class SlicesApiRequest extends ApiRequest {
public SlicesApiRequest(
String sliceName,
String format,
String headerFormat,
@NotNull String perPage,
@NotNull String page,
PhysicalTableDictionary tableDictionary,
DataSourceMetadataService dataSourceMetadataService,
UriInfo uriInfo
) throws BadApiRequestException {
super(format, perPage, page, uriInfo);
super(format, headerFormat, perPage, page, uriInfo);
this.slices = generateSlices(tableDictionary, uriInfo);

this.slice = sliceName != null ? generateSlice(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class TablesApiRequest extends ApiRequest {
* ((field name and operation):((multiple values bounded by [])or(single value))))(followed by , or end of string)
* }</pre>
* @param format response data format JSON or CSV. Default is JSON.
* @param headerFormat The accept field from http request header
* @param perPage number of rows to display per page of results. If present in the original request,
* must be a positive integer. If not present, must be the empty string.
* @param page desired page of results. If present in the original request, must be a positive
Expand All @@ -78,12 +79,13 @@ public TablesApiRequest(
String tableName,
String granularity,
String format,
String headerFormat,
@NotNull String perPage,
@NotNull String page,
UriInfo uriInfo,
BardConfigResources bardConfigResources
) throws BadApiRequestException {
super(format, perPage, page, uriInfo);
super(format, headerFormat, perPage, page, uriInfo);

this.tables = generateTables(tableName, bardConfigResources.getLogicalTableDictionary());

Expand Down Expand Up @@ -121,6 +123,7 @@ public TablesApiRequest(
* @param tableName Logical table corresponding to the table name specified in the URL
* @param granularity Requested time granularity
* @param format Response data format JSON or CSV. Default is JSON.
* @param headerFormat The accept field from http request header
* @param perPage Number of rows to display per page of results. It must represent a positive integer or an empty
* string if it's not specified
* @param page Desired page of results. It must represent a positive integer or an empty
Expand All @@ -143,6 +146,7 @@ public TablesApiRequest(
String tableName,
String granularity,
String format,
final String headerFormat,
@NotNull String perPage,
@NotNull String page,
UriInfo uriInfo,
Expand All @@ -153,7 +157,7 @@ public TablesApiRequest(
String filters,
String timeZoneId
) throws BadApiRequestException {
super(format, perPage, page, uriInfo);
super(format, headerFormat, perPage, page, uriInfo);

LogicalTableDictionary logicalTableDictionary = bardConfigResources.getLogicalTableDictionary();
this.tables = generateTables(tableName, logicalTableDictionary);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ public void getData(
count,
topN,
format,
containerRequestContext.getHeaderString("Accept"),
timeZone,
asyncAfter,
perPage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public Response getAllDimensions(
null,
null,
format,
containerRequestContext.getHeaderString("Accept"),
perPage,
page,
dimensionDictionary,
Expand Down Expand Up @@ -184,6 +185,7 @@ public Response getDimension(
dimensionName,
null,
null,
containerRequestContext.getHeaderString("Accept"),
"",
"",
dimensionDictionary,
Expand Down Expand Up @@ -271,6 +273,7 @@ public Response getDimensionRows(
dimensionName,
filterQuery,
format,
containerRequestContext.getHeaderString("Accept"),
perPage,
page,
dimensionDictionary,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
Expand Down Expand Up @@ -66,12 +67,19 @@ class FeatureFlagApiRequest extends ApiRequest {
* Constructor.
*
* @param format Format of the request
* @param headerFormat The accept field from http request header
* @param perPage How many items to show per page
* @param page Which page to show
* @param uriInfo URL information about the request
*/
FeatureFlagApiRequest(String format, String perPage, String page, UriInfo uriInfo) {
super(format, perPage, page, uriInfo);
FeatureFlagApiRequest(
String format,
final String headerFormat,
String perPage,
String page,
UriInfo uriInfo
) {
super(format, headerFormat, perPage, page, uriInfo);
}
}

Expand Down Expand Up @@ -101,6 +109,7 @@ class FeatureFlagEntry {
* @param page the page to start from
* @param format the format to use
* @param uriInfo the injected UriInfo
* @param containerRequestContext Context from the http request object
*
* @return Response Format:
* <pre><code>
Expand All @@ -121,13 +130,20 @@ public Response getFeatureFlagStatusAll(
@DefaultValue("") @NotNull @QueryParam("perPage") String perPage,
@DefaultValue("") @NotNull @QueryParam("page") String page,
@QueryParam("format") String format,
@Context UriInfo uriInfo
@Context UriInfo uriInfo,
@Context final ContainerRequestContext containerRequestContext
) {
try {
RequestLog.startTiming(this);
RequestLog.record(new FeatureFlagRequest("all"));

FeatureFlagApiRequest apiRequest = new FeatureFlagApiRequest(format, perPage, page, uriInfo);
FeatureFlagApiRequest apiRequest = new FeatureFlagApiRequest(
format,
containerRequestContext.getHeaderString("Accept"),
perPage,
page,
uriInfo
);

List<FeatureFlagEntry> status = flags.getValues().stream()
.map(flag -> new FeatureFlagEntry(flag.getName(), flag.isOn()))
Expand Down Expand Up @@ -158,6 +174,7 @@ public Response getFeatureFlagStatusAll(
* @param flagName The feature flag
* @param format The format to return results in
* @param uriInfo The injected UriInfo
* @param containerRequestContext Context from the http request object
*
* @return Response Format:
* <pre><code>
Expand All @@ -176,13 +193,20 @@ public Response getFeatureFlagStatusAll(
public Response getFeatureFlagStatus(
@PathParam("flagName") String flagName,
@QueryParam("format") String format,
@Context UriInfo uriInfo
@Context UriInfo uriInfo,
@Context final ContainerRequestContext containerRequestContext
) {
try {
RequestLog.startTiming(this);
RequestLog.record(new FeatureFlagRequest(flagName));

FeatureFlagApiRequest apiRequest = new FeatureFlagApiRequest(format, "", "", uriInfo);
FeatureFlagApiRequest apiRequest = new FeatureFlagApiRequest(
format,
containerRequestContext.getHeaderString("Accept"),
"",
"",
uriInfo
);

FeatureFlag flag = flags.forName(flagName);
FeatureFlagEntry status = new FeatureFlagEntry(flag.getName(), flag.isOn());
Expand Down
Loading