package com.hubspot.blazar.data; import javax.inject.Provider; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.StatementContext; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.jdbi.InstrumentedTimingCollector; import com.codahale.metrics.jdbi.strategies.DelegatingStatementNameStrategy; import com.codahale.metrics.jdbi.strategies.NameStrategies; import com.codahale.metrics.jdbi.strategies.StatementNameStrategy; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Optional; import com.google.inject.Inject; import com.hubspot.guice.transactional.TransactionalDataSource; import com.hubspot.rosetta.jdbi.RosettaMapperFactory; import com.hubspot.rosetta.jdbi.RosettaObjectMapperOverride; import io.dropwizard.db.DataSourceFactory; import io.dropwizard.db.ManagedDataSource; import io.dropwizard.jdbi.DBIHealthCheck; import io.dropwizard.jdbi.GuavaOptionalContainerFactory; import io.dropwizard.jdbi.ImmutableListContainerFactory; import io.dropwizard.jdbi.ImmutableSetContainerFactory; import io.dropwizard.jdbi.args.JodaDateTimeArgumentFactory; import io.dropwizard.jdbi.args.JodaDateTimeMapper; import io.dropwizard.jdbi.args.OptionalArgumentFactory; import io.dropwizard.jdbi.logging.LogbackLog; import io.dropwizard.setup.Environment; public class DBIProvider implements Provider<DBI> { private final TransactionalDataSource transactionalDataSource; private final ManagedDataSource managedDataSource; private final DataSourceFactory dataSourceFactory; private final ObjectMapper objectMapper; private Optional<Environment> environment; @Inject public DBIProvider(TransactionalDataSource transactionalDataSource, ManagedDataSource managedDataSource, DataSourceFactory dataSourceFactory, ObjectMapper objectMapper) { this.transactionalDataSource = transactionalDataSource; this.managedDataSource = managedDataSource; this.dataSourceFactory = dataSourceFactory; this.objectMapper = objectMapper.copy().setSerializationInclusion(Include.ALWAYS); this.environment = Optional.absent(); } @Inject(optional = true) public void setEnvironment(Environment environment) { this.environment = Optional.of(environment); } @Override public DBI get() { final DBI dbi = new DBI(transactionalDataSource); dbi.setSQLLog(new LogbackLog()); if (environment.isPresent()) { environment.get().lifecycle().manage(managedDataSource); environment.get().healthChecks().register("db", new DBIHealthCheck(dbi, dataSourceFactory.getValidationQuery())); dbi.setTimingCollector(new InstrumentedTimingCollector(environment.get().metrics(), new SanerNamingStrategy())); } dbi.registerArgumentFactory(new OptionalArgumentFactory(dataSourceFactory.getDriverClass())); dbi.registerContainerFactory(new ImmutableListContainerFactory()); dbi.registerContainerFactory(new ImmutableSetContainerFactory()); dbi.registerContainerFactory(new GuavaOptionalContainerFactory()); dbi.registerArgumentFactory(new JodaDateTimeArgumentFactory()); dbi.registerColumnMapper(new JodaDateTimeMapper()); dbi.registerMapper(new RosettaMapperFactory()); new RosettaObjectMapperOverride(objectMapper).override(dbi); return dbi; } private static class SanerNamingStrategy extends DelegatingStatementNameStrategy { private static final String RAW_SQL = MetricRegistry.name(DBI.class, "raw-sql"); private SanerNamingStrategy() { super(NameStrategies.CHECK_EMPTY, NameStrategies.CONTEXT_CLASS, NameStrategies.CONTEXT_NAME, NameStrategies.SQL_OBJECT, new StatementNameStrategy() { @Override public String getStatementName(StatementContext statementContext) { return RAW_SQL; } }); } } }