From bf818ad0063e39fae0de37d286852675f268d972 Mon Sep 17 00:00:00 2001 From: gcolon021 Date: Fri, 14 Jul 2023 11:48:39 -0400 Subject: [PATCH] Handle Open Access Binned Response --- .../AggregateDataSharingResourceRS.java | 16 +++++++++++-- .../visualization/model/ContinuousData.java | 9 ++++++++ .../service/DataProcessingService.java | 23 +++++++++++++++---- .../service/VisualizationService.java | 15 ++++++++---- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/pic-sure-resources/pic-sure-aggregate-data-sharing-resource/src/main/java/edu/harvard/hms/dbmi/avillach/AggregateDataSharingResourceRS.java b/pic-sure-resources/pic-sure-aggregate-data-sharing-resource/src/main/java/edu/harvard/hms/dbmi/avillach/AggregateDataSharingResourceRS.java index 7daeb141..7ef945c0 100644 --- a/pic-sure-resources/pic-sure-aggregate-data-sharing-resource/src/main/java/edu/harvard/hms/dbmi/avillach/AggregateDataSharingResourceRS.java +++ b/pic-sure-resources/pic-sure-aggregate-data-sharing-resource/src/main/java/edu/harvard/hms/dbmi/avillach/AggregateDataSharingResourceRS.java @@ -530,12 +530,11 @@ protected String processContinuousCrossCounts(String continuousCrossCountRespons // call the binning endpoint HttpResponse httpResponse = getHttpResponse(queryRequest, properties.getVisualizationResourceId(), "/format/continuous"); - HttpEntity entity = httpResponse.getEntity(); String responseString = EntityUtils.toString(entity, "UTF-8"); logger.info("Response from binning endpoint: {}", responseString); - Map> binnedContinuousCrossCounts = objectMapper.convertValue(responseString, new TypeReference<>() {}); + Map> binnedContinuousCrossCounts = objectMapper.convertValue(responseString, new TypeReference<>() {}); Map crossCounts = objectMapper.readValue(crossCountEntityString, new TypeReference<>(){}); int generatedVariance = this.generateVarianceWithCrossCounts(crossCounts); @@ -547,6 +546,19 @@ protected String processContinuousCrossCounts(String continuousCrossCountRespons return objectMapper.writeValueAsString(binnedContinuousCrossCounts); } + // TODO: We can refactor this code as it is duplicated in the categorical cross count obfuscation + binnedContinuousCrossCounts.forEach((key, value) -> { + value.forEach((innerKey, innerValue) -> { + Optional aggregateCount = aggregateCountHelper(innerValue); + if (aggregateCount.isPresent()) { + value.put(innerKey, aggregateCount.get()); + } else { + value.put(innerKey, randomize(innerValue.toString(), generatedVariance)); + } + }); + }); + + return objectMapper.writeValueAsString(binnedContinuousCrossCounts); } diff --git a/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/model/ContinuousData.java b/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/model/ContinuousData.java index ea875532..2b8515ba 100644 --- a/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/model/ContinuousData.java +++ b/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/model/ContinuousData.java @@ -23,4 +23,13 @@ public ContinuousData(String title, Map continuousMap, String x this.setYAxisName(yAxisLabel); this.continuousMap = continuousMap; } + + public ContinuousData(String title, Map continuousMap, String xAxisLabel, String yAxisLabel, boolean isObfuscated) { + super(); + this.setTitle(title); + this.setXAxisName(xAxisLabel); + this.setYAxisName(yAxisLabel); + this.setObfuscated(isObfuscated); + this.continuousMap = continuousMap; + } } diff --git a/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/service/DataProcessingService.java b/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/service/DataProcessingService.java index 7a657b03..f19261ba 100644 --- a/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/service/DataProcessingService.java +++ b/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/service/DataProcessingService.java @@ -85,27 +85,42 @@ private static boolean skipKey(Map.Entry> entry) { return false; } + public List getContinuousData(Map> crossCountsMap) { + return handleGetContinuousData(crossCountsMap, false); + } + + public List getContinuousData(Map> crossCountsMap, boolean isObfuscated) { + return handleGetContinuousData(crossCountsMap, isObfuscated); + } /** * For each continuous cross count we create a histogram of the values. * * @return List - result of query */ - public List getContinuousData(Map> crossCountsMap) { + private List handleGetContinuousData(Map> crossCountsMap, boolean isObfuscated) { List continuousDataList = new ArrayList<>(); + // If it's not obfuscated we need to bin the data for (Map.Entry> entry : crossCountsMap.entrySet()) { String title = getChartTitle(entry.getKey()); + LinkedHashMap binnedData; + if (!isObfuscated) { + binnedData = new LinkedHashMap<>(bucketData(entry.getValue())); + } else { + // If it is obfuscated the data is already binned + binnedData = new LinkedHashMap<>(entry.getValue()); + } + continuousDataList.add(new ContinuousData( title, - new LinkedHashMap<>( - bucketData(entry.getValue()) - ), + binnedData, createXAxisLabel(title), "Number of Participants" )); } + logger.debug("Finished Categorical Data with " + continuousDataList.size() + " results"); return continuousDataList; } diff --git a/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/service/VisualizationService.java b/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/service/VisualizationService.java index be037871..e9d9c520 100644 --- a/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/service/VisualizationService.java +++ b/pic-sure-resources/pic-sure-visualization-resource/src/main/java/edu/harvard/hms/dbmi/avillach/resource/visualization/service/VisualizationService.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import edu.harvard.dbmi.avillach.domain.QueryRequest; import edu.harvard.hms.dbmi.avillach.resource.visualization.ApplicationProperties; -import edu.harvard.hms.dbmi.avillach.resource.visualization.model.ContinuousData; import edu.harvard.hms.dbmi.avillach.resource.visualization.model.ProcessedCrossCountsResponse; import edu.harvard.hms.dbmi.avillach.resource.visualization.model.domain.Query; import edu.harvard.hms.dbmi.avillach.resource.visualization.model.domain.ResultType; @@ -15,7 +14,6 @@ import javax.inject.Inject; import javax.ws.rs.core.Response; import java.util.HashMap; -import java.util.List; import java.util.Map; @Stateless @@ -73,9 +71,10 @@ public Response handleQuerySync(QueryRequest query, String requestSource) { return getProcessedCrossCountResponse(categroyCrossCountsMap, continuousCrossCountsMap); } else { Map> openCategoricalCrossCounts = getOpenCrossCounts(query, queryJson, ResultType.CATEGORICAL_CROSS_COUNT); + Map> openContinuousCrossCounts = getOpenCrossCounts(query, queryJson, ResultType.CONTINUOUS_CROSS_COUNT); logger.info("openCategoricalCrossCounts: " + openCategoricalCrossCounts); - return getOpenProcessedCrossCountResponse(openCategoricalCrossCounts); + return getOpenProcessedCrossCountResponse(openCategoricalCrossCounts, openContinuousCrossCounts); } } @@ -86,14 +85,18 @@ private Response getProcessedCrossCountResponse(Map return Response.ok(response).build(); } - private Response getOpenProcessedCrossCountResponse(Map> categroyCrossCountsMap) { + private Response getOpenProcessedCrossCountResponse(Map> categroyCrossCountsMap, + Map> continuousCrossCountsMap) { if ((categroyCrossCountsMap == null || categroyCrossCountsMap.isEmpty())) return Response.ok().build(); boolean isCategoricalObfuscated = isObfuscated(categroyCrossCountsMap); Map> cleanedCategoricalData = cleanCategoricalData(categroyCrossCountsMap); - ProcessedCrossCountsResponse response = buildOpenProcessedCrossCountsResponse(cleanedCategoricalData, isCategoricalObfuscated); + boolean isContinuousObfuscated = isObfuscated(continuousCrossCountsMap); + Map> cleanedContinuousData = cleanCategoricalData(continuousCrossCountsMap); + + ProcessedCrossCountsResponse response = buildOpenProcessedCrossCountsResponse(cleanedCategoricalData, cleanedContinuousData, (isCategoricalObfuscated || isContinuousObfuscated)); return Response.ok(response).build(); } @@ -157,10 +160,12 @@ private boolean isObfuscated(Map> categroyCrossCount } private ProcessedCrossCountsResponse buildOpenProcessedCrossCountsResponse(Map> categroyCrossCountsMap, + Map> continuousCrossCountsMap, boolean isObfuscated) { ProcessedCrossCountsResponse response = new ProcessedCrossCountsResponse(); response.getCategoricalData().addAll(dataProcessingServices.getCategoricalData(categroyCrossCountsMap, isObfuscated)); + response.getContinuousData().addAll(dataProcessingServices.getContinuousData(continuousCrossCountsMap, isObfuscated)); return response; }