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

LNK-2037 #703

Merged
merged 6 commits into from
Feb 27, 2024
Merged
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 @@ -2,6 +2,7 @@

import com.lantanagroup.link.Constants;
import com.lantanagroup.link.db.SharedService;
import com.lantanagroup.link.db.TenantService;
import com.lantanagroup.link.db.model.MetricData;
import com.lantanagroup.link.db.model.Metrics;
import com.lantanagroup.link.model.*;
Expand All @@ -14,6 +15,11 @@
import org.springframework.web.server.ResponseStatusException;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -401,4 +407,146 @@ private List<MetricData> getPeriodMetricData(String category, String task, List<
.collect(Collectors.toList());
}

@GetMapping("/size/PatientMeasureReport/{tenantId}")
public DataSizeSummary getPatientMeasureReportSizeSummary(
@PathVariable String tenantId,
@RequestParam(name = "patientId", required = false) String patientId,
@RequestParam(name = "reportId", required = false) String reportId,
@RequestParam(name = "measureId", required = false) String measureId,
@RequestParam(name = "patientMeasureReportId", required = false) String patientMeasureReportId) {

var tenantService = TenantService.create(sharedService, tenantId);

var dataSizes = tenantService.getPatientMeasureReportSize(patientId, reportId, measureId, patientMeasureReportId);

var summary = new DataSizeSummary();
double sum = 0.0;
var dataCountMap = summary.getCountDataType();
var dataAverageMap = summary.getAverageDataSize();

var reportKey = "ReportId";
var measureKey = "MeasureId";
var pidKey = "PatientId";

dataCountMap.put(reportKey, new HashMap<>());
dataCountMap.put(measureKey, new HashMap<>());
dataCountMap.put(pidKey, new HashMap<>());

dataAverageMap.put(reportKey, new HashMap<>());
dataAverageMap.put(measureKey, new HashMap<>());
dataAverageMap.put(pidKey, new HashMap<>());

double min = 0, max = 0;
for(var r : dataSizes)
{
var mId = r.getMeasureId();
var pId = r.getPatientId();
var rId = r.getReportId();

var sizeKb = r.getSizeKb();
sum += sizeKb;

if(min > sizeKb || min == 0)
min = sizeKb;

if(max < sizeKb)
max = sizeKb;

dataCountMap.get(reportKey).merge(rId, 1, (count, value) -> count + value);
dataCountMap.get(measureKey).merge(mId, 1, (count, value) -> count + value);
dataCountMap.get(pidKey).merge(pId, 1, (count, value) -> count + value);

dataAverageMap.get(reportKey).merge(rId, r.getSizeKb(), (size, value) -> size + value);
dataAverageMap.get(measureKey).merge(mId, r.getSizeKb(), (size, value) -> size + value);
dataAverageMap.get(pidKey).merge(pId, r.getSizeKb(), (size, value) -> size + value);
}

summary.setTotalSize(sum);
summary.setData(Collections.singletonList(dataSizes));
summary.setCount(dataSizes.size());
summary.setAverageSize(sum/dataSizes.size());
summary.setMinSize(min);
summary.setMaxSize(max);

dataAverageMap.get(reportKey).replaceAll((key, value) -> value/dataCountMap.get(reportKey).get(key));
dataAverageMap.get(measureKey).replaceAll((key, value) -> value/dataCountMap.get(measureKey).get(key));
dataAverageMap.get(pidKey).replaceAll((key, value) -> value/dataCountMap.get(pidKey).get(key));

return summary;
}

@GetMapping("/size/PatientData/{tenantId}")
public DataSizeSummary getPatientDataSizeSummary(
@PathVariable String tenantId,
@RequestParam(name = "patientId", required = false) String patientId,
@RequestParam(name = "resourceType", required = false) String resourceType,
@RequestParam(name = "startDate", required = false) String startDate,
@RequestParam(name = "endDate", required = false) String endDate
) {

var tenantService = TenantService.create(sharedService, tenantId);

LocalDateTime zdtStart = null, zdtEnd = null;
if(startDate != null && endDate != null)
{
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneOffset.UTC);
zdtStart = LocalDateTime.parse(startDate, formatter);
zdtEnd = LocalDateTime.parse(endDate, formatter);
}

var dataSize = tenantService.getPatientDataReportSize(patientId, resourceType, zdtStart, zdtEnd);

