Skip to content

Commit 4a3a974

Browse files
authored
fix: null handling in config mapper (#897)
* fix: core config validation * fix: core config validation * fix: PR comments * fix: PR comments * fix: test * fix: startup test * fix: using ConfigMapper * fix: test * fix: config mapper * fix: core config * fix: null handling * fix: test defaults
1 parent 16293c1 commit 4a3a974

File tree

3 files changed

+46
-20
lines changed

3 files changed

+46
-20
lines changed

src/main/java/io/supertokens/config/Config.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.fasterxml.jackson.databind.ObjectMapper;
2020
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
2121
import com.google.gson.Gson;
22+
import com.google.gson.GsonBuilder;
2223
import com.google.gson.JsonObject;
2324
import io.supertokens.Main;
2425
import io.supertokens.ProcessState;
@@ -51,7 +52,7 @@ private Config(Main main, String configFilePath) throws InvalidConfigException,
5152
this.main = main;
5253
final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
5354
Object configObj = mapper.readValue(new File(configFilePath), Object.class);
54-
JsonObject jsonConfig = new Gson().toJsonTree(configObj).getAsJsonObject();
55+
JsonObject jsonConfig = new GsonBuilder().serializeNulls().create().toJsonTree(configObj).getAsJsonObject();
5556
CoreConfig config = ConfigMapper.mapConfig(jsonConfig, CoreConfig.class);
5657
config.normalizeAndValidate(main, true);
5758
this.core = config;
@@ -91,7 +92,7 @@ public static JsonObject getBaseConfigAsJsonObject(Main main) throws IOException
9192
// omit them from the output json.
9293
ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory());
9394
Object obj = yamlReader.readValue(new File(getConfigFilePath(main)), Object.class);
94-
return new Gson().toJsonTree(obj).getAsJsonObject();
95+
return new GsonBuilder().serializeNulls().create().toJsonTree(obj).getAsJsonObject();
9596
}
9697

9798
private static String getConfigFilePath(Main main) {

src/main/java/io/supertokens/utils/ConfigMapper.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,21 +72,9 @@ private static <T> Field findField(Class<T> clazz, String key) {
7272
}
7373

7474
private static <T> void setValue(T object, Field field, JsonElement value) throws InvalidConfigException {
75-
boolean foundAnnotation = false;
76-
for (Annotation a : field.getAnnotations()) {
77-
if (a.toString().contains("JsonProperty")) {
78-
foundAnnotation = true;
79-
break;
80-
}
81-
}
82-
83-
if (!foundAnnotation) {
84-
return;
85-
}
86-
8775
field.setAccessible(true);
8876
Object convertedValue = convertJsonElementToTargetType(value, field.getType(), field.getName());
89-
if (convertedValue != null) {
77+
if (convertedValue != null || isNullable(field.getType())) {
9078
try {
9179
field.set(object, convertedValue);
9280
} catch (IllegalAccessException e) {
@@ -95,6 +83,10 @@ private static <T> void setValue(T object, Field field, JsonElement value) throw
9583
}
9684
}
9785

86+
private static boolean isNullable(Class<?> type) {
87+
return !type.isPrimitive();
88+
}
89+
9890
private static Object convertJsonElementToTargetType(JsonElement value, Class<?> targetType, String fieldName)
9991
throws InvalidConfigException {
10092
// If the value is JsonNull, return null for any type

src/test/java/io/supertokens/test/ConfigMapperTest.java

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,40 @@ public class ConfigMapperTest {
2929

3030
public static class DummyConfig {
3131
@JsonProperty
32-
int int_property;
32+
int int_property = -1;
3333

3434
@JsonProperty
35-
long long_property;
35+
long long_property = -1;
3636

3737
@JsonProperty
38-
float float_property;
38+
float float_property = -1;
3939

4040
@JsonProperty
41-
double double_property;
41+
double double_property = -1;
4242

4343
@JsonProperty
44-
String string_property;
44+
String string_property = "default_string";
4545

4646
@JsonProperty
4747
boolean bool_property;
48+
49+
@JsonProperty
50+
Long nullable_long_property = new Long(-1);
4851
}
4952

5053
@Test
5154
public void testAllValidConversions() throws Exception {
55+
// Test defaults
56+
{
57+
JsonObject config = new JsonObject();
58+
assertEquals(-1, ConfigMapper.mapConfig(config, DummyConfig.class).int_property);
59+
assertEquals(-1, ConfigMapper.mapConfig(config, DummyConfig.class).long_property);
60+
assertEquals(-1, ConfigMapper.mapConfig(config, DummyConfig.class).float_property, 0.0001);
61+
assertEquals(-1, ConfigMapper.mapConfig(config, DummyConfig.class).double_property, 0.0001);
62+
assertEquals("default_string", ConfigMapper.mapConfig(config, DummyConfig.class).string_property);
63+
assertEquals(new Long(-1), ConfigMapper.mapConfig(config, DummyConfig.class).nullable_long_property);
64+
}
65+
5266
// valid for int
5367
{
5468
JsonObject config = new JsonObject();
@@ -171,6 +185,25 @@ public void testAllValidConversions() throws Exception {
171185
config.addProperty("string_property", "hello");
172186
assertEquals("hello", ConfigMapper.mapConfig(config, DummyConfig.class).string_property);
173187
}
188+
189+
{
190+
JsonObject config = new JsonObject();
191+
config.add("string_property", null);
192+
assertEquals(null, ConfigMapper.mapConfig(config, DummyConfig.class).string_property);
193+
}
194+
195+
// valid for nullable long
196+
{
197+
JsonObject config = new JsonObject();
198+
config.add("nullable_long_property", null);
199+
assertEquals(null, ConfigMapper.mapConfig(config, DummyConfig.class).nullable_long_property);
200+
}
201+
202+
{
203+
JsonObject config = new JsonObject();
204+
config.addProperty("nullable_long_property", 100);
205+
assertEquals(new Long(100), ConfigMapper.mapConfig(config, DummyConfig.class).nullable_long_property);
206+
}
174207
}
175208

176209
@Test

0 commit comments

Comments
 (0)