HikariCP icon indicating copy to clipboard operation
HikariCP copied to clipboard

HikariConfig writing to disk and reloading - properties loaded as strings.

Open Narimm opened this issue 5 years ago • 1 comments

I have written a helper class to save a instance of HikariConfig to a properties file. As far as I know there is not a default handler for this?

the helper class effectively does

Object out = PropertyElf.getProperty(k, dbConfig);
            if (out != null) {
                prop.setProperty(k, out.toString());
            }
//and for the dataSourceProperties
        Properties datasourceProps = dbConfig.getDataSourceProperties();
        Set<Object> names = datasourceProps.keySet();
        for (Object name : names) {
            Object val = datasourceProps.get(name);
            if (val != null) {
                prop.setProperty("dataSource." + name, val.toString());
            }
        }

Unfortunately this fails during testing the config it produces is

# Hikari Datasource Properties for advanced database Configuration - Updated: 3/3/21, 2:44 pm
#Wed Mar 03 14:44:05 AEST 2021
initializationFailTimeout=1
validationTimeout=5000
dataSource.minimumIdle=2
readOnly=false
registerMbeans=false
isolateInternalQueries=false
maxLifetime=1800000
leakDetectionThreshold=0
minimumIdle=2
allowPoolSuspension=false
dataSource.maximumPoolSize=10
idleTimeout=600000
maximumPoolSize=10
autoCommit=true
connectionTimeout=30000
poolName=prism

on testing

        File file = new File(tempDirectory, "hikari.properties");
        HikariConfig config = new HikariConfig();
        config.addDataSourceProperty("maximumPoolSize", 10);
        config.addDataSourceProperty("minimumIdle", 2);
        Assertions.assertEquals(2,config.getDataSourceProperties().get("minimumIdle"));
        HikariHelper.saveHikariConfig(file, config, false);
        HikariConfig dbConfig = new HikariConfig(file.getPath());
        Assertions.assertEquals(config.getMinimumIdle(), dbConfig.getMinimumIdle());
        Assertions.assertEquals(config.getDataSourceProperties().get("minimumIdle"),
                                                                                        dbConfig.getDataSourceProperties().get("minimumIdle"));

This fails on the last assertion - because the original config produces a Long and the reloaded one is a String.

Should the `addDataSourceProperty(String, Object) method validate that each object can be saved as a String and convert it before it writes it into the properties?

Narimm avatar Mar 03 '21 05:03 Narimm


import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.util.PropertyElf;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class HikariHelper {

    public static void saveHikariConfig(File file, HikariConfig dbConfig, boolean append) throws IOException {
        Properties prop = new Properties();
        // Save HikariConfig properties
        for (String k : PropertyElf.getPropertyNames(HikariConfig.class)) {
            Object out = PropertyElf.getProperty(k, dbConfig);
            if (out != null) {
                prop.setProperty(k, out.toString());
            }
        }

        // Save dataSource properties
        Properties datasourceProps = dbConfig.getDataSourceProperties();
        Set<Object> names = datasourceProps.keySet();
        for (Object name : names) {
            Object val = datasourceProps.get(name);
            if (val != null) {
                // You can check the type here if necessary, and handle special cases
                prop.setProperty("dataSource." + name, val.toString());
            }
        }

        // Write properties to file
        try (FileWriter writer = new FileWriter(file, append)) {
            prop.store(writer, "Hikari Datasource Properties for advanced database Configuration");
        }
    }

    public static HikariConfig loadHikariConfig(File file) throws IOException {
        Properties prop = new Properties();
        try (FileReader reader = new FileReader(file)) {
            prop.load(reader);
        }

        HikariConfig dbConfig = new HikariConfig(prop);

        // Ensure type safety when reloading datasource properties
        for (String key : prop.stringPropertyNames()) {
            if (key.startsWith("dataSource.")) {
                String dsKey = key.substring("dataSource.".length());
                String value = prop.getProperty(key);
                if (value != null) {
                    // Perform any type conversions if needed (convert strings back to their original types)
                    if (dsKey.equals("maximumPoolSize") || dsKey.equals("minimumIdle")) {
                        dbConfig.addDataSourceProperty(dsKey, Integer.parseInt(value));
                    } else {
                        dbConfig.addDataSourceProperty(dsKey, value);
                    }
                }
            }
        }

        return dbConfig;
    }
}

ljluestc avatar Oct 18 '24 05:10 ljluestc