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

fix!: Put back /criterion_product endpoint accidentally removed #1796

Open
wants to merge 1 commit into
base: staging
Choose a base branch
from
Open
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 @@ -12,6 +12,7 @@
import gov.healthit.chpl.developer.search.DeveloperSearchRequest;
import gov.healthit.chpl.developer.search.DeveloperSearchResult;
import gov.healthit.chpl.developer.search.DeveloperSearchService;
import gov.healthit.chpl.manager.StatisticsManager;
import gov.healthit.chpl.report.ReportDataManager;
import gov.healthit.chpl.report.ReportMetadata;
import gov.healthit.chpl.report.criteriamigrationreport.CriteriaMigrationReportDenormalized;
Expand All @@ -28,6 +29,7 @@
import gov.healthit.chpl.scheduler.job.summarystatistics.data.CertificationBodyStatistic;
import gov.healthit.chpl.search.domain.ListingSearchResult;
import gov.healthit.chpl.util.SwaggerSecurityRequirement;
import gov.healthit.chpl.web.controller.results.CriterionProductStatisticsResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -41,11 +43,15 @@
@RequestMapping("/report-data")
public class ReportDataController {
private ReportDataManager reportDataManager;
private StatisticsManager statisticsManager;
private DeveloperSearchService developerSearchService;

@Autowired
public ReportDataController(ReportDataManager reportDataManager, DeveloperSearchService developerSearchService) {
public ReportDataController(ReportDataManager reportDataManager,
StatisticsManager statisticsManager,
DeveloperSearchService developerSearchService) {
this.reportDataManager = reportDataManager;
this.statisticsManager = statisticsManager;
this.developerSearchService = developerSearchService;
}

Expand Down Expand Up @@ -431,4 +437,17 @@ public ReportDataController(ReportDataManager reportDataManager, DeveloperSearch
public @ResponseBody List<AttestationReport> getAttestationReports() {
return reportDataManager.getAttestationReports();
}

@Operation(summary = "Get count of Criteria certified to by unique Product.",
description = "Retrieves and returns the Criterion/Product counts.",
security = {
@SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY)
})
@RequestMapping(value = "/criterion-product", method = RequestMethod.GET,
produces = "application/json; charset=utf-8")
public @ResponseBody CriterionProductStatisticsResult getCriterionProductStatistics() {
CriterionProductStatisticsResult response = new CriterionProductStatisticsResult();
response.setCriterionProductStatisticsResult(statisticsManager.getCriterionProductStatisticsResult());
return response;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
import java.util.Date;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import gov.healthit.chpl.certificationCriteria.CertificationCriterion;
import gov.healthit.chpl.manager.StatisticsManager;
import gov.healthit.chpl.util.SwaggerSecurityRequirement;
import gov.healthit.chpl.web.controller.annotation.DeprecatedApi;
import gov.healthit.chpl.web.controller.results.CriterionProductStatisticsResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -21,6 +25,30 @@
@RestController
@RequestMapping("/statistics")
public class StatisticsController {
private StatisticsManager statisticsManager;

@Autowired
public StatisticsController(StatisticsManager statisticsManager) {
this.statisticsManager = statisticsManager;
}

@Deprecated
@DeprecatedApi(friendlyUrl = "/statistics/criterion_product",
message = "This endpoint is deprecated and will be removed in a future release. Please use /report-data/criterion-product as a replacement.",
removalDate = "2025-09-01")
@Operation(summary = "Get count of Criteria certified to by unique Product.",
description = "Retrieves and returns the Criterion/Product counts.",
security = {
@SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY)
})
@RequestMapping(value = "/criterion_product", method = RequestMethod.GET,
produces = "application/json; charset=utf-8")
public @ResponseBody CriterionProductStatisticsResult getCriterionProductStatistics() {
CriterionProductStatisticsResult response = new CriterionProductStatisticsResult();
response.setCriterionProductStatisticsResult(statisticsManager.getCriterionProductStatisticsResult());
return response;
}


@Deprecated
@DeprecatedApi(friendlyUrl = "/statistics/nonconformity_criteria_count",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package gov.healthit.chpl.web.controller.results;

Check warning on line 1 in chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/results/CriterionProductStatisticsResult.java

View workflow job for this annotation

GitHub Actions / Checkstyle job

[reviewdog] reported by reviewdog 🐶 File does not end with a newline. Raw Output: /github/workspace/./chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/results/CriterionProductStatisticsResult.java:1:0: warning: File does not end with a newline. (com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck)

import java.util.ArrayList;
import java.util.List;

import gov.healthit.chpl.domain.CriterionProductStatistics;

public class CriterionProductStatisticsResult {
private List<CriterionProductStatistics> criterionProductStatisticsResult;

public CriterionProductStatisticsResult() {
this.criterionProductStatisticsResult = new ArrayList<CriterionProductStatistics>();
}

public List<CriterionProductStatistics> getCriterionProductStatisticsResult() {
return criterionProductStatisticsResult;
}

public void setCriterionProductStatisticsResult(
final List<CriterionProductStatistics> criterionProductStatisticsResult) {
this.criterionProductStatisticsResult = criterionProductStatisticsResult;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<Appenders>
<Console name="chartDataCreatorJobJson" target="SYSTEM_OUT">
<JsonLayout compact="true" eventEol="true" properties="true" stacktraceAsString="true">
<KeyValuePair key="service" value="chartDataCreatorJob" />
<KeyValuePair key="dd.trace_id" value="%X{dd.trace_id}" />
<KeyValuePair key="dd.span_id" value="%X{dd.span_id}" />
</JsonLayout>
</Console>
<Console name="standardsUpdateJobJson" target="SYSTEM_OUT">
<JsonLayout compact="true" eventEol="true" properties="true" stacktraceAsString="true">
<KeyValuePair key="service" value="standardsUpdateJob" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<Appenders>
<RollingFile name="chartDataCreatorJob"
fileName="${logDir}/scheduler/chartDataCreatorJob.log"
filePattern="${logDir}/scheduler/history/chartDataCreatorJob-%d{yyyy-MM-dd}.log"
filePermissions="rw-rw-r--">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %X{dd.trace_id} %X{dd.span_id} - %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy
interval="1" modulate="true" />
</Policies>
</RollingFile>
<RollingFile name="standardsUpdateJob"
fileName="${logDir}/scheduler/standardsUpdateJob.log"
filePattern="${logDir}/scheduler/history/standardsUpdateJob-%d{yyyy-MM-dd}.log"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
<Logger name="questionableUrlReportGeneratorJobLogger" level="INFO" additivity="false">
<AppenderRef ref="questionableUrlReportGeneratorJob" />
</Logger>
<Logger name="chartDataCreatorJobLogger" level="INFO" additivity="false">
<AppenderRef ref="chartDataCreatorJob" />
</Logger>
<Logger name="standardsUpdateJobLogger" level="INFO" additivity="false">
<AppenderRef ref="standardsUpdateJob" />
</Logger>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
<AppenderRef ref="questionableUrlReportGeneratorJob" />
<AppenderRef ref="questionableUrlReportGeneratorJobJson" />
</Logger>
<Logger name="chartDataCreatorJobLogger" level="INFO" additivity="false">
<AppenderRef ref="chartDataCreatorJob" />
<AppenderRef ref="chartDataCreatorJobJson" />
</Logger>
<Logger name="standardsUpdateJobLogger" level="INFO" additivity="false">
<AppenderRef ref="standardsUpdateJob" />
<AppenderRef ref="standardsUpdateJobJson" />
Expand Down
14 changes: 10 additions & 4 deletions chpl/chpl-resources/src/main/resources/jobs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
<delete-triggers-in-group>triggerJob</delete-triggers-in-group>
<delete-triggers-in-group>interruptJob</delete-triggers-in-group>
<!-- BEGIN REMOVE after PROD push -->
<delete-job>
<name>chartDataCreator</name>
<group>systemJobs</group>
</delete-job>
<!-- END remove after PROD push -->
</pre-processing-commands>
<processing-directives>
Expand Down Expand Up @@ -237,6 +233,16 @@
</job-data-map>
</job>

<!-- Chart data creator -->
<job>
<name>chartDataCreator</name>
<group>systemJobs</group>
<description>Generates the chart data</description>
<job-class>gov.healthit.chpl.scheduler.job.chartdata.ChartDataCreatorJob</job-class>
<durability>true</durability>
<recover>false</recover>
</job>

<job>
<name>standardsUpdateJob</name>
<group>systemJobs</group>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package gov.healthit.chpl.dao;

Check warning on line 1 in chpl/chpl-service/src/main/java/gov/healthit/chpl/dao/CriterionProductStatisticsDAO.java

View workflow job for this annotation

GitHub Actions / Checkstyle job

[reviewdog] reported by reviewdog 🐶 File does not end with a newline. Raw Output: /github/workspace/./chpl/chpl-service/src/main/java/gov/healthit/chpl/dao/CriterionProductStatisticsDAO.java:1:0: warning: File does not end with a newline. (com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck)

import java.util.List;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import gov.healthit.chpl.dao.impl.BaseDAOImpl;
import gov.healthit.chpl.domain.CriterionProductStatistics;
import gov.healthit.chpl.entity.statistics.CriterionProductStatisticsEntity;
import gov.healthit.chpl.exception.EntityCreationException;
import gov.healthit.chpl.exception.EntityRetrievalException;
import jakarta.persistence.Query;


@Repository("criterionProductStatisticsDAO")
public class CriterionProductStatisticsDAO extends BaseDAOImpl {
public List<CriterionProductStatistics> findAll() {
return this.findAllEntities().stream()
.map(entity -> entity.toDomain())
.toList();
}

@Transactional
public void delete(Long id) throws EntityRetrievalException {
CriterionProductStatisticsEntity toDelete = getEntityById(id);

if (toDelete != null) {
toDelete.setDeleted(true);
entityManager.merge(toDelete);
}
}

@Transactional
public CriterionProductStatisticsEntity create(CriterionProductStatistics criteirCriterionProductStatistics)
throws EntityCreationException, EntityRetrievalException {

CriterionProductStatisticsEntity entity = new CriterionProductStatisticsEntity();
entity.setProductCount(criteirCriterionProductStatistics.getProductCount());
entity.setCertificationCriterionId(criteirCriterionProductStatistics.getCertificationCriterionId());

entityManager.persist(entity);
entityManager.flush();
return entity;
}

private List<CriterionProductStatisticsEntity> findAllEntities() {
Query query = entityManager.createQuery("from CriterionProductStatisticsEntity cpse "
+ "LEFT OUTER JOIN FETCH cpse.certificationCriterion cce "
+ "LEFT OUTER JOIN FETCH cce.certificationEdition "
+ "LEFT JOIN FETCH cce.rule "
+ "WHERE (cpse.deleted = false)",
CriterionProductStatisticsEntity.class);
return query.getResultList();
}

private CriterionProductStatisticsEntity getEntityById(Long id) throws EntityRetrievalException {
CriterionProductStatisticsEntity entity = null;

Query query = entityManager.createQuery("from CriterionProductStatisticsEntity cpse "
+ "LEFT OUTER JOIN FETCH cpse.certificationCriterion cce "
+ "LEFT OUTER JOIN FETCH cce.certificationEdition "
+ "LEFT JOIN FETCH cce.rule "
+ "WHERE (cpse.deleted = false) "
+ "AND (cpse.id = :entityid)",
CriterionProductStatisticsEntity.class);
query.setParameter("entityid", id);
List<CriterionProductStatisticsEntity> result = query.getResultList();

if (result.size() == 1) {
entity = result.get(0);
} else {
throw new EntityRetrievalException("Data error. Did not find only one entity.");
}

return entity;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package gov.healthit.chpl.domain;

Check warning on line 1 in chpl/chpl-service/src/main/java/gov/healthit/chpl/domain/CriterionProductStatistics.java

View workflow job for this annotation

GitHub Actions / Checkstyle job

[reviewdog] reported by reviewdog 🐶 File does not end with a newline. Raw Output: /github/workspace/./chpl/chpl-service/src/main/java/gov/healthit/chpl/domain/CriterionProductStatistics.java:1:0: warning: File does not end with a newline. (com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck)

import java.io.Serializable;

import gov.healthit.chpl.certificationCriteria.CertificationCriterion;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class CriterionProductStatistics implements Serializable {
private static final long serialVersionUID = -1648513956784683632L;

private Long id;
private Long productCount;
private Long certificationCriterionId;
private CertificationCriterion criterion;
private Integer sortOrder;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package gov.healthit.chpl.entity.statistics;

Check warning on line 1 in chpl/chpl-service/src/main/java/gov/healthit/chpl/entity/statistics/CriterionProductStatisticsEntity.java

View workflow job for this annotation

GitHub Actions / Checkstyle job

[reviewdog] reported by reviewdog 🐶 File does not end with a newline. Raw Output: /github/workspace/./chpl/chpl-service/src/main/java/gov/healthit/chpl/entity/statistics/CriterionProductStatisticsEntity.java:1:0: warning: File does not end with a newline. (com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck)

import gov.healthit.chpl.certificationCriteria.CertificationCriterionEntity;
import gov.healthit.chpl.domain.CriterionProductStatistics;
import gov.healthit.chpl.entity.EntityAudit;
import gov.healthit.chpl.entity.lastmodifieduserstrategy.CurrentUserThenSystemUserStrategy;
import gov.healthit.chpl.entity.lastmodifieduserstrategy.LastModifiedUserStrategy;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;

@Getter
@Setter
@ToString
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "criterion_product_statistics")
public class CriterionProductStatisticsEntity extends EntityAudit {
private static final long serialVersionUID = -4258273713908999510L;

@Override
public LastModifiedUserStrategy getLastModifiedUserStrategy() {
return new CurrentUserThenSystemUserStrategy();
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Long id;

@Basic(optional = false)
@Column(name = "product_count", nullable = false)
private Long productCount;

@Basic(optional = false)
@Column(name = "certification_criterion_id", nullable = false)
private Long certificationCriterionId;

@OneToOne(optional = true, fetch = FetchType.LAZY)
@JoinColumn(name = "certification_criterion_id", insertable = false, updatable = false)
private CertificationCriterionEntity certificationCriterion;

public CriterionProductStatisticsEntity(final Long id) {
this.id = id;
}

@Transient
public Class<?> getClassType() {
return CriterionProductStatisticsEntity.class;
}

public CriterionProductStatistics toDomain() {
return CriterionProductStatistics.builder()
.id(this.id)
.productCount(this.productCount)
.certificationCriterionId(this.certificationCriterionId)
.criterion(this.certificationCriterion.toDomain())
.build();
}
}
Loading