Skip to content

Commit 2e69ccf

Browse files
Notice table names that we don't handle yet
Adds a new exception to look for (a subclass of SQLException, so no interfaces are changed yet), and stops trying to deal with tables that we don't handle (looking at you, `repcap`).
1 parent fb2f4ee commit 2e69ccf

File tree

3 files changed

+86
-52
lines changed

3 files changed

+86
-52
lines changed

proxyserver/src/main/java/edu/suffolk/litlab/efsp/ecfcodes/CodeUpdater.java

Lines changed: 66 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import edu.suffolk.litlab.efsp.db.DatabaseCreator;
44
import edu.suffolk.litlab.efsp.ecfcodes.tyler.CodeDatabase;
5+
import edu.suffolk.litlab.efsp.ecfcodes.tyler.CodeTableConstants.UnsupportedTableException;
56
import edu.suffolk.litlab.efsp.server.ecf4.Ecf4Helper;
67
import edu.suffolk.litlab.efsp.server.ecf4.SoapClientChooser;
78
import edu.suffolk.litlab.efsp.server.utils.HeaderSigner;
@@ -25,15 +26,14 @@
2526
import java.net.URL;
2627
import java.sql.SQLException;
2728
import java.sql.Savepoint;
28-
import java.time.Clock;
2929
import java.time.Duration;
3030
import java.time.Instant;
31+
import java.util.HashMap;
3132
import java.util.HashSet;
3233
import java.util.List;
3334
import java.util.Map;
3435
import java.util.Map.Entry;
3536
import java.util.Optional;
36-
import java.util.Set;
3737
import java.util.concurrent.ConcurrentHashMap;
3838
import java.util.function.Function;
3939
import java.util.function.Supplier;
@@ -176,19 +176,17 @@ public static InputStream getCodesZip(String toRead, String authHeader) throws I
176176
*/
177177
private boolean downloadAndProcessZip(
178178
String toRead, String signedTime, Function<InputStream, Boolean> process) {
179-
Instant startTable = Instant.now(Clock.systemUTC());
179+
Instant startTable = Instant.now();
180180
try (InputStream urlStream = getCodesZip(toRead, signedTime)) {
181181
// Write out the zip file
182-
downloadDuration =
183-
downloadDuration.plus(Duration.between(startTable, Instant.now(Clock.systemUTC())));
182+
downloadDuration = downloadDuration.plus(Duration.between(startTable, Instant.now()));
184183

185184
ZipInputStream zip = new ZipInputStream(urlStream);
186185
zip.getNextEntry();
187186

188-
Instant updateTableLoc = Instant.now(Clock.systemUTC());
187+
Instant updateTableLoc = Instant.now();
189188
boolean success = process.apply(zip);
190-
updateDuration =
191-
updateDuration.plus(Duration.between(updateTableLoc, Instant.now(Clock.systemUTC())));
189+
updateDuration = updateDuration.plus(Duration.between(updateTableLoc, Instant.now()));
192190
zip.close();
193191
return success;
194192
} catch (IOException ex) {
@@ -234,6 +232,8 @@ private boolean downloadSystemTables(String baseUrl, CodeDatabaseAPI cd, HeaderS
234232
}
235233

236234
for (Map.Entry<String, String> urlSuffix : codeUrls.entrySet()) {
235+
// Let SQL exceptions through here; table names are hard coded, so if they break
236+
// we need to know.
237237
cd.deleteFromTable(urlSuffix.getKey());
238238
final Function<InputStream, Boolean> process =
239239
(is) -> {
@@ -348,7 +348,7 @@ private boolean downloadCourtTables(
348348
throws JAXBException, IOException, SQLException {
349349
MDC.put(MDCWrappers.SESSION_ID, location);
350350
log.info("Doing updates for: {}, tables: {}", location, tables);
351-
Instant downloadStart = Instant.now(Clock.systemUTC());
351+
Instant downloadStart = Instant.now();
352352
// TODO(brycew-later): check that the effective date is later than today
353353
// JAXBElement<?> obj = ccl.getEffectiveDate().getDateRepresentation();
354354
Map<String, String> urlMap =
@@ -383,12 +383,12 @@ private boolean downloadCourtTables(
383383
}
384384
Map<String, DownloadedCodes> downloaded =
385385
streamDownload(signedTime.get(), location, toDownload.parallel(), tables);
386-
var downloadInc = Duration.between(downloadStart, Instant.now(Clock.systemUTC()));
386+
var downloadInc = Duration.between(downloadStart, Instant.now());
387387
downloadDuration = downloadDuration.plus(downloadInc);
388388
log.info(
389389
"Location: {}: Downloads took: {} (total: {})", location, downloadInc, downloadDuration);
390390

391-
Instant updateStart = Instant.now(Clock.systemUTC());
391+
Instant updateStart = Instant.now();
392392
for (DownloadedCodes down : downloaded.values()) {
393393
MDC.put(MDCWrappers.REQUEST_ID, down.tableName());
394394
try {
@@ -400,7 +400,7 @@ private boolean downloadCourtTables(
400400
down.input().close();
401401
}
402402
}
403-
var updateInc = Duration.between(updateStart, Instant.now(Clock.systemUTC()));
403+
var updateInc = Duration.between(updateStart, Instant.now());
404404
updateDuration = updateDuration.plus(updateInc);
405405

406406
cd.commit();
@@ -410,6 +410,45 @@ private boolean downloadCourtTables(
410410
return true;
411411
}
412412

413+
/**
414+
* Creates all of the tables to update. If it can't create them, it removes them from the list.
415+
*/
416+
private Map<String, List<String>> makeOrRemoveUnsupportedTables(
417+
Map<String, List<String>> versionsToUpdate, CodeDatabaseAPI cd) throws SQLException {
418+
var allTables = new HashSet<String>();
419+
log.info("Making tables (if any are absent)");
420+
for (var tables : versionsToUpdate.values()) {
421+
allTables.addAll(tables);
422+
}
423+
424+
var brokenTables = new HashSet<String>();
425+
for (String table : allTables) {
426+
try {
427+
cd.createTableIfAbsent(table);
428+
} catch (UnsupportedTableException ex) {
429+
log.warn("Ignoring table {} from Tyler's report (not in our allow list)", table);
430+
brokenTables.add(table);
431+
}
432+
}
433+
434+
var toReturn = new HashMap<String, List<String>>();
435+
for (var courtAndTables : versionsToUpdate.entrySet()) {
436+
String courtLocation = courtAndTables.getKey();
437+
if (courtLocation.isBlank()) {
438+
log.warn("Ignoring tables with an empty court!");
439+
continue;
440+
}
441+
List<String> tables = courtAndTables.getValue();
442+
tables.removeAll(brokenTables);
443+
if (tables.isEmpty()) {
444+
continue;
445+
}
446+
toReturn.put(courtLocation, tables);
447+
}
448+
449+
return toReturn;
450+
}
451+
413452
/** Returns true if successful, false if not successful */
414453
public boolean updateAll(String baseUrl, FilingReviewMDEPort filingPort, CodeDatabaseAPI cd)
415454
throws SQLException, IOException, JAXBException {
@@ -424,49 +463,36 @@ public boolean updateAll(String baseUrl, FilingReviewMDEPort filingPort, CodeDat
424463

425464
// Drop each of tables that need to be updated
426465
Savepoint sp = cd.setSavepoint("court update savepoint");
427-
Map<String, List<String>> versionsToUpdate = cd.getVersionsToUpdate();
428-
Instant startDel = Instant.now(Clock.systemUTC());
429-
Set<String> allTables = new HashSet<>();
430-
int n = 0;
431-
log.info("Making tables if absent");
432-
for (var tables : versionsToUpdate.values()) {
433-
n += tables.size();
434-
allTables.addAll(tables);
435-
}
436-
for (String table : allTables) {
437-
cd.createTableIfAbsent(table);
438-
}
439-
log.info("Removing {} court entries, over {} queries", versionsToUpdate.size(), n);
466+
Map<String, List<String>> rawVersionsToUpdate = cd.getVersionsToUpdate();
467+
Map<String, List<String>> versionsToUpdate =
468+
makeOrRemoveUnsupportedTables(rawVersionsToUpdate, cd);
469+
Instant startDel = Instant.now();
470+
log.info(
471+
"Removing {} court entries, over {} queries",
472+
versionsToUpdate.size(),
473+
versionsToUpdate.values().stream().map(List::size).reduce(0, (a, b) -> a + b));
440474
for (Entry<String, List<String>> courtAndTables : versionsToUpdate.entrySet()) {
441475
final String courtLocation = courtAndTables.getKey();
442-
if (courtLocation.isBlank()) {
443-
log.warn("Ignoring tables with an empty court!");
444-
continue;
445-
}
446476
List<String> tables = courtAndTables.getValue();
447477
log.debug(
448478
"In {}, removing entries for court {} for tables: {}",
449479
cd.getDomain(),
450480
courtLocation,
451481
tables);
452482
for (String table : tables) {
453-
Instant deleteFromTable = Instant.now(Clock.systemUTC());
483+
Instant delTime = Instant.now();
454484

455-
// No longer checking for false here -- see PR.
456485
// Will ignore tables that don't exist.
457486
cd.deleteFromTable(table, courtLocation);
458487

459-
updateDuration =
460-
updateDuration.plus(Duration.between(deleteFromTable, Instant.now(Clock.systemUTC())));
488+
updateDuration = updateDuration.plus(Duration.between(delTime, Instant.now()));
461489
}
462490
}
463-
log.info(
464-
"Took {} to remove existing tables",
465-
Duration.between(startDel, Instant.now(Clock.systemUTC())));
466-
Instant startPolicy = Instant.now(Clock.systemUTC());
491+
log.info("Took {} to remove existing tables", Duration.between(startDel, Instant.now()));
492+
Instant startPolicy = Instant.now();
467493
Map<String, CourtPolicyResponseMessageType> policies =
468494
streamPolicies(versionsToUpdate.keySet().stream().parallel(), cd.getDomain(), filingPort);
469-
var soapInc = Duration.between(startPolicy, Instant.now(Clock.systemUTC()));
495+
var soapInc = Duration.between(startPolicy, Instant.now());
470496
soapDuration = soapDuration.plus(soapInc);
471497
log.info("Soaps took: {} (total: {})", soapInc, soapDuration);
472498

@@ -517,10 +543,10 @@ public boolean replaceSome(
517543
}
518544
// Remove the "0" or top level court, which doesn't usually have individual court tables
519545
locs.remove("0");
520-
Instant startPolicy = Instant.now(Clock.systemUTC());
546+
Instant startPolicy = Instant.now();
521547
Map<String, CourtPolicyResponseMessageType> policies =
522548
streamPolicies(locs.stream(), cd.getDomain(), filingPort);
523-
soapDuration = soapDuration.plus(Duration.between(startPolicy, Instant.now(Clock.systemUTC())));
549+
soapDuration = soapDuration.plus(Duration.between(startPolicy, Instant.now()));
524550
log.info("Soaps: {}", soapDuration);
525551
for (var policy : policies.entrySet()) {
526552
final String location = policy.getKey();

proxyserver/src/main/java/edu/suffolk/litlab/efsp/ecfcodes/tyler/CodeDatabase.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package edu.suffolk.litlab.efsp.ecfcodes.tyler;
22

33
import edu.suffolk.litlab.efsp.ecfcodes.CodeDatabaseAPI;
4+
import edu.suffolk.litlab.efsp.ecfcodes.tyler.CodeTableConstants.UnsupportedTableException;
45
import edu.suffolk.litlab.efsp.stdlib.SQLFunction;
56
import edu.suffolk.litlab.efsp.tyler.TylerEnv;
67
import jakarta.xml.bind.JAXBException;
@@ -106,10 +107,6 @@ public void createTableIfAbsent(String tableName) throws SQLException {
106107
OptionalServiceCode.createFromOptionalServiceTable(conn);
107108
} else {
108109
String createQuery = CodeTableConstants.getCreateTable(tableName);
109-
if (createQuery.isEmpty()) {
110-
log.warn("Will not create table with name: {}", tableName);
111-
return;
112-
}
113110
try (Statement createSt = conn.createStatement()) {
114111
log.info("Full statement: {}", createQuery);
115112
createSt.executeUpdate(createQuery);
@@ -190,6 +187,9 @@ public void updateTable(
190187
update.setString(4, tylerDomain);
191188
update.setString(5, newVersion);
192189
update.executeUpdate();
190+
} catch (UnsupportedTableException ex) {
191+
log.error("Silently ignoring a missing table exception.", ex);
192+
return;
193193
} catch (SQLException ex) {
194194
log.error("Tried to execute an insert, but failed! Exception", ex);
195195
log.error("Going to rollback updates to this table");

proxyserver/src/main/java/edu/suffolk/litlab/efsp/ecfcodes/tyler/CodeTableConstants.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package edu.suffolk.litlab.efsp.ecfcodes.tyler;
22

3+
import java.sql.SQLException;
34
import java.util.ArrayList;
45
import java.util.HashMap;
56
import java.util.List;
@@ -451,15 +452,22 @@ public static String vacuumAnalyzeAll() {
451452
return "VACUUM ANALYZE";
452453
}
453454

455+
/** This exception is returned when a given table name isn't in the pre-approved list of names. */
456+
public static class UnsupportedTableException extends SQLException {
457+
public UnsupportedTableException(String message) {
458+
super(message);
459+
}
460+
}
461+
454462
public static boolean tableHasLocation(String tableName) {
455463
return tableColumns.containsKey(tableName) && tableColumns.get(tableName).needsExtraLocCol;
456464
}
457465

458-
public static String getCreateTable(String tableName) {
466+
public static String getCreateTable(String tableName) throws UnsupportedTableException {
459467
if (createQueries.containsKey(tableName)) {
460468
return createQueries.get(tableName);
461469
}
462-
return "";
470+
throw new UnsupportedTableException("No create query for table " + tableName);
463471
}
464472

465473
public static List<String> getCreateIndex(String tableName) {
@@ -469,23 +477,23 @@ public static List<String> getCreateIndex(String tableName) {
469477
return tableIndices.get(tableName);
470478
}
471479

472-
public static String getInsertInto(String tableName) {
480+
public static String getInsertInto(String tableName) throws UnsupportedTableException {
473481
if (!insertQueries.containsKey(tableName)) {
474-
return "";
482+
throw new UnsupportedTableException("No insert query for table " + tableName);
475483
}
476484
return insertQueries.get(tableName);
477485
}
478486

479-
public static String getDeleteFrom(String tableName) {
487+
public static String getDeleteFrom(String tableName) throws UnsupportedTableException {
480488
if (!deleteFromQueries.containsKey(tableName)) {
481-
return "";
489+
throw new UnsupportedTableException("No 'delete from' query for table " + tableName);
482490
}
483491
return deleteFromQueries.get(tableName);
484492
}
485493

486-
public static String getDeleteAllCourtsFrom(String tableName) {
494+
public static String getDeleteAllCourtsFrom(String tableName) throws UnsupportedTableException {
487495
if (!deleteAllCourtsFromQueries.containsKey(tableName)) {
488-
return "";
496+
throw new UnsupportedTableException("No 'delete all courts from' query for table " + tableName);
489497
}
490498
return deleteAllCourtsFromQueries.get(tableName);
491499
}

0 commit comments

Comments
 (0)