Skip to content

Commit fc5efcb

Browse files
authored
update jooq codegen to 26.02.17-RC01 (#1656)
- this time using Oracle 19C to generate the codegen - This contains some bug fixes for fragile exception handling that has changed between ojdbc8 and ojdbc11 - replaced the hand-copied codegen jars with a shaded version of the previous codegen jar used explicitly for the water supply accounting UDT's
1 parent 1c89464 commit fc5efcb

14 files changed

+424
-750
lines changed

cwms-data-api/build.gradle

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ plugins {
77
id 'war'
88
id 'com.github.node-gradle.node' version '7.1.0'
99
id "org.openapi.generator" version "7.15.0"
10+
id 'com.gradleup.shadow' version '8.3.10'
1011
}
1112

1213
configurations {
@@ -16,6 +17,7 @@ configurations {
1617
baseLibs
1718
tomcatLibs
1819
testImplementation.extendsFrom(tomcatLibs)
20+
jooqCodegenShadow
1921
}
2022

2123
configurations.implementation {
@@ -43,7 +45,24 @@ dependencies {
4345
exclude group: "log4j", module: "log4j"
4446
exclude group: "org.slf4j", module: "slf4j-log4j12"
4547
exclude group: "org.jooq.pro-java-8", module: "jooq"
48+
exclude group: "org.jooq.pro-java-11", module: "jooq"
4649
}
50+
//Adding a shaded version of the previous schemas codegen
51+
//Due to the way jOOQ generates UDT's, any changes to members of the UDT
52+
//means it is not backwards compatible (the bind indexes get messed up)
53+
//We could also use this mechanism to shade a 'latest' version of the schema codegen
54+
//to allow for work not yet merged into a schema release/rc
55+
jooqCodegenShadow(libs.cwms.db.jooq.codegen.shadow) {
56+
exclude group: "com.oracle", module: "*"
57+
exclude group: "com.oracle.database.jdbc", module: "*"
58+
exclude group: "org.jooq.pro", module: "*"
59+
exclude group: "org.jooq", module: "jooq"
60+
exclude group: "log4j", module: "log4j"
61+
exclude group: "org.slf4j", module: "slf4j-log4j12"
62+
exclude group: "org.jooq.pro-java-8", module: "jooq"
63+
exclude group: "org.jooq.pro-java-11", module: "jooq"
64+
}
65+
implementation(files("$buildDir/libs/${project.name}-${project.version}-codegen-shadow.jar"))
4766

4867
implementation(libs.slf4j)
4968

@@ -71,6 +90,7 @@ dependencies {
7190
implementation(libs.cwms.ratings.io.xml)
7291
implementation(libs.cwms.ratings.io.jdbc) {
7392
exclude group: "mil.army.usace.hec", module: "cwms-db-jooq-codegen"
93+
exclude group: "org.jooq.pro-java-11", module: "jooq"
7494
}
7595

7696
implementation(libs.jooq) {
@@ -381,4 +401,14 @@ if (JavaVersion.current() >= JavaVersion.VERSION_11) {
381401
node {
382402
nodeProjectDir = file("$rootDir/cda-client/")
383403
}
384-
}
404+
}
405+
406+
tasks.register('shadeCodegen', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
407+
archiveClassifier.set('codegen-shadow')
408+
configurations = [project.configurations.jooqCodegenShadow]
409+
//See comment above on why shading is needed. Using 'codegen_shadow' as a
410+
//suitably obnoxious package name so that imports don't get confused.
411+
//We can also shade a 'codegen_latest' in the future if needed.
412+
relocate 'usace.cwms.db.jooq.codegen', 'usace.cwms.db.jooq.codegen_shadow'
413+
}
414+
tasks.compileJava.dependsOn(tasks.shadeCodegen)

cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
import java.sql.PreparedStatement;
2626
import java.sql.ResultSet;
2727
import java.sql.SQLException;
28+
import java.sql.Timestamp;
2829
import java.sql.Types;
2930
import java.time.ZoneId;
31+
import java.time.ZoneOffset;
3032
import java.time.ZonedDateTime;
3133
import java.util.ArrayList;
3234
import java.util.Calendar;
@@ -492,8 +494,15 @@ public ApiKey apiKeyForUser(DataApiPrincipal p, String keyName) {
492494
private static ApiKey rs2ApiKey(ResultSet rs) throws SQLException {
493495
String userId = rs.getString("userid");
494496
String keyName = rs.getString("key_name");
495-
ZonedDateTime created = rs.getObject("created",ZonedDateTime.class);
496-
ZonedDateTime expires = rs.getObject("expires",ZonedDateTime.class);
497+
498+
ZonedDateTime created = Optional.ofNullable(rs.getObject("created", Timestamp.class))
499+
.map(Timestamp::toInstant)
500+
.map(i -> i.atZone(ZoneOffset.UTC))
501+
.orElse(null);
502+
ZonedDateTime expires = Optional.ofNullable(rs.getObject("expires", Timestamp.class))
503+
.map(Timestamp::toInstant)
504+
.map(i -> i.atZone(ZoneOffset.UTC))
505+
.orElse(null);
497506
return new ApiKey(userId,keyName,null,created,expires);
498507
}
499508

cwms-data-api/src/main/java/cwms/cda/data/dao/JooqDao.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,14 @@ public abstract class JooqDao<T> extends Dao<T> {
8989
private static final Pattern INVALID_OFFICE_ID = Pattern.compile(
9090
"INVALID_OFFICE_ID: \"([^\"]+)\" is not a valid CWMS office id");
9191
private static final Pattern INVALID_UNIT = Pattern.compile(
92-
"(.+\\R+){6}ORA-20102: The unit: \\S+"
93-
+ " is not a recognized CWMS Database unit for the .+(.+\\R+){10}");
92+
"ORA-20102: The unit: \\S+"
93+
+ " is not a recognized CWMS Database unit for the");
9494
private static final Pattern CONVERSION_ERROR = Pattern.compile(
9595
"^ORA-20998: ERROR: Cannot convert ((parameter .+ from specified units: .+$)"
9696
+ "|(from unit .+ to unit .+$))");
9797
private static final Pattern FIELD_LENGTH_EXCEEDED = Pattern.compile(
98-
"^ORA-12899: value too large for column \".+\"\\.\".+\"\\.\"(.+)\" "
99-
+ "\\(actual: (\\d+), maximum: (\\d+)\\)\\R*$");
98+
"ORA-12899: value too large for column \".+\"\\.\".+\"\\.\"(.+)\" "
99+
+ "\\(actual: (\\d+), maximum: (\\d+)\\)");
100100

101101
public enum DeleteMethod {
102102
DELETE_ALL(DeleteRule.DELETE_ALL),
@@ -389,7 +389,7 @@ public static boolean isInvalidOffice(RuntimeException input) {
389389

390390
public static boolean isValueTooLargeException(RuntimeException input) {
391391
return getSqlException(input.getCause()).map(sqlException -> hasCodeOrMessage(sqlException,
392-
Arrays.asList(6502, 12899, 20041),
392+
Arrays.asList(6502, 12899, 20041, 17072),
393393
Arrays.asList("value too large for column", "character string buffer too small",
394394
"Error while writing value at JDBC bind index:")))
395395
.orElse(false);
@@ -597,7 +597,7 @@ public static boolean isInvalidUnits(RuntimeException input) {
597597
SQLException sqlException = optional.get();
598598
String message = sqlException.getLocalizedMessage();
599599

600-
if (INVALID_UNIT.matcher(message).matches()) {
600+
if (INVALID_UNIT.matcher(message).find()) {
601601
retVal = true;
602602
}
603603

@@ -677,7 +677,7 @@ private static FieldLengthExceededException buildFieldLengthExceededException(Ru
677677

678678
if (localizedMessage != null) {
679679
Matcher matcher = FIELD_LENGTH_EXCEEDED.matcher(localizedMessage);
680-
if (matcher.matches()) {
680+
if (matcher.find()) {
681681
String parameter = matcher.group(1);
682682
int actualLength = Integer.parseInt(matcher.group(2));
683683
int maxLength = Integer.parseInt(matcher.group(3));

cwms-data-api/src/main/java/cwms/cda/data/dao/rss/MessageUtil.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ static Optional<String> extractPayload(Object userData) {
104104
}
105105
try {
106106
Struct struct = (Struct) userData;
107-
String oracleType = struct.getSQLTypeName();
108-
if (oracleType.endsWith("JMS_TEXT_MESSAGE")) {
107+
String oracleType = struct.getSQLTypeName().replace("\"", "");
108+
if (oracleType.contains("JMS_TEXT_MESSAGE")) {
109109
return Optional.ofNullable(extractTextMessage(userData));
110110
}
111-
if (oracleType.endsWith("JMS_MAP_MESSAGE")) {
111+
if (oracleType.contains("JMS_MAP_MESSAGE")) {
112112
Map<?, ?> map = extractMapMessage(userData);
113113
return Optional.ofNullable(MAPPER.writeValueAsString(map)); // JACKSON HERE
114114
}

cwms-data-api/src/main/java/cwms/cda/data/dao/watersupply/WaterSupplyAccountingDao.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ private static boolean isBindException(DataAccessException e) {
8686
SQLException se = (SQLException)cause;
8787
String sqlMessage = se.getMessage();
8888
Throwable sqlCause = se.getCause();
89-
isBind = sqlCause instanceof IllegalArgumentException && sqlMessage.contains("Error while writing value");
89+
isBind = (sqlCause instanceof IllegalArgumentException || sqlCause instanceof ArrayIndexOutOfBoundsException)
90+
&& sqlMessage.contains("Error while writing value");
9091
}
9192
return isBind;
9293
}
@@ -103,13 +104,12 @@ private static void storeViaCodegen(Connection c, WaterSupplyAccounting accounti
103104
}
104105

105106
private static void storeViaManual(Connection c, WaterSupplyAccounting accounting, boolean overrideProtection, String volumeUnitId, String storeRule) {
106-
cwms.cda.data.dao.watersupply.handgen.records.WAT_USR_CONTRACT_ACCT_TAB_T accountingTab = WaterSupplyUtils.toManualWaterUserContractAcctTs(accounting);
107-
WATER_USER_CONTRACT_REF_T contractRefT = WaterSupplyUtils
108-
.toContractRef(accounting.getWaterUser(), accounting.getContractName());
109-
LOC_REF_TIME_WINDOW_TAB_T pumpTimeWindowTab = WaterSupplyUtils.toTimeWindowTabT(accounting);
107+
var accountingTab = WaterSupplyUtilsShadow.toManualWaterUserContractAcctTs(accounting);
108+
var contractRefT = WaterSupplyUtilsShadow .toContractRef(accounting.getWaterUser(), accounting.getContractName());
109+
var pumpTimeWindowTab = WaterSupplyUtilsShadow.toTimeWindowTabT(accounting);
110110
String timeZoneId = "UTC";
111111
String overrideProt = formatBool(overrideProtection);
112-
cwms.cda.data.dao.watersupply.handgen.CWMS_WATER_SUPPLY_PACKAGE.call_STORE_ACCOUNTING_SET(DSL.using(c).configuration(), accountingTab,
112+
usace.cwms.db.jooq.codegen_shadow.packages.CWMS_WATER_SUPPLY_PACKAGE.call_STORE_ACCOUNTING_SET(DSL.using(c).configuration(), accountingTab,
113113
contractRefT, pumpTimeWindowTab, timeZoneId, volumeUnitId, storeRule, overrideProt);
114114
}
115115

@@ -118,7 +118,6 @@ public List<WaterSupplyAccounting> retrieveAccounting(String contractName, Water
118118
boolean startInclusive, boolean endInclusive, boolean ascendingFlag, int rowLimit) {
119119

120120
String transferType = null;
121-
WATER_USER_CONTRACT_REF_T contractRefT = WaterSupplyUtils.toContractRef(waterUser, contractName);
122121
Timestamp startTimestamp = Timestamp.from(startTime);
123122
Timestamp endTimestamp = Timestamp.from(endTime);
124123
String timeZoneId = "UTC";
@@ -130,23 +129,25 @@ public List<WaterSupplyAccounting> retrieveAccounting(String contractName, Water
130129
return connectionResult(dsl, c -> {
131130
setOffice(c, projectLocation.getOfficeId());
132131
try {
132+
var contractRefT = WaterSupplyUtils.toContractRef(waterUser, contractName);
133133
return retrieveFromCodegen(units, c, contractRefT, startTimestamp, endTimestamp, timeZoneId, startInclusiveFlag, endInclusiveFlag, ascendingFlagStr, rowLimitBigInt, transferType);
134134
} catch (DataAccessException e){
135135
if(isInvalidColumn(e)){
136-
return retrieveViaManual(units, c, contractRefT, startTimestamp, endTimestamp, timeZoneId, startInclusiveFlag, endInclusiveFlag, ascendingFlagStr, rowLimitBigInt, transferType);
136+
var contractRefT = WaterSupplyUtilsShadow.toContractRef(waterUser, contractName);
137+
return retrieveViaManual(units, c, contractRefT, startTimestamp, endTimestamp, timeZoneId, startInclusiveFlag, endInclusiveFlag, ascendingFlagStr, rowLimitBigInt, transferType);
137138
}
138139
throw e;
139140
}
140141
});
141142
}
142143

143-
private @NonNull List<WaterSupplyAccounting> retrieveViaManual(String units, Connection c, WATER_USER_CONTRACT_REF_T contractRefT, Timestamp startTimestamp, Timestamp endTimestamp, String timeZoneId, String startInclusiveFlag, String endInclusiveFlag, String ascendingFlagStr, BigInteger rowLimitBigInt, String transferType) {
144-
cwms.cda.data.dao.watersupply.handgen.records.WAT_USR_CONTRACT_ACCT_TAB_T watUsrContractAcctObjTs
145-
= cwms.cda.data.dao.watersupply.handgen.CWMS_WATER_SUPPLY_PACKAGE.call_RETRIEVE_ACCOUNTING_SET(DSL.using(c).configuration(),
144+
private @NonNull List<WaterSupplyAccounting> retrieveViaManual(String units, Connection c, usace.cwms.db.jooq.codegen_shadow.udt.records.WATER_USER_CONTRACT_REF_T contractRefT, Timestamp startTimestamp, Timestamp endTimestamp, String timeZoneId, String startInclusiveFlag, String endInclusiveFlag, String ascendingFlagStr, BigInteger rowLimitBigInt, String transferType) {
145+
usace.cwms.db.jooq.codegen_shadow.udt.records.WAT_USR_CONTRACT_ACCT_TAB_T watUsrContractAcctObjTs
146+
= usace.cwms.db.jooq.codegen_shadow.packages.CWMS_WATER_SUPPLY_PACKAGE.call_RETRIEVE_ACCOUNTING_SET(DSL.using(c).configuration(),
146147
contractRefT, units, startTimestamp, endTimestamp, timeZoneId, startInclusiveFlag,
147148
endInclusiveFlag, ascendingFlagStr, rowLimitBigInt, transferType);
148149
if (!watUsrContractAcctObjTs.isEmpty()) {
149-
return WaterSupplyUtils.toWaterSupplyAccountingList(c, watUsrContractAcctObjTs);
150+
return WaterSupplyUtilsShadow.toWaterSupplyAccountingList(c, watUsrContractAcctObjTs, units);
150151
} else {
151152
return new ArrayList<>();
152153
}
@@ -171,7 +172,7 @@ private boolean isInvalidColumn(DataAccessException e) {
171172
contractRefT, units, startTimestamp, endTimestamp, timeZoneId, startInclusiveFlag,
172173
endInclusiveFlag, ascendingFlagStr, rowLimitBigInt, transferType);
173174
if (!watUsrContractAcctObjTs.isEmpty()) {
174-
return WaterSupplyUtils.toWaterSupplyAccountingList(c, watUsrContractAcctObjTs, units);
175+
return WaterSupplyUtils.toWaterSupplyAccountingList(c, watUsrContractAcctObjTs);
175176
} else {
176177
return new ArrayList<>();
177178
}

0 commit comments

Comments
 (0)