yugabyte / yugabyte-db

YugabyteDB - the cloud native distributed SQL database for mission-critical applications.
https://www.yugabyte.com
Other
9.02k stars 1.08k forks source link

[Docs] Jdbc driver example contains incorrect properties #23738

Open Aelentel opened 2 months ago

Aelentel commented 2 months ago

Description

the documentation :

https://docs.yugabyte.com/stable/reference/drivers/java/yugabyte-jdbc-reference/

contains improper example for topology keys, the proper property is not "dataSource.topologyKeys" but "dataSource.topology-keys".

String geoLocations = "cloud1.region1.zone1,cloud1.region2.zone2";
poolProperties.setProperty("dataSource.topologyKeys", geoLocations);

should be

String geoLocations = "cloud1.region1.zone1,cloud1.region2.zone2";
poolProperties.setProperty("dataSource.topology-keys", geoLocations);

regards.

Warning: Please confirm that this issue does not contain any sensitive information

ashetkar commented 2 months ago

Hi @Aelentel Just curious, is the documented example failing for you?

I see it's a bit confusing since we use the hyphenated property name (topology-keys) in the connection url or even in the property bag for the DriverManager.getConnection() method, whereas for the HikariConfig, we use the camelCase name (topologyKeys).

Hikari attempts to invoke setter method for the datasource property by using PascalCase form of the property name, prefixing set to it and searching with that name. We cannot have a method named setTopology-Keys but setTopologyKeys is fine. Hence the difference.

Aelentel commented 2 months ago

Hi @ashetkar, here's the code i had to do to make it working :

        @Bean
    LazyConnectionDataSourceProxy datasource(DatabaseProperties props)
    {
        // see https://docs.yugabyte.com/preview/reference/drivers/java/yugabyte-jdbc-reference/
        Properties poolProperties = new Properties();
        //
        poolProperties.setProperty("dataSource.user", props.getUser());
        poolProperties.setProperty("dataSource.password", props.getPassword());
        //
        if (props.getTopology()!=null && !props.getTopology().isEmpty())
        {
            poolProperties.setProperty("dataSource.topology-keys", props.getTopology().stream().collect(Collectors.joining(",")));
            poolProperties.setProperty("dataSource.load-balance", "true");
        }
        else
        {
            poolProperties.setProperty("dataSource.load-balance", "false");
        }
        //
        HikariConfig config = new HikariConfig(poolProperties);
        config.setPoolName("service-pool");
        config.setJdbcUrl(props.getUrl());
        config.setMaximumPoolSize(props.getPoolMax());
        config.setAutoCommit(false);
        config.validate();
        //
        HikariDataSource ds = new HikariDataSource(config);
        //
        return new LazyConnectionDataSourceProxy(ds);
    }

as you can notice it's snake case and using topologyKeys instead of topology-keys didn't work at all, when using topologyKeys the driver is cluster aware, get the list of the whole topology and ignore the topology keys, when using topology-keys the driver is topology aware and is using the topology keys provided.

to be noted, my connection url is using a list of hosts so there's a fall back in case a node is unavailable, those hosts are part of the topology keys. the format of my connection url is "jdbc:yugabytedb://host_a:port_a,host_b:port_b/database"

so it seems the documentation is incorrect about using camelCase for datasource properties, as the same did apply to the "load-balance"

also the yugabyte driver used is : com.yugabyte:com.yugabyte:42.3.5-yb-5 the Hikari CP is 5.1.0 ( thru spring-boot-starter-jdbc 3.3.2 )