Skip to content

Commit c3630ce

Browse files
fix: Fix continuous event analytics export (#23858)
* Invert skipPrograms ternary in getRegularAnalyticsTables (was returning all programs when skip list was set, filtering when not) * Use getMainName() in removeUpdatedData so continuous updates delete from the live table, not the staging table Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1a42804 commit c3630ce

2 files changed

Lines changed: 80 additions & 6 deletions

File tree

dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcEventAnalyticsTableManager.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,10 @@ private List<AnalyticsTable> getRegularAnalyticsTables(
178178

179179
List<Program> programs =
180180
params.isSkipPrograms()
181-
? idObjectManager.getAllNoAcl(Program.class)
182-
: idObjectManager.getAllNoAcl(Program.class).stream()
181+
? idObjectManager.getAllNoAcl(Program.class).stream()
183182
.filter(p -> !params.getSkipPrograms().contains(p.getUid()))
184-
.toList();
183+
.toList()
184+
: idObjectManager.getAllNoAcl(Program.class);
185185

186186
Integer firstDataYear = availableDataYears.get(0);
187187
Integer latestDataYear = availableDataYears.get(availableDataYears.size() - 1);
@@ -376,7 +376,7 @@ where ax.event in ( \
376376
and ev.lastupdated >= '${startDate}' \
377377
and ev.lastupdated < '${endDate}');""",
378378
Map.of(
379-
"tableName", sqlBuilder.qualifyTable(table.getName()),
379+
"tableName", sqlBuilder.qualifyTable(table.getMainName()),
380380
"programId", String.valueOf(program.getId()),
381381
"startDate", toLongDate(partition.getStartDate()),
382382
"endDate", toLongDate(partition.getEndDate())));
@@ -401,15 +401,15 @@ where ax.event in ( \
401401
and ev.lastupdated >= '${startDate}' \
402402
and ev.lastupdated < '${endDate}');""",
403403
Map.of(
404-
"tableName", sqlBuilder.qualifyTable(table.getName()),
404+
"tableName", sqlBuilder.qualifyTable(table.getMainName()),
405405
"programStageId", String.valueOf(programStageId),
406406
"startDate", toLongDate(partition.getStartDate()),
407407
"endDate", toLongDate(partition.getEndDate())));
408408
}
409409
}
410410

411411
if (isNotBlank(sql)) {
412-
invokeTimeAndLog(sql, "Remove updated events for table: '{}'", table.getName());
412+
invokeTimeAndLog(sql, "Remove updated events for table: '{}'", table.getMainName());
413413
}
414414
}
415415
}

dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/table/JdbcEventAnalyticsTableManagerTest.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
import static org.hamcrest.MatcherAssert.assertThat;
3535
import static org.hamcrest.Matchers.containsString;
3636
import static org.hamcrest.Matchers.equalTo;
37+
import static org.hamcrest.Matchers.hasItem;
3738
import static org.hamcrest.Matchers.hasSize;
3839
import static org.hamcrest.Matchers.is;
40+
import static org.hamcrest.Matchers.not;
3941
import static org.hamcrest.Matchers.notNullValue;
4042
import static org.hisp.dhis.db.model.DataType.BIGINT;
4143
import static org.hisp.dhis.db.model.DataType.CHARACTER_11;
@@ -112,6 +114,7 @@
112114
import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
113115
import org.joda.time.DateTime;
114116
import org.junit.jupiter.api.BeforeEach;
117+
import org.junit.jupiter.api.DisplayName;
115118
import org.junit.jupiter.api.Test;
116119
import org.junit.jupiter.api.extension.ExtendWith;
117120
import org.mockito.ArgumentCaptor;
@@ -1091,6 +1094,77 @@ void verifyTeaTypeOrgUnitFetchesOuNameWhenPopulatingEventAnalyticsTable() {
10911094
assertThat(sql.getValue(), containsString(ouNameQuery));
10921095
}
10931096