var summary = new DataSizeSummary();
summary.setStartDate(zdtStart);
summary.setEndDate(zdtEnd);
double sum = 0.0;
var dataCountMap = summary.getCountDataType();
var dataAverageMap = summary.getAverageDataSize();

var rtKey = "ResourceType";
var pidKey = "PatientId";

dataCountMap.put(rtKey, new HashMap<>());
dataCountMap.put(pidKey, new HashMap<>());

dataAverageMap.put(rtKey, new HashMap<>());
dataAverageMap.put(pidKey, new HashMap<>());

double min = 0, max = 0;
for(var r : dataSize)
{
var resourceKey = r.getResourceType();
var patientKey = r.getPatientId();

if(patientKey == null || resourceKey == null)
continue;

var sizeKb = r.getSizeKb();
sum += sizeKb;

if(min > sizeKb || min == 0)
min = sizeKb;

if(max < sizeKb)
max = sizeKb;

dataCountMap.get(rtKey).merge(resourceKey, 1, (count, value) -> count + value);
dataCountMap.get(pidKey).merge(patientKey, 1, (count, value) -> count + value);

dataAverageMap.get(rtKey).merge(resourceKey, r.getSizeKb(), (size, value) -> size + value);
dataAverageMap.get(pidKey).merge(patientKey, r.getSizeKb(), (size, value) -> size + value);
}

summary.setTotalSize(sum);
summary.setData(Collections.singletonList(dataSize));
summary.setCount(dataSize.size());
summary.setAverageSize(sum/dataSize.size());
summary.setMinSize(min);
summary.setMaxSize(max);

dataAverageMap.get(rtKey).replaceAll((key, value) -> value/dataCountMap.get(rtKey).get(key));
dataAverageMap.get(pidKey).replaceAll((key, value) -> value/dataCountMap.get(pidKey).get(key));

return summary;
}
}
14 changes: 14 additions & 0 deletions core/src/main/java/com/lantanagroup/link/db/TenantService.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -235,6 +236,19 @@ public List<PatientMeasureReport> getPatientMeasureReports(String reportId) {
public List<PatientMeasureReport> getPatientMeasureReports(String reportId, String measureId) {
return this.patientMeasureReports.findByReportIdAndMeasureId(reportId, measureId);
}
public List<PatientMeasureReportSize> getPatientMeasureReportSize(String patientId, String reportId, String measureId, String patientMeasureReportId) {
if(patientMeasureReportId != null && !patientMeasureReportId.isEmpty()) {
var reportSize = patientMeasureReports.GetMeasureReportSizeById(patientMeasureReportId);
return List.of(reportSize);
}
else {
return patientMeasureReports.GetMeasureReportSize(patientId, reportId, measureId);
}
}

public List<PatientDataSize> getPatientDataReportSize(String patientId, String resourceType, LocalDateTime startDate, LocalDateTime endDate) {
return patientDatas.GetPatientDataResourceSizeInDateRange(patientId, resourceType, startDate, endDate);
}

public void savePatientMeasureReport(PatientMeasureReport patientMeasureReport) {
this.patientMeasureReports.save(patientMeasureReport);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ public Row(ResultSet resultSet) {
public String getString(String columnName) throws SQLException {
return resultSet.getNString(columnName);
}

public double getDouble(String columnName) throws SQLException {
return resultSet.getDouble(columnName);
}
public Date getDate(String columnName) throws SQLException {
return resultSet.getTimestamp(columnName);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.lantanagroup.link.db.mappers;

import com.lantanagroup.link.db.model.PatientDataSize;

import java.sql.ResultSet;
import java.sql.SQLException;

public class PatientDataSizeMapper extends BaseMapper<PatientDataSize> {
@Override
protected PatientDataSize doToModel(ResultSet resultSet) throws SQLException {
Row row = new Row(resultSet);
var model = new PatientDataSize();
model.setResourceType(row.getString("resourceType"));
model.setPatientId(row.getString("patientId"));
model.setSizeKb(row.getDouble("sizeKb"));

return model;
}

@Override
protected Parameters doToParameters(PatientDataSize model) {
Parameters parameters = new Parameters();
parameters.addString("reportId", model.getResourceType());
parameters.addString("patientId", model.getPatientId());
parameters.addValue("sizeKb", model.getSizeKb());
return parameters;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.lantanagroup.link.db.mappers;

import com.lantanagroup.link.db.model.PatientMeasureReportSize;

import java.sql.ResultSet;
import java.sql.SQLException;

public class PatientMeasureReportSizeMapper extends BaseMapper<PatientMeasureReportSize> {
@Override
protected PatientMeasureReportSize doToModel(ResultSet resultSet) throws SQLException {
Row row = new Row(resultSet);
var model = new PatientMeasureReportSize();
model.setReportId(row.getString("reportId"));
model.setMeasureId(row.getString("measureId"));
model.setPatientId(row.getString("patientId"));
model.setSizeKb(row.getDouble("sizeKb"));

return model;
}

@Override
protected Parameters doToParameters(PatientMeasureReportSize model) {
Parameters parameters = new Parameters();
parameters.addString("reportId", model.getReportId());
parameters.addString("measureId", model.getMeasureId());
parameters.addString("patientId", model.getPatientId());
parameters.addValue("sizeKb", model.getSizeKb());
return parameters;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.lantanagroup.link.db.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class PatientDataSize {
private String patientId;
private String resourceType;
private double SizeKb;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.lantanagroup.link.db.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class PatientMeasureReportSize {
private String reportId;
private String measureId;
private String patientId;
private double SizeKb;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.lantanagroup.link.db.repositories;

import com.lantanagroup.link.db.mappers.PatientDataMapper;
import com.lantanagroup.link.db.mappers.PatientDataSizeMapper;
import com.lantanagroup.link.db.model.PatientData;
import com.lantanagroup.link.db.model.PatientDataSize;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
Expand All @@ -11,15 +13,13 @@
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.time.LocalDateTime;
import java.util.*;

public class PatientDataRepository {
private static final Logger logger = LoggerFactory.getLogger(PatientDataRepository.class);
private static final PatientDataMapper mapper = new PatientDataMapper();

private static final PatientDataSizeMapper sizeMapper = new PatientDataSizeMapper();
private final TransactionTemplate txTemplate;
private final NamedParameterJdbcTemplate jdbc;

Expand All @@ -44,6 +44,35 @@ public List<PatientData> findByReportIdAndPatientId(String reportId, String pati
return jdbc.query(sql, parameters, mapper);
}

public List<PatientDataSize> GetPatientDataResourceSize(String patientId, String resourceType) {
String sql = "SELECT pmr.patientId, pmr.resourceType, CAST(SUM(DATALENGTH(pmr.resource)) as FLOAT)/1024.0 as sizeKb FROM dbo.patientData AS pmr WHERE (:resourceType = '' OR resourceType = :resourceType) AND (:patientId = '' OR patientId = :patientId) GROUP BY pmr.patientId, pmr.resourceType";

if(resourceType == null) resourceType = "";
if(patientId == null) patientId = "";

HashMap<String, String> parameters = new HashMap();
parameters.put("resourceType", resourceType);
parameters.put("patientId", patientId);


return jdbc.query(sql, parameters, sizeMapper);
}

public List<PatientDataSize> GetPatientDataResourceSizeInDateRange(String patientId, String resourceType, LocalDateTime startDate, LocalDateTime endDate) {
String sql = "SELECT pmr.patientId, pmr.resourceType, CAST(SUM(DATALENGTH(pmr.resource)) as FLOAT)/1024.0 as sizeKb FROM dbo.patientData AS pmr WHERE (:resourceType = '' OR resourceType = :resourceType) AND (:patientId = '' OR patientId = :patientId) AND (:startDate IS NULL OR pmr.retrieved BETWEEN :startDate AND :endDate) GROUP BY pmr.patientId, pmr.resourceType";

if(resourceType == null) resourceType = "";
if(patientId == null) patientId = "";

HashMap<String, Object> parameters = new HashMap<>();
parameters.put("resourceType", resourceType);
parameters.put("patientId", patientId);
parameters.put("startDate", startDate);
parameters.put("endDate", endDate);

return jdbc.query(sql, parameters, sizeMapper);
}

public void saveAll(String reportId, List<PatientData> models) {
String sql = "INSERT INTO dbo.patientData (id, dataTraceId, patientId, resourceType, resourceId, resource, retrieved) " +
"SELECT :id, :dataTraceId, :patientId, :resourceType, :resourceId, :resource, :retrieved " +
Expand Down
Loading