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

Metrics caching doesn't handle dataLocation parameter #10379

Closed
qqmyers opened this issue Mar 14, 2024 · 0 comments · Fixed by #10865
Closed

Metrics caching doesn't handle dataLocation parameter #10379

qqmyers opened this issue Mar 14, 2024 · 0 comments · Fixed by #10865

Comments

@qqmyers
Copy link
Member

qqmyers commented Mar 14, 2024

The dataset related calls in

public Response getDatasetsAllTime(@Context UriInfo uriInfo, @QueryParam("dataLocation") String dataLocation, @QueryParam("parentAlias") String parentAlias) {
return getDatasetsToMonth(uriInfo, MetricsUtil.getCurrentMonth(), dataLocation, parentAlias);
}
@GET
@Path("datasets/monthly")
@Produces("text/csv, application/json")
public Response getDatasetsTimeSeriest(@Context Request req, @Context UriInfo uriInfo, @QueryParam("dataLocation") String dataLocation, @QueryParam("parentAlias") String parentAlias) {
Dataverse d = findDataverseOrDieIfNotFound(parentAlias);
try {
errorIfUnrecongizedQueryParamPassed(uriInfo, new String[] { "dataLocation", "parentAlias" });
} catch (IllegalArgumentException ia) {
return error(BAD_REQUEST, ia.getLocalizedMessage());
}
String metricName = "datasets";
JsonArray jsonArray = MetricsUtil.stringToJsonArray(metricsSvc.returnUnexpiredCacheAllTime(metricName, null, d));
if (null == jsonArray) { // run query and save
jsonArray = metricsSvc.getDatasetsTimeSeries(uriInfo, dataLocation, d);
metricsSvc.save(new Metric(metricName, null, null, d, jsonArray.toString()));
}
MediaType requestedType = getVariant(req, MediaType.valueOf(FileUtil.MIME_TYPE_CSV), MediaType.APPLICATION_JSON_TYPE);
if ((requestedType != null) && (requestedType.equals(MediaType.APPLICATION_JSON_TYPE))) {
return ok(jsonArray);
}
return ok(FileUtil.jsonArrayOfObjectsToCSV(jsonArray, MetricsUtil.DATE, MetricsUtil.COUNT), MediaType.valueOf(FileUtil.MIME_TYPE_CSV), "datasets.timeseries.csv");
}
@GET
@Path("datasets/toMonth/{yyyymm}")
public Response getDatasetsToMonth(@Context UriInfo uriInfo, @PathParam("yyyymm") String yyyymm, @QueryParam("dataLocation") String dataLocation, @QueryParam("parentAlias") String parentAlias) {
Dataverse d = findDataverseOrDieIfNotFound(parentAlias);
try {
errorIfUnrecongizedQueryParamPassed(uriInfo, new String[] { "dataLocation", "parentAlias" });
} catch (IllegalArgumentException ia) {
return error(BAD_REQUEST, ia.getLocalizedMessage());
}
String metricName = "datasetsToMonth";
String sanitizedyyyymm = MetricsUtil.sanitizeYearMonthUserInput(yyyymm);
String validDataLocation = MetricsUtil.validateDataLocationStringType(dataLocation);
JsonObject jsonObj = MetricsUtil.stringToJsonObject(metricsSvc.returnUnexpiredCacheMonthly(metricName, sanitizedyyyymm, validDataLocation, d));
if (null == jsonObj) { // run query and save
Long count = metricsSvc.datasetsToMonth(sanitizedyyyymm, validDataLocation, d);
jsonObj = MetricsUtil.countToJson(count).build();
metricsSvc.save(new Metric(metricName, sanitizedyyyymm, validDataLocation, d, jsonObj.toString()));
}
return ok(jsonObj);
}
@GET
@Path("datasets/pastDays/{days}")
public Response getDatasetsPastDays(@Context UriInfo uriInfo, @PathParam("days") int days, @QueryParam("dataLocation") String dataLocation, @QueryParam("parentAlias") String parentAlias) {
Dataverse d = findDataverseOrDieIfNotFound(parentAlias);
try {
errorIfUnrecongizedQueryParamPassed(uriInfo, new String[] { "dataLocation", "parentAlias" });
} catch (IllegalArgumentException ia) {
return error(BAD_REQUEST, ia.getLocalizedMessage());
}
String metricName = "datasetsPastDays";
if (days < 1) {
return error(BAD_REQUEST, "Invalid parameter for number of days.");
}
String validDataLocation = MetricsUtil.validateDataLocationStringType(dataLocation);
JsonObject jsonObj = MetricsUtil.stringToJsonObject(metricsSvc.returnUnexpiredCacheDayBased(metricName, String.valueOf(days), validDataLocation, d));
if (null == jsonObj) { // run query and save
Long count = metricsSvc.datasetsPastDays(days, validDataLocation, d);
jsonObj = MetricsUtil.countToJson(count).build();
metricsSvc.save(new Metric(metricName, String.valueOf(days), validDataLocation, d, jsonObj.toString()));
}
return ok(jsonObj);
}
@GET
@Path("datasets/bySubject")
@Produces("text/csv, application/json")
public Response getDatasetsBySubject(@Context Request req, @Context UriInfo uriInfo, @QueryParam("dataLocation") String dataLocation, @QueryParam("parentAlias") String parentAlias) {
return getDatasetsBySubjectToMonth(req, uriInfo, MetricsUtil.getCurrentMonth(), dataLocation, parentAlias);
}
@GET
@Path("datasets/bySubject/toMonth/{yyyymm}")
@Produces("text/csv, application/json")
public Response getDatasetsBySubjectToMonth(@Context Request req, @Context UriInfo uriInfo, @PathParam("yyyymm") String yyyymm, @QueryParam("dataLocation") String dataLocation, @QueryParam("parentAlias") String parentAlias) {
Dataverse d = findDataverseOrDieIfNotFound(parentAlias);
try {
errorIfUnrecongizedQueryParamPassed(uriInfo, new String[] { "dataLocation", "parentAlias" });
} catch (IllegalArgumentException ia) {
return error(BAD_REQUEST, ia.getLocalizedMessage());
}
String metricName = "datasetsBySubjectToMonth";
String sanitizedyyyymm = MetricsUtil.sanitizeYearMonthUserInput(yyyymm);
String validDataLocation = MetricsUtil.validateDataLocationStringType(dataLocation);
JsonArray jsonArray = MetricsUtil.stringToJsonArray(metricsSvc.returnUnexpiredCacheMonthly(metricName, sanitizedyyyymm, validDataLocation, d));
if (null == jsonArray) { // run query and save
jsonArray = MetricsUtil.datasetsBySubjectToJson(metricsSvc.datasetsBySubjectToMonth(sanitizedyyyymm, validDataLocation, d)).build();
metricsSvc.save(new Metric(metricName, sanitizedyyyymm, validDataLocation, d, jsonArray.toString()));
}
MediaType requestedType = getVariant(req, MediaType.valueOf(FileUtil.MIME_TYPE_CSV), MediaType.APPLICATION_JSON_TYPE);
if ((requestedType != null) && (requestedType.equals(MediaType.APPLICATION_JSON_TYPE))) {
return ok(jsonArray);
}
return ok(FileUtil.jsonArrayOfObjectsToCSV(jsonArray, MetricsUtil.SUBJECT, MetricsUtil.COUNT), MediaType.valueOf(FileUtil.MIME_TYPE_CSV), "datasets.bySubject.csv");
}
support a dataLocation parameter to get info for local, remote (harvested), or all datasets. However, the caching doesn't handle the parameter. Thus, whichever call is made first is cached and served as the response regardless of whether the parameter is different the next time. A partial workaround is to clear the cache before making a call.

A fix would involve adding the param value (after sanitizing) to the metricName being cached so that values for all three options are cached separately.

  • When does this issue occur?
    Metrics API

Which version of Dataverse are you using?
develop/6.1+

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done 🧹
Development

Successfully merging a pull request may close this issue.

3 participants