Skip to content

Commit 6fca0a1

Browse files
Merge remote-tracking branch 'origin/master' into BFD-4348-prune-older-claim-versions-excluding-part-d
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
2 parents 36efe2b + 8190fb4 commit 6fca0a1

29 files changed

Lines changed: 951 additions & 29 deletions

.github/workflows/v3-release-deploy.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ jobs:
388388
idr-pipeline-metrics,
389389
idr-pipeline-alarms,
390390
server-ng,
391-
server-ng-metrics
391+
server-ng-metrics,
392+
server-ng-alarms
392393
git-ref: ${{ github.ref_name }}
393394
per-service-vars-json: >-
394395
{

apps/bfd-pipeline-idr/model/base_model.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -850,13 +850,18 @@ def stale_phase_1_claims_query(
850850
cutoff_date: datetime,
851851
) -> tuple[str, tuple[datetime, datetime]]:
852852
return (
853-
f"""
853+
f"""
854+
WITH claims AS (
855+
SELECT clm.clm_uniq_id
856+
FROM {header_table} clm
857+
WHERE clm.clm_type_cd BETWEEN {PHASE_1_SS_MIN} AND {PHASE_1_SS_MAX}
858+
AND clm.clm_src_id IN ('{FISS_CLM_SOURCE}', '{MCS_CLM_SOURCE}', '{VMS_CLM_SOURCE}')
859+
AND clm.bfd_updated_ts < %s
860+
ORDER BY clm.bfd_updated_ts, clm.clm_uniq_id
861+
)
854862
SELECT clm.clm_uniq_id
855-
FROM {header_table} clm
856-
WHERE clm.clm_type_cd BETWEEN {PHASE_1_SS_MIN} AND {PHASE_1_SS_MAX}
857-
AND clm.clm_src_id IN ('{FISS_CLM_SOURCE}', '{MCS_CLM_SOURCE}', '{VMS_CLM_SOURCE}')
858-
AND clm.bfd_updated_ts < %s
859-
AND NOT EXISTS (
863+
FROM claims clm
864+
WHERE NOT EXISTS (
860865
SELECT 1 FROM {item_table} item
861866
WHERE clm.clm_uniq_id = item.clm_uniq_id
862867
AND item.bfd_updated_ts >= %s

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/Application.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,19 @@ public Clock systemClock() {
8383
* @param configuration app configuration
8484
* @param auditEventRepository Audit Event Repository
8585
* @param objectMapper object mapper
86+
* @param certPartnersConfiguration certificate configuration
8687
* @return audit logger
8788
*/
8889
@Bean
8990
public AuditLogger auditLogger(
9091
Configuration configuration,
9192
AuditEventRepository auditEventRepository,
92-
ObjectMapper objectMapper) {
93-
return configuration.getAuditLogger(auditEventRepository, objectMapper);
93+
ObjectMapper objectMapper,
94+
CertPartnersConfiguration certPartnersConfiguration) {
95+
return configuration.getAuditLogger(
96+
auditEventRepository,
97+
objectMapper,
98+
certPartnersConfiguration.getPartnerNamesByCertificateAlias());
9499
}
95100

96101
/**
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package gov.cms.bfd.server.ng;
2+
3+
import com.google.gson.Gson;
4+
import java.util.ArrayList;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.Objects;
9+
import java.util.stream.Collectors;
10+
import lombok.Data;
11+
import lombok.Getter;
12+
import org.springframework.boot.context.properties.ConfigurationProperties;
13+
import org.springframework.stereotype.Component;
14+
15+
/** Typed representation of cert partner configuration loaded from properties. */
16+
@Data
17+
@Component
18+
@ConfigurationProperties("bfd.nonsensitive")
19+
public class CertPartnersConfiguration {
20+
private CertPartnerProperties certPartners = new CertPartnerProperties();
21+
22+
@Getter(lazy = true)
23+
private final Map<String, String> partnerNamesByCertificateAlias =
24+
getPartnerNamesByCertificateAliasInternal();
25+
26+
private Map<String, String> getPartnerNamesByCertificateAliasInternal() {
27+
return certPartners.getPartnerCertificate().entrySet().stream()
28+
.flatMap(
29+
entry -> {
30+
var partner = new Gson().fromJson(entry.getValue(), Partner.class);
31+
return partner.getCertificateAliases().stream()
32+
.filter(Objects::nonNull)
33+
.map(alias -> Map.entry(alias, partner.getName()));
34+
})
35+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
36+
}
37+
38+
/** bfd.nonsensitive.cert_partners properties. */
39+
@Data
40+
private static class CertPartnerProperties {
41+
private Map<String, String> partnerCertificate = new HashMap<>();
42+
}
43+
44+
/** Partner certificate configuration from cert_partners properties. */
45+
@Data
46+
private static class Partner {
47+
private String name;
48+
49+
private List<String> certificateAliases = new ArrayList<>();
50+
}
51+
}

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/Configuration.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,17 @@ public DataSourceFactory getDataSourceFactory() {
118118
*
119119
* @param auditEventRepository used for logging to DynamoDB
120120
* @param objectMapper used for serializing patient audit records
121+
* @param partnerAliases used for mapping certificate aliases to partner names
121122
* @return audit logger
122123
*/
123124
public AuditLogger getAuditLogger(
124-
AuditEventRepository auditEventRepository, ObjectMapper objectMapper) {
125+
AuditEventRepository auditEventRepository,
126+
ObjectMapper objectMapper,
127+
Map<String, String> partnerAliases) {
125128
var logStreamLogger = new LogStreamAuditLogger(objectMapper);
126129
if (getAuditLoggerType() == AuditLoggerType.DYNAMO_DB) {
127-
var dynamoLogger = new DynamoDbAuditLogger(auditEventRepository, objectMapper);
130+
var dynamoLogger =
131+
new DynamoDbAuditLogger(auditEventRepository, objectMapper, partnerAliases);
128132

129133
return auditRecord -> {
130134
logStreamLogger.log(auditRecord);

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/audit/AuditEventBase.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import static gov.cms.bfd.server.ng.util.LoggerConstants.FINAL_DETERMINATION;
1010
import static gov.cms.bfd.server.ng.util.LoggerConstants.MATCHED_BENE_SK;
1111
import static gov.cms.bfd.server.ng.util.LoggerConstants.MATCH_ALGORITHM_VERSION;
12+
import static gov.cms.bfd.server.ng.util.LoggerConstants.PARTNER_APP_NAME;
1213
import static gov.cms.bfd.server.ng.util.LoggerConstants.TIMESTAMP;
1314

1415
import gov.cms.bfd.server.ng.util.SystemUrls;
@@ -41,6 +42,7 @@ public class AuditEventBase {
4142
private String combinationsEvaluated;
4243
private String finalDetermination;
4344
private String matchAlgorithmVersion;
45+
private String partnerAppName;
4446

4547
/**
4648
* Create Audit Table Schema For DynamoDB. We use this rather than @DynamoDbBean. This annotation
@@ -106,6 +108,12 @@ public class AuditEventBase {
106108
a.name(MATCH_ALGORITHM_VERSION)
107109
.getter(AuditEventBase::getMatchAlgorithmVersion)
108110
.setter(AuditEventBase::setMatchAlgorithmVersion))
111+
.addAttribute(
112+
String.class,
113+
a ->
114+
a.name(PARTNER_APP_NAME)
115+
.getter(AuditEventBase::getPartnerAppName)
116+
.setter(AuditEventBase::setPartnerAppName))
109117
.build();
110118

111119
/**

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/beneficiary/model/PatientMatchAuditRecord.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ public record PatientMatchAuditRecord(
1919
String clientId,
2020
Instant timestamp,
2121
List<MatchCombinationResult> combinationsEvaluated,
22-
Optional<FinalDetermination> finalDetermination) {}
22+
Optional<FinalDetermination> finalDetermination,
23+
String certAlias) {}

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/log/DynamoDbAuditLogger.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import gov.cms.bfd.server.ng.audit.AuditEventRepository;
77
import gov.cms.bfd.server.ng.beneficiary.model.PatientMatchAuditRecord;
88
import java.util.HashSet;
9+
import java.util.Map;
910
import lombok.AllArgsConstructor;
1011
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
1112

@@ -15,6 +16,7 @@ public class DynamoDbAuditLogger implements AuditLogger {
1516

1617
private final AuditEventRepository auditEventRepository;
1718
private final ObjectMapper objectMapper;
19+
private final Map<String, String> partnerAliases;
1820

1921
@Override
2022
public void log(PatientMatchAuditRecord auditRecord) {
@@ -30,6 +32,8 @@ public void log(PatientMatchAuditRecord auditRecord) {
3032
auditEvent.setTimestamp(auditRecord.timestamp().toString());
3133
auditEvent.setClientId(auditRecord.clientId());
3234
auditEvent.setClientName(auditRecord.clientName());
35+
auditEvent.setPartnerAppName(
36+
partnerAliases.getOrDefault(auditRecord.certAlias(), "Unknown"));
3337
auditEvent.setClientIp(auditRecord.clientIp());
3438
auditEvent.setCombinationsEvaluated(
3539
objectMapper.writeValueAsString(auditRecord.combinationsEvaluated()));

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/patient/PatientHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,16 @@ public Bundle matchPatient(Optional<PatientMatch> patientMatch) {
105105
var clientIp = MDC.get(logKey(MDC_PREFIX, CLIENT_IP_KEY));
106106
var clientName = MDC.get(logKey(MDC_PREFIX, CLIENT_NAME_KEY));
107107
var clientId = MDC.get(logKey(MDC_PREFIX, CLIENT_ID_KEY));
108+
var certAlias = MDC.get(logKey(MDC_PREFIX, CERTIFICATE_ALIAS));
108109
var auditRecord =
109110
new PatientMatchAuditRecord(
110111
clientIp,
111112
clientName,
112113
clientId,
113114
Instant.now(),
114115
result.combinations(),
115-
result.finalDetermination());
116+
result.finalDetermination(),
117+
certAlias);
116118
auditLogger.log(auditRecord);
117119

118120
return patientMatchBundle(beneficiary);

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/util/CertificateUtil.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ public class CertificateUtil {
1919
private final Configuration configuration;
2020
private final Environment environment;
2121

22-
private static final String LEAF_CERT_HEADER = "X-Amzn-Mtls-Clientcert";
22+
/** Header name for the leaf certificate in the request. */
23+
public static final String LEAF_CERT_HEADER = "X-Amzn-Mtls-Clientcert";
24+
2325
private static final String CLIENT_CERT_ALIAS_ATTRIBUTE = "CLIENT_CERT_ALIAS";
2426

2527
/**

0 commit comments

Comments
 (0)