1097+
@Test
1098+
@DisplayName("removeUpdatedData deletes from the live table, not the staging table")
1099+
void removeUpdatedDataTargetsLiveTable() {
1100+
ArgumentCaptor<String> sql = ArgumentCaptor.forClass(String.class);
1101+
Program program = createProgram('A');
1102+
program.setProgramType(WITH_REGISTRATION);
1103+
1104+
Date lastFullTableUpdate = new DateTime(2019, 3, 1, 2, 0).toDate();
1105+
Date lastLatestPartitionUpdate = new DateTime(2019, 3, 1, 9, 0).toDate();
1106+
Date startTime = new DateTime(2019, 3, 1, 10, 0).toDate();
1107+
1108+
AnalyticsTableUpdateParams params =
1109+
AnalyticsTableUpdateParams.newBuilder().startTime(startTime).build().withLatestPartition();
1110+
1111+
List<Map<String, Object>> queryResp = new ArrayList<>();
1112+
queryResp.add(Map.of("eventid", 1));
1113+
1114+
when(settings.getLastSuccessfulAnalyticsTablesUpdate()).thenReturn(lastFullTableUpdate);
1115+
when(settings.getLastSuccessfulLatestAnalyticsPartitionUpdate())
1116+
.thenReturn(lastLatestPartitionUpdate);
1117+
when(jdbcTemplate.queryForList(Mockito.anyString())).thenReturn(queryResp);
1118+
when(idObjectManager.getAllNoAcl(Program.class)).thenReturn(List.of(program));
1119+
whenConfigurationPeriodSettings();
1120+
1121+
List<AnalyticsTable> tables = subject.getAnalyticsTables(params);
1122+
assertThat(tables, hasSize(1));
1123+
1124+
subject.removeUpdatedData(tables);
1125+
1126+
verify(jdbcTemplate).execute(sql.capture());
1127+
1128+
String mainTableName = TABLE_PREFIX + program.getUid().toLowerCase();
1129+
assertThat(sql.getValue(), containsString(quote(mainTableName)));
1130+
assertThat(sql.getValue(), not(containsString(quote(mainTableName + STAGING_TABLE_SUFFIX))));
1131+
}
1132+
1133+
@Test
1134+
@DisplayName("getRegularAnalyticsTables excludes programs listed in skipPrograms")
1135+
void getRegularAnalyticsTablesExcludesSkippedPrograms() {
1136+
Program prA = createProgram('A');
1137+
Program prB = createProgram('B');
1138+
Program prC = createProgram('C');
1139+
Program prD = createProgram('D');
1140+
1141+
Set<String> skipPrograms = new HashSet<>();
1142+
skipPrograms.add(prC.getUid());
1143+
skipPrograms.add(prD.getUid());
1144+
1145+
AnalyticsTableUpdateParams params =
1146+
AnalyticsTableUpdateParams.newBuilder()
1147+
.lastYears(2)
1148+
.startTime(START_TIME)
1149+
.today(today)
1150+
.skipPrograms(skipPrograms)
1151+
.build();
1152+
1153+
when(idObjectManager.getAllNoAcl(Program.class)).thenReturn(List.of(prA, prB, prC, prD));
1154+
mockPeriodYears(List.of(2018, 2019, now().getYear()));
1155+
whenConfigurationPeriodSettings();
1156+
when(jdbcTemplate.queryForList(Mockito.anyString(), Mockito.eq(Integer.class)))
1157+
.thenReturn(List.of(2018, 2019));
1158+
1159+
List<AnalyticsTable> tables = subject.getAnalyticsTables(params);
1160+
1161+
assertThat(tables, hasSize(2));
1162+
1163+
List<String> programUids = tables.stream().map(t -> t.getProgram().getUid()).toList();
1164+
assertThat(programUids, not(hasItem(prC.getUid())));
1165+
assertThat(programUids, not(hasItem(prD.getUid())));
1166+
}
1167+
10941168
private String toSelectExpression(String template, String uid) {
10951169
return String.format(template, uid, uid, uid);
10961170
}

0 commit comments

Comments
 (0)