gavlyukovskiy/spring-boot-data-source-decorator

DataSource decorator with HikariDataSourcePoolMetadata

oburgosm opened this issue · 2 comments

I have an SB 2.5 application with a Hikari datasource and I'm using datasource-proxy-spring-boot-starter (1.7.1).

Also I am using datasources metrics provided by SB, based on class HikariDataSourcePoolMetadata, and here I have the problem. The method getActive invoke to getHikariPool that does this:

        private HikariPool getHikariPool() {
		return (HikariPool) new DirectFieldAccessor(getDataSource()).getPropertyValue("pool");
	}

But, because the datasource is a proxy, it return null.

I¡m not sure if it's possible that proxied datasource will give access to field pool, or it's an issue that I should report to SB.

Meanwhile I have a workaround. I have created the next bean, which take into account that HikariDataSource could be a proxy and it have more priority that bean hikariPoolDataSourceMetadataProvider provides by SB :

    @Bean
    @Order(Ordered.LOWEST_PRECEDENCE - 10)
    DataSourcePoolMetadataProvider customHikariPoolDataSourceMetadataProvider() {
        return (dataSource) -> {
            HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(dataSource, HikariConfigMXBean.class,
                    HikariDataSource.class);
            if (hikariDataSource != null) {
                // Because HikariDataSourcePoolMetadata access to HikariPool via reflection, we need to unwrap AOP
                // proxies
                if (AopUtils.isAopProxy(hikariDataSource)) {
                    Object target;
                    try {
                        target = ((Advised) hikariDataSource).getTargetSource().getTarget();
                        hikariDataSource = (HikariDataSource) target;
                    } catch (Exception ex) {
                        LOG.warn(
                                "Unwrap hikari AOP proxy failed. We instrument Hikari proxied datasource, but some metrics might not be available");
                    }
                }
                return new HikariDataSourcePoolMetadata(hikariDataSource);
            }
            return null;
        };
    }


I was under the impression that DataSourceUnwrapper.unwrap(dataSource, HikariConfigMXBean.class, HikariDataSource.class) will return real data source, not the proxy. I have a separate branch which doesn't use proxies, can you please check that it works in your case?

I have checked branch no-cglib and it works.