Skip to content

Commit ffebdaa

Browse files
authored
Merge pull request #51383 from michalvavrik/feature/configurable-oidc-db-state-man-col-size
Allow to configure OIDC DB token state manager column sizes for tokens
2 parents 9c4c8c4 + 53cc419 commit ffebdaa

File tree

4 files changed

+126
-91
lines changed

4 files changed

+126
-91
lines changed

extensions/oidc-db-token-state-manager/deployment/src/main/java/io/quarkus/oidc/db/token/state/manager/OidcDbTokenStateManagerProcessor.java

Lines changed: 12 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212
import java.util.function.BooleanSupplier;
1313

14-
import jakarta.enterprise.context.Dependent;
1514
import jakarta.inject.Singleton;
1615

1716
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
1817
import io.quarkus.arc.deployment.BeanContainerBuildItem;
18+
import io.quarkus.arc.deployment.BeanContainerListenerBuildItem;
1919
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
2020
import io.quarkus.arc.deployment.SyntheticBeansRuntimeInitBuildItem;
2121
import io.quarkus.builder.item.SimpleBuildItem;
@@ -27,7 +27,7 @@
2727
import io.quarkus.oidc.TokenStateManager;
2828
import io.quarkus.oidc.db.token.state.manager.runtime.OidcDbTokenStateManager;
2929
import io.quarkus.oidc.db.token.state.manager.runtime.OidcDbTokenStateManagerInitializer;
30-
import io.quarkus.oidc.db.token.state.manager.runtime.OidcDbTokenStateManagerInitializer.OidcDbTokenStateManagerInitializerProperties;
30+
import io.quarkus.oidc.db.token.state.manager.runtime.OidcDbTokenStateManagerInitializer.SupportedReactiveSqlClient;
3131
import io.quarkus.oidc.db.token.state.manager.runtime.OidcDbTokenStateManagerRecorder;
3232
import io.quarkus.runtime.configuration.ConfigurationException;
3333

@@ -109,77 +109,17 @@ AdditionalBeanBuildItem makeDbTokenStateManagerInitializerBean() {
109109

110110
@BuildStep
111111
@Record(STATIC_INIT)
112-
SyntheticBeanBuildItem createDbTokenStateInitializerProps(ReactiveSqlClientBuildItem sqlClientBuildItem,
112+
BeanContainerListenerBuildItem createDbTokenStateInitializerProps(ReactiveSqlClientBuildItem sqlClientBuildItem,
113113
OidcDbTokenStateManagerRecorder recorder) {
114-
final String createTableDdl;
115-
final boolean supportsIfTableNotExists;
116-
switch (sqlClientBuildItem.reactiveClient) {
117-
case REACTIVE_PG_CLIENT:
118-
createTableDdl = "CREATE TABLE IF NOT EXISTS oidc_db_token_state_manager (" +
119-
"id VARCHAR(100) PRIMARY KEY, " +
120-
"id_token VARCHAR, " +
121-
"access_token VARCHAR, " +
122-
"refresh_token VARCHAR, " +
123-
"access_token_expires_in BIGINT, " +
124-
"access_token_scope VARCHAR, " +
125-
"expires_in BIGINT NOT NULL)";
126-
supportsIfTableNotExists = true;
127-
break;
128-
case REACTIVE_MYSQL_CLIENT:
129-
createTableDdl = "CREATE TABLE IF NOT EXISTS oidc_db_token_state_manager ("
130-
+ "id VARCHAR(100), "
131-
+ "id_token VARCHAR(5000) NULL, "
132-
+ "access_token VARCHAR(5000) NULL, "
133-
+ "refresh_token VARCHAR(5000) NULL, "
134-
+ "access_token_expires_in BIGINT NULL, "
135-
+ "access_token_scope VARCHAR(100) NULL, "
136-
+ "expires_in BIGINT NOT NULL, "
137-
+ "PRIMARY KEY (id))";
138-
supportsIfTableNotExists = true;
139-
break;
140-
case REACTIVE_MSSQL_CLIENT:
141-
createTableDdl = "CREATE TABLE oidc_db_token_state_manager ("
142-
+ "id NVARCHAR(100) PRIMARY KEY, "
143-
+ "id_token NVARCHAR(MAX), "
144-
+ "access_token NVARCHAR(MAX), "
145-
+ "refresh_token NVARCHAR(MAX), "
146-
+ "access_token_expires_in BIGINT, "
147-
+ "access_token_scope NVARCHAR(100), "
148-
+ "expires_in BIGINT NOT NULL)";
149-
supportsIfTableNotExists = false;
150-
break;
151-
case REACTIVE_DB2_CLIENT:
152-
createTableDdl = "CREATE TABLE oidc_db_token_state_manager ("
153-
+ "id VARCHAR(100) NOT NULL PRIMARY KEY, "
154-
+ "id_token VARCHAR(5000), "
155-
+ "access_token VARCHAR(5000), "
156-
+ "refresh_token VARCHAR(5000), "
157-
+ "access_token_expires_in BIGINT, "
158-
+ "access_token_scope VARCHAR(100), "
159-
+ "expires_in BIGINT NOT NULL)";
160-
supportsIfTableNotExists = false;
161-
break;
162-
case REACTIVE_ORACLE_CLIENT:
163-
createTableDdl = "CREATE TABLE IF NOT EXISTS oidc_db_token_state_manager ("
164-
+ "id VARCHAR2(100), "
165-
+ "id_token VARCHAR2(5000), "
166-
+ "access_token VARCHAR2(5000), "
167-
+ "refresh_token VARCHAR2(5000), "
168-
+ "access_token_expires_in NUMBER, "
169-
+ "access_token_scope VARCHAR2(100), "
170-
+ "expires_in NUMBER NOT NULL, "
171-
+ "PRIMARY KEY (id))";
172-
supportsIfTableNotExists = true;
173-
break;
174-
default:
175-
throw new ConfigurationException("Unknown Reactive Sql Client " + sqlClientBuildItem.reactiveClient);
176-
}
177-
return SyntheticBeanBuildItem
178-
.configure(OidcDbTokenStateManagerInitializerProperties.class)
179-
.supplier(recorder.createDbTokenStateInitializerProps(createTableDdl, supportsIfTableNotExists))
180-
.unremovable()
181-
.scope(Dependent.class)
182-
.done();
114+
var supportedReactiveSqlClient = switch (sqlClientBuildItem.reactiveClient) {
115+
case REACTIVE_PG_CLIENT -> SupportedReactiveSqlClient.POSTGRESQL;
116+
case REACTIVE_MYSQL_CLIENT -> SupportedReactiveSqlClient.MYSQL;
117+
case REACTIVE_MSSQL_CLIENT -> SupportedReactiveSqlClient.MSSQL;
118+
case REACTIVE_DB2_CLIENT -> SupportedReactiveSqlClient.DB2;
119+
case REACTIVE_ORACLE_CLIENT -> SupportedReactiveSqlClient.ORACLE;
120+
default -> throw new ConfigurationException("Unknown Reactive Sql Client " + sqlClientBuildItem.reactiveClient);
121+
};
122+
return new BeanContainerListenerBuildItem(recorder.setSupportedReactiveSqlClient(supportedReactiveSqlClient));
183123
}
184124

185125
@Consume(SyntheticBeansRuntimeInitBuildItem.class)

extensions/oidc-db-token-state-manager/runtime/src/main/java/io/quarkus/oidc/db/token/state/manager/runtime/OidcDbTokenStateManagerInitializer.java

Lines changed: 91 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
import static io.quarkus.oidc.db.token.state.manager.runtime.OidcDbTokenStateManager.now;
44

5+
import java.util.Objects;
56
import java.util.concurrent.atomic.AtomicBoolean;
67
import java.util.function.BiFunction;
78
import java.util.function.Consumer;
89
import java.util.function.Function;
910

1011
import jakarta.enterprise.event.Observes;
12+
import jakarta.inject.Singleton;
1113

1214
import org.jboss.logging.Logger;
1315

@@ -20,20 +22,27 @@
2022
import io.vertx.sqlclient.Row;
2123
import io.vertx.sqlclient.RowSet;
2224

23-
public class OidcDbTokenStateManagerInitializer {
25+
@Singleton
26+
public final class OidcDbTokenStateManagerInitializer {
2427

2528
private static final Logger LOG = Logger.getLogger(OidcDbTokenStateManagerInitializer.class);
2629
private static final String FAILED_TO_CREATE_DB_TABLE = "unknown reason, please report the issue and create table manually";
2730
/**
2831
* Extra 30 seconds before we delete expired tokens.
2932
*/
3033
private static final long EXPIRED_EXTRA_GRACE = 30;
31-
private static volatile Long timerId = null;
34+
private volatile Long timerId = null;
35+
private volatile SupportedReactiveSqlClient supportedReactiveSqlClient = null;
3236

33-
void initialize(@Observes StartupEvent event, OidcDbTokenStateManagerRunTimeConfig config, Vertx vertx, Pool pool,
34-
OidcDbTokenStateManagerInitializerProperties initializerProps) {
37+
void setSupportedReactiveSqlClient(SupportedReactiveSqlClient supportedReactiveSqlClient) {
38+
this.supportedReactiveSqlClient = supportedReactiveSqlClient;
39+
}
40+
41+
void initialize(@Observes StartupEvent event, OidcDbTokenStateManagerRunTimeConfig config, Vertx vertx, Pool pool) {
42+
Objects.requireNonNull(supportedReactiveSqlClient);
3543
if (config.createDatabaseTableIfNotExists()) {
36-
createDatabaseTable(pool, initializerProps.createTableDdl, initializerProps.supportsIfTableNotExists);
44+
createDatabaseTable(pool, supportedReactiveSqlClient.getCreateTableDdl(config),
45+
supportedReactiveSqlClient.supportsIfTableNotExists);
3746
}
3847
periodicallyDeleteExpiredTokens(vertx, pool, config.deleteExpiredDelay().toMillis());
3948
}
@@ -44,7 +53,7 @@ void shutdown(@Observes ShutdownEvent event, Vertx vertx) {
4453
}
4554
}
4655

47-
private static void periodicallyDeleteExpiredTokens(Vertx vertx, Pool pool, long delayBetweenChecks) {
56+
private void periodicallyDeleteExpiredTokens(Vertx vertx, Pool pool, long delayBetweenChecks) {
4857
timerId = vertx
4958
.setPeriodic(5000, delayBetweenChecks, new Handler<Long>() {
5059

@@ -101,6 +110,7 @@ public Uni<String> apply(RowSet<Row> rows, Throwable throwable) {
101110
return Uni.createFrom().item(throwable.getMessage());
102111
} else {
103112
// most likely we tried to create table even though it already exists
113+
LOG.debug("Failed to create database table", throwable);
104114
return Uni.createFrom().nullItem();
105115
}
106116
}
@@ -140,14 +150,85 @@ public String apply(Throwable throwable) {
140150
}
141151
}
142152

143-
public static final class OidcDbTokenStateManagerInitializerProperties {
153+
public enum SupportedReactiveSqlClient {
154+
POSTGRESQL(true,
155+
(int idToken, int accessToken, int refreshToken) -> "CREATE TABLE IF NOT EXISTS oidc_db_token_state_manager ("
156+
+ "id VARCHAR(100) PRIMARY KEY, "
157+
+ "id_token VARCHAR(" + idToken + "), "
158+
+ "access_token VARCHAR(" + accessToken + "), "
159+
+ "refresh_token VARCHAR(" + refreshToken + "), "
160+
+ "access_token_expires_in BIGINT, "
161+
+ "access_token_scope VARCHAR, "
162+
+ "expires_in BIGINT NOT NULL)"),
163+
DB2(false, (int idToken, int accessToken, int refreshToken) -> "CREATE TABLE oidc_db_token_state_manager ("
164+
+ "id VARCHAR(100) NOT NULL PRIMARY KEY, "
165+
+ "id_token VARCHAR(" + idToken + "), "
166+
+ "access_token VARCHAR(" + accessToken + "), "
167+
+ "refresh_token VARCHAR(" + refreshToken + "), "
168+
+ "access_token_expires_in BIGINT, "
169+
+ "access_token_scope VARCHAR(100), "
170+
+ "expires_in BIGINT NOT NULL)"),
171+
ORACLE(true,
172+
(int idToken, int accessToken, int refreshToken) -> "CREATE TABLE IF NOT EXISTS oidc_db_token_state_manager ("
173+
+ "id VARCHAR2(100), "
174+
+ "id_token VARCHAR2(" + idToken + "), "
175+
+ "access_token VARCHAR2(" + accessToken + "), "
176+
+ "refresh_token VARCHAR2(" + refreshToken + "), "
177+
+ "access_token_expires_in NUMBER, "
178+
+ "access_token_scope VARCHAR2(100), "
179+
+ "expires_in NUMBER NOT NULL, "
180+
+ "PRIMARY KEY (id))"),
181+
MYSQL(true,
182+
(int idToken, int accessToken, int refreshToken) -> "CREATE TABLE IF NOT EXISTS oidc_db_token_state_manager ("
183+
+ "id VARCHAR(100), "
184+
+ "id_token VARCHAR(" + idToken + ") NULL, "
185+
+ "access_token VARCHAR(" + accessToken + ") NULL, "
186+
+ "refresh_token VARCHAR(" + refreshToken + ") NULL, "
187+
+ "access_token_expires_in BIGINT NULL, "
188+
+ "access_token_scope VARCHAR(100) NULL, "
189+
+ "expires_in BIGINT NOT NULL, "
190+
+ "PRIMARY KEY (id))"),
191+
MSSQL(false, new CreateTableDdlProvider() {
192+
193+
@Override
194+
public String getCreateTableDdl(int idToken, int accessToken, int refreshToken) {
195+
return "CREATE TABLE oidc_db_token_state_manager ("
196+
+ "id NVARCHAR(100) PRIMARY KEY, "
197+
+ "id_token NVARCHAR(" + getColumnSize(idToken) + "), "
198+
+ "access_token NVARCHAR(" + getColumnSize(accessToken) + "), "
199+
+ "refresh_token NVARCHAR(" + getColumnSize(refreshToken) + "), "
200+
+ "access_token_expires_in BIGINT, "
201+
+ "access_token_scope NVARCHAR(100), "
202+
+ "expires_in BIGINT NOT NULL)";
203+
}
204+
205+
private static String getColumnSize(int columnSize) {
206+
// from SQL Server docs:
207+
// - the value of n defines the string size in byte-pairs, and can be from 1 through 4000
208+
// - 'max' indicates that the maximum storage size is 2^31-1 characters (2 GB)
209+
// therefore if someone tries to set more than maximum 4000 byte-pairs, we simply use 'max'
210+
if (columnSize > 4000) {
211+
return "max";
212+
}
213+
return Integer.toString(columnSize);
214+
}
215+
});
144216

145-
private final String createTableDdl;
146217
private final boolean supportsIfTableNotExists;
218+
private final CreateTableDdlProvider createTableDdlProvider;
147219

148-
OidcDbTokenStateManagerInitializerProperties(String createTableDdl, boolean supportsIfTableNotExists) {
149-
this.createTableDdl = createTableDdl;
220+
SupportedReactiveSqlClient(boolean supportsIfTableNotExists, CreateTableDdlProvider createTableDdlProvider) {
150221
this.supportsIfTableNotExists = supportsIfTableNotExists;
222+
this.createTableDdlProvider = createTableDdlProvider;
223+
}
224+
225+
private String getCreateTableDdl(OidcDbTokenStateManagerRunTimeConfig config) {
226+
return createTableDdlProvider.getCreateTableDdl(config.idTokenColumnSize(), config.accessTokenColumnSize(),
227+
config.refreshTokenColumnSize());
228+
}
229+
230+
private interface CreateTableDdlProvider {
231+
String getCreateTableDdl(int idToken, int accessToken, int refreshToken);
151232
}
152233
}
153234
}

extensions/oidc-db-token-state-manager/runtime/src/main/java/io/quarkus/oidc/db/token/state/manager/runtime/OidcDbTokenStateManagerRecorder.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import java.util.function.Supplier;
44

55
import io.quarkus.arc.runtime.BeanContainer;
6-
import io.quarkus.oidc.db.token.state.manager.runtime.OidcDbTokenStateManagerInitializer.OidcDbTokenStateManagerInitializerProperties;
6+
import io.quarkus.arc.runtime.BeanContainerListener;
7+
import io.quarkus.oidc.db.token.state.manager.runtime.OidcDbTokenStateManagerInitializer.SupportedReactiveSqlClient;
78
import io.quarkus.runtime.annotations.Recorder;
89
import io.vertx.sqlclient.Pool;
910

@@ -27,13 +28,8 @@ public void setSqlClientPool(BeanContainer container) {
2728
}
2829

2930
/* STATIC INIT */
30-
public Supplier<OidcDbTokenStateManagerInitializerProperties> createDbTokenStateInitializerProps(String createTableDdl,
31-
boolean supportsIfTableNotExists) {
32-
return new Supplier<OidcDbTokenStateManagerInitializerProperties>() {
33-
@Override
34-
public OidcDbTokenStateManagerInitializerProperties get() {
35-
return new OidcDbTokenStateManagerInitializerProperties(createTableDdl, supportsIfTableNotExists);
36-
}
37-
};
31+
public BeanContainerListener setSupportedReactiveSqlClient(SupportedReactiveSqlClient supportedReactiveSqlClient) {
32+
return container -> container.beanInstance(OidcDbTokenStateManagerInitializer.class)
33+
.setSupportedReactiveSqlClient(supportedReactiveSqlClient);
3834
}
3935
}

extensions/oidc-db-token-state-manager/runtime/src/main/java/io/quarkus/oidc/db/token/state/manager/runtime/OidcDbTokenStateManagerRunTimeConfig.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,22 @@ public interface OidcDbTokenStateManagerRunTimeConfig {
2323
*/
2424
@WithDefault("true")
2525
boolean createDatabaseTableIfNotExists();
26+
27+
/**
28+
* ID token column size.
29+
*/
30+
@WithDefault("5000")
31+
int idTokenColumnSize();
32+
33+
/**
34+
* Access token column size.
35+
*/
36+
@WithDefault("5000")
37+
int accessTokenColumnSize();
38+
39+
/**
40+
* Refresh token column size.
41+
*/
42+
@WithDefault("5000")
43+
int refreshTokenColumnSize();
2644
}

0 commit comments

Comments
 (0)