diff --git a/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ReportDataController.java b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ReportDataController.java index 91e6a184e5..8f7b585858 100644 --- a/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ReportDataController.java +++ b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ReportDataController.java @@ -19,7 +19,6 @@ import gov.healthit.chpl.report.listing.UniqueListingCount; import gov.healthit.chpl.report.product.ProductByAcb; import gov.healthit.chpl.report.product.UniqueProductCount; -import gov.healthit.chpl.report.servicebaseurllistreport.UrlUptimeMonitorEx; import gov.healthit.chpl.report.surveillance.CapCounts; import gov.healthit.chpl.report.surveillance.NonconformityCounts; import gov.healthit.chpl.report.surveillance.SurveillanceActivityCounts; @@ -429,16 +428,6 @@ public ReportDataController(ReportDataManager reportDataManager, return reportDataManager.getDirectReviewCounts(); } - @Operation(summary = "Retrieves the data used to generate the Service Base Url List report.", - description = "Retrieves the data used to generate the Service Base Url List report.", - security = { - @SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY) - }) - @LogMethodUsage - @RequestMapping(value = "/service-base-url-list", method = RequestMethod.GET, produces = "application/json; charset=utf-8") - public @ResponseBody List getUrlUptimeMonitors() { - return reportDataManager.getUrlUptimeMonitors(); - } @Operation(summary = "Get count of Criteria certified to by unique Product.", description = "Retrieves and returns the Criterion/Product counts.", diff --git a/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ServiceBaseUrlListReportController.java b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ServiceBaseUrlListReportController.java new file mode 100644 index 0000000000..4e49626f83 --- /dev/null +++ b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ServiceBaseUrlListReportController.java @@ -0,0 +1,59 @@ +package gov.healthit.chpl.web.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import gov.healthit.chpl.report.ReportDataManager; +import gov.healthit.chpl.report.servicebaseurllistreport.UrlUptimeMonitorEx; +import gov.healthit.chpl.report.servicebaseurllistreport.UrlUptimeMonitorSummary; +import gov.healthit.chpl.util.LogMethodUsage; +import gov.healthit.chpl.util.SwaggerSecurityRequirement; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@Tag(name = "report-data/service-base-url-list", description = "Allows retrieval of data used by SBUL reports.") +@RestController +@RequestMapping("/report-data/service-base-url-list") +public class ServiceBaseUrlListReportController { + private ReportDataManager reportDataManager; + + @Autowired + public ServiceBaseUrlListReportController(ReportDataManager reportDataManager) { + this.reportDataManager = reportDataManager; + } + + @Operation(summary = "Retrieves the data used to generate the Service Base Url List report.", + description = "Retrieves the data used to generate the Service Base Url List report.", + security = { + @SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY) + }) + @LogMethodUsage + @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json; charset=utf-8") + public @ResponseBody List getUrlUptimeMonitors() { + return reportDataManager.getUrlUptimeMonitors(); + } + + @Operation(summary = "Retrieves the data used to generate the Service Base Url List uptime summaries by Developer and URL.", + description = "Retrieves the data used to generate the Service Base Url List uptime summaries by Developer and URL. " + + "Returns uptime summaries for the last 30 days by default, which can be adjusted using the parameters.", + security = { + @SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY) + }) + @LogMethodUsage + @RequestMapping(value = "/uptime-summary", method = RequestMethod.GET, produces = "application/json; charset=utf-8") + public @ResponseBody List getUrlUptimeMonitorsSummaries( + @RequestParam(name = "numDaysAgoMin", required = false, defaultValue = "0") Integer numDaysAgoMin, + @RequestParam(name = "numDaysAgoMax", required = false, defaultValue = "30") Integer numDaysAgoMax) { + return reportDataManager.getUrlUptimeMonitorsSummaries(numDaysAgoMin, numDaysAgoMax); + } + +} diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/entity/developer/DeveloperEntitySimple.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/entity/developer/DeveloperEntitySimple.java index 9ea9dd962e..baa331561a 100644 --- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/entity/developer/DeveloperEntitySimple.java +++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/entity/developer/DeveloperEntitySimple.java @@ -1,5 +1,10 @@ package gov.healthit.chpl.entity.developer; +import org.hibernate.annotations.Immutable; + +import gov.healthit.chpl.domain.Developer; +import gov.healthit.chpl.domain.contact.PointOfContact; +import gov.healthit.chpl.entity.EntityAudit; import jakarta.persistence.Basic; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -7,12 +12,6 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; - -import org.hibernate.annotations.Immutable; - -import gov.healthit.chpl.domain.Developer; -import gov.healthit.chpl.domain.contact.PointOfContact; -import gov.healthit.chpl.entity.EntityAudit; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -48,7 +47,7 @@ public class DeveloperEntitySimple extends EntityAudit { @Column(length = 300, nullable = true) private String website; - @Column(name="self_developer") + @Column(name = "self_developer") private Boolean selfDeveloper; @Basic(optional = true) diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/ReportDataManager.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/ReportDataManager.java index cbffa7f610..9bb381620c 100644 --- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/ReportDataManager.java +++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/ReportDataManager.java @@ -27,6 +27,7 @@ import gov.healthit.chpl.report.realworldtesting.RealWorldTestingReportDataService; import gov.healthit.chpl.report.servicebaseurllistreport.ServiceBaseUrlListReportService; import gov.healthit.chpl.report.servicebaseurllistreport.UrlUptimeMonitorEx; +import gov.healthit.chpl.report.servicebaseurllistreport.UrlUptimeMonitorSummary; import gov.healthit.chpl.report.surveillance.CapCounts; import gov.healthit.chpl.report.surveillance.NonconformityCounts; import gov.healthit.chpl.report.surveillance.SurveillanceActivityCounts; @@ -292,6 +293,11 @@ public List getUrlUptimeMonitors() { return serviceBaseUrlListReportService.getUrlUptimeMonitors(); } + @Synchronized("lock") + public List getUrlUptimeMonitorsSummaries(Integer numDaysAgoMin, Integer numDaysAgoMax) { + return serviceBaseUrlListReportService.getUrlUptimeMonitorsSummaries(numDaysAgoMin, numDaysAgoMax); + } + @Synchronized("lock") public RealWorldTestingReportDataService getRealWorldTestingReportDataService() { return realWorldTestingReportDataService; diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/servicebaseurllistreport/ServiceBaseUrlListReportService.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/servicebaseurllistreport/ServiceBaseUrlListReportService.java index 0eb3b1f237..3516f3d8b4 100644 --- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/servicebaseurllistreport/ServiceBaseUrlListReportService.java +++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/servicebaseurllistreport/ServiceBaseUrlListReportService.java @@ -1,35 +1,37 @@ package gov.healthit.chpl.report.servicebaseurllistreport; import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import gov.healthit.chpl.developer.search.DeveloperSearchService; import gov.healthit.chpl.domain.IdNamePair; import gov.healthit.chpl.exception.EntityRetrievalException; import gov.healthit.chpl.manager.CertificationBodyManager; import gov.healthit.chpl.scheduler.job.urluptime.UrlUptimeMonitor; import gov.healthit.chpl.scheduler.job.urluptime.UrlUptimeMonitorDAO; +import gov.healthit.chpl.scheduler.job.urluptime.UrlUptimeMonitorTest; import gov.healthit.chpl.scheduler.job.urluptime.UrlUptimeMonitorTestDAO; import lombok.extern.log4j.Log4j2; @Log4j2 @Component public class ServiceBaseUrlListReportService { + private static final Double CONVERT_TO_PERCENT = 100.0; + private UrlUptimeMonitorDAO urlUptimeMonitorDAO; private UrlUptimeMonitorTestDAO urlUptimeMonitorTestDAO; - private DeveloperSearchService developerSearchService; private CertificationBodyManager certificationBodyManager; @Autowired - public ServiceBaseUrlListReportService(UrlUptimeMonitorDAO urlUptimeMonitorDAO, UrlUptimeMonitorTestDAO urlUptimeMonitorTestDAO, DeveloperSearchService developerSearchService, + public ServiceBaseUrlListReportService(UrlUptimeMonitorDAO urlUptimeMonitorDAO, + UrlUptimeMonitorTestDAO urlUptimeMonitorTestDAO, CertificationBodyManager certificationBodyManager) { this.urlUptimeMonitorDAO = urlUptimeMonitorDAO; this.urlUptimeMonitorTestDAO = urlUptimeMonitorTestDAO; - this.developerSearchService = developerSearchService; this.certificationBodyManager = certificationBodyManager; } @@ -48,6 +50,20 @@ public List getUrlUptimeMonitors() { .toList(); } + public List getUrlUptimeMonitorsSummaries(Integer numDaysAgoMin, Integer numDaysAgoMax) { + LocalDateTime minTestCheckTime = LocalDateTime.now().minusDays(numDaysAgoMax).truncatedTo(ChronoUnit.DAYS); + LocalDateTime maxTestCheckTime = LocalDateTime.now().minusDays(numDaysAgoMin).truncatedTo(ChronoUnit.DAYS); + + LOGGER.info("Finding URL Uptime Monitor Tests that happened between " + minTestCheckTime + " and " + maxTestCheckTime); + return (List) urlUptimeMonitorDAO.getAll().stream() + .map(monitor -> UrlUptimeMonitorSummary.builder() + .developer(monitor.getDeveloper()) + .url(monitor.getUrl()) + .percentPassed(calculatePercentPassedBetween(monitor.getId(), minTestCheckTime, maxTestCheckTime)) + .build()) + .toList(); + } + private List getAssocatedAcbs(UrlUptimeMonitor monitor) { if (monitor.getDelimitedAcbIds() == null || monitor.getDelimitedAcbIds().equals("")) { return List.of(); @@ -66,4 +82,21 @@ private List getAssocatedAcbs(UrlUptimeMonitor monitor) { .map(acb -> new IdNamePair(acb.getId(), acb.getName())) .toList(); } + + private Double calculatePercentPassedBetween(Long monitorId, LocalDateTime minTestCheckTime, LocalDateTime maxTestCheckTime) { + List uptimeTestsWithinTimeWindow = urlUptimeMonitorTestDAO.getChplUptimeMonitorTests(monitorId).stream() + .filter(test -> + (test.getCheckTime().isEqual(minTestCheckTime) || test.getCheckTime().isAfter(minTestCheckTime)) + && (test.getCheckTime().isEqual(maxTestCheckTime) || test.getCheckTime().isBefore(maxTestCheckTime))) + .toList(); + long totalTests = uptimeTestsWithinTimeWindow.size(); + long passedTests = uptimeTestsWithinTimeWindow.stream() + .filter(test -> test.getPassed()) + .count(); + + if (passedTests == 0 || totalTests == 0) { + return 0.0; + } + return ((double) passedTests / totalTests) * CONVERT_TO_PERCENT; + } } diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/servicebaseurllistreport/UrlUptimeMonitorSummary.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/servicebaseurllistreport/UrlUptimeMonitorSummary.java new file mode 100644 index 0000000000..1505bf4847 --- /dev/null +++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/servicebaseurllistreport/UrlUptimeMonitorSummary.java @@ -0,0 +1,17 @@ +package gov.healthit.chpl.report.servicebaseurllistreport; + +import gov.healthit.chpl.domain.Developer; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class UrlUptimeMonitorSummary { + private Developer developer; + private String url; + private Double percentPassed; +}