Skip to content

Commit d2eb7ab

Browse files
authored
Merge pull request #304 from supertokens/fix/min_idle_connection_envvar_9_3
fix: min idle connection envvar 9 3
2 parents 9e466f0 + 3075fce commit d2eb7ab

5 files changed

Lines changed: 123 additions & 62 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
99

10+
## [9.3.3]
11+
12+
- Fixes env var parsing with a few types
13+
1014
## [9.3.2]
1115

1216
- Regenerates `implementationDependencies.json`

build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ plugins {
22
id 'java-library'
33
}
44

5-
version = "9.3.2"
5+
version = "9.3.3"
66

77
repositories {
88
mavenCentral()
@@ -82,7 +82,8 @@ tasks.register('generateMetaInf') {
8282
build.dependsOn(generateMetaInf)
8383

8484
test {
85-
jvmArgs '-Djava.security.egd=file:/dev/urandom'
85+
jvmArgs '-Djava.security.egd=file:/dev/urandom',
86+
'--add-opens=java.base/java.util=ALL-UNNAMED'
8687
minHeapSize = "128m" // initial heap size
8788
maxHeapSize = "1024m" // maximum heap size
8889
testLogging {

implementationDependencies.json

Lines changed: 10 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,25 @@
11
{
22
"_comment": "Contains list of implementation dependencies URL for this project. This is a generated file, don't modify the contents by hand.",
33
"list": [
4-
{
5-
"jar":"https://repo.maven.apache.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.18.2/jackson-dataformat-yaml-2.18.2.jar",
6-
"name":"jackson-dataformat-yaml 2.18.2",
7-
"src":"https://repo.maven.apache.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.18.2/jackson-dataformat-yaml-2.18.2-sources.jar"
8-
},
9-
{
10-
"jar":"https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.18.2/jackson-databind-2.18.2.jar",
11-
"name":"jackson-databind 2.18.2",
12-
"src":"https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.18.2/jackson-databind-2.18.2-sources.jar"
13-
},
14-
{
15-
"jar":"https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/2.18.2/jackson-core-2.18.2.jar",
16-
"name":"jackson-core 2.18.2",
17-
"src":"https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/2.18.2/jackson-core-2.18.2-sources.jar"
18-
},
19-
{
20-
"jar":"https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.18.2/jackson-annotations-2.18.2.jar",
21-
"name":"jackson-annotations 2.18.2",
22-
"src":"https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.18.2/jackson-annotations-2.18.2-sources.jar"
23-
},
24-
{
25-
"jar":"https://repo.maven.apache.org/maven2/org/yaml/snakeyaml/2.3/snakeyaml-2.3.jar",
26-
"name":"snakeyaml 2.3",
27-
"src":"https://repo.maven.apache.org/maven2/org/yaml/snakeyaml/2.3/snakeyaml-2.3-sources.jar"
28-
},
29-
{
30-
"jar":"https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/1.5.13/logback-classic-1.5.13.jar",
31-
"name":"logback-classic 1.5.13",
32-
"src":"https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/1.5.13/logback-classic-1.5.13-sources.jar"
33-
},
34-
{
35-
"jar":"https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/1.5.13/logback-core-1.5.13.jar",
36-
"name":"logback-core 1.5.13",
37-
"src":"https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/1.5.13/logback-core-1.5.13-sources.jar"
38-
},
39-
{
40-
"jar":"https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.0.15/slf4j-api-2.0.15.jar",
41-
"name":"slf4j-api 2.0.15",
42-
"src":"https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.0.15/slf4j-api-2.0.15-sources.jar"
43-
},
44-
{
45-
"jar":"https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar",
46-
"name":"jsr305 3.0.2",
47-
"src":"https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2-sources.jar"
48-
},
49-
{
50-
"jar":"https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.jar",
51-
"name":"annotations 13.0",
52-
"src":"https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0-sources.jar"
53-
},
54-
{
55-
"jar":"https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.3.1/gson-2.3.1.jar",
56-
"name":"gson 2.3.1",
57-
"src":"https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.3.1/gson-2.3.1-sources.jar"
58-
},
594
{
605
"jar":"https://repo.maven.apache.org/maven2/com/zaxxer/HikariCP/6.3.0/HikariCP-6.3.0.jar",
616
"name":"HikariCP 6.3.0",
627
"src":"https://repo.maven.apache.org/maven2/com/zaxxer/HikariCP/6.3.0/HikariCP-6.3.0-sources.jar"
638
},
9+
{
10+
"jar":"https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar",
11+
"name":"slf4j-api 1.7.36",
12+
"src":"https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36-sources.jar"
13+
},
6414
{
6515
"jar":"https://repo.maven.apache.org/maven2/org/postgresql/postgresql/42.7.2/postgresql-42.7.2.jar",
6616
"name":"postgresql 42.7.2",
6717
"src":"https://repo.maven.apache.org/maven2/org/postgresql/postgresql/42.7.2/postgresql-42.7.2-sources.jar"
18+
},
19+
{
20+
"jar":"https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.42.0/checker-qual-3.42.0.jar",
21+
"name":"checker-qual 3.42.0",
22+
"src":"https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.42.0/checker-qual-3.42.0-sources.jar"
6823
}
6924
]
7025
}

src/main/java/io/supertokens/storage/postgresql/Start.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -863,18 +863,24 @@ public void updateConfigJsonFromEnv(JsonObject configJson) {
863863
.replace("\\\\", "\\");
864864
}
865865

866+
// Empty/unset stringValue is already handled above (null/empty check),
867+
// so boxed types (Integer, Long, etc.) can safely share branches
868+
// with their primitive counterparts.
866869
if (field.getType().equals(String.class)) {
867870
configJson.addProperty(field.getName(), stringValue);
868-
} else if (field.getType().equals(int.class)) {
871+
} else if (field.getType().equals(int.class) || field.getType().equals(Integer.class)) {
869872
configJson.addProperty(field.getName(), Integer.parseInt(stringValue));
870-
} else if (field.getType().equals(long.class)) {
873+
} else if (field.getType().equals(long.class) || field.getType().equals(Long.class)) {
871874
configJson.addProperty(field.getName(), Long.parseLong(stringValue));
872-
} else if (field.getType().equals(boolean.class)) {
875+
} else if (field.getType().equals(boolean.class) || field.getType().equals(Boolean.class)) {
873876
configJson.addProperty(field.getName(), Boolean.parseBoolean(stringValue));
874-
} else if (field.getType().equals(float.class)) {
877+
} else if (field.getType().equals(float.class) || field.getType().equals(Float.class)) {
875878
configJson.addProperty(field.getName(), Float.parseFloat(stringValue));
876-
} else if (field.getType().equals(double.class)) {
879+
} else if (field.getType().equals(double.class) || field.getType().equals(Double.class)) {
877880
configJson.addProperty(field.getName(), Double.parseDouble(stringValue));
881+
} else {
882+
throw new RuntimeException(
883+
"Unknown field type " + field.getType().getName() + " for config field " + field.getName());
878884
}
879885
}
880886
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright (c) 2025, VRAI Labs and/or its affiliates. All rights reserved.
3+
*
4+
* This software is licensed under the Apache License, Version 2.0 (the
5+
* "License") as published by the Apache Software Foundation.
6+
*
7+
* You may not use this file except in compliance with the License. You may
8+
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
17+
package io.supertokens.storage.postgresql.test;
18+
19+
import com.google.gson.JsonObject;
20+
import io.supertokens.storage.postgresql.Start;
21+
import org.junit.Test;
22+
23+
import java.lang.reflect.Field;
24+
import java.util.Map;
25+
26+
import static org.junit.Assert.*;
27+
28+
public class EnvConfigTest {
29+
30+
private static void setEnv(String key, String value) {
31+
try {
32+
Map<String, String> env = System.getenv();
33+
Class<?> cl = env.getClass();
34+
Field field = cl.getDeclaredField("m");
35+
field.setAccessible(true);
36+
@SuppressWarnings("unchecked")
37+
Map<String, String> writableEnv = (Map<String, String>) field.get(env);
38+
writableEnv.put(key, value);
39+
} catch (Exception e) {
40+
throw new IllegalStateException("Failed to set environment variable", e);
41+
}
42+
}
43+
44+
private static void removeEnv(String key) {
45+
try {
46+
Map<String, String> env = System.getenv();
47+
Class<?> cl = env.getClass();
48+
Field field = cl.getDeclaredField("m");
49+
field.setAccessible(true);
50+
@SuppressWarnings("unchecked")
51+
Map<String, String> writableEnv = (Map<String, String>) field.get(env);
52+
writableEnv.remove(key);
53+
} catch (Exception e) {
54+
throw new IllegalStateException("Failed to remove environment variable", e);
55+
}
56+
}
57+
58+
@Test
59+
public void testUpdateConfigJsonFromEnvHandlesBoxedTypes() {
60+
// Regression test: Integer fields like postgresql_minimum_idle_connections
61+
// were silently dropped because updateConfigJsonFromEnv only checked
62+
// primitive types (int.class) not boxed types (Integer.class).
63+
Start start = new Start();
64+
try {
65+
setEnv("POSTGRESQL_MINIMUM_IDLE_CONNECTIONS", "5");
66+
67+
JsonObject configJson = new JsonObject();
68+
start.updateConfigJsonFromEnv(configJson);
69+
70+
assertTrue("POSTGRESQL_MINIMUM_IDLE_CONNECTIONS env var should be loaded into configJson",
71+
configJson.has("postgresql_minimum_idle_connections"));
72+
assertEquals(5, configJson.get("postgresql_minimum_idle_connections").getAsInt());
73+
} finally {
74+
removeEnv("POSTGRESQL_MINIMUM_IDLE_CONNECTIONS");
75+
}
76+
}
77+
78+
@Test
79+
public void testUpdateConfigJsonFromEnvHandlesBoxedTypeWithZero() {
80+
// Tests that Integer value of 0 is correctly loaded (not confused with null/unset)
81+
Start start = new Start();
82+
try {
83+
setEnv("POSTGRESQL_MINIMUM_IDLE_CONNECTIONS", "0");
84+
85+
JsonObject configJson = new JsonObject();
86+
start.updateConfigJsonFromEnv(configJson);
87+
88+
assertTrue("POSTGRESQL_MINIMUM_IDLE_CONNECTIONS env var with value 0 should be loaded",
89+
configJson.has("postgresql_minimum_idle_connections"));
90+
assertEquals(0, configJson.get("postgresql_minimum_idle_connections").getAsInt());
91+
} finally {
92+
removeEnv("POSTGRESQL_MINIMUM_IDLE_CONNECTIONS");
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)