package com.linkedin.thirdeye.datalayer.util; import com.linkedin.thirdeye.datalayer.entity.AlertConfigIndex; import com.linkedin.thirdeye.datalayer.entity.ClassificationConfigIndex; import com.linkedin.thirdeye.datalayer.entity.EventIndex; import com.linkedin.thirdeye.datalayer.entity.AutotuneConfigIndex; import com.linkedin.thirdeye.datalayer.entity.GroupedAnomalyResultsIndex; import com.linkedin.thirdeye.datalayer.entity.OverrideConfigIndex; import io.dropwizard.configuration.ConfigurationFactory; import io.dropwizard.jackson.Jackson; import java.io.File; import java.sql.Connection; import javax.validation.Validation; import org.apache.tomcat.jdbc.pool.DataSource; import com.google.common.base.CaseFormat; import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.linkedin.thirdeye.datalayer.bao.jdbc.AbstractManagerImpl; import com.linkedin.thirdeye.datalayer.dto.AbstractDTO; import com.linkedin.thirdeye.datalayer.entity.AnomalyFeedbackIndex; import com.linkedin.thirdeye.datalayer.entity.AnomalyFunctionIndex; import com.linkedin.thirdeye.datalayer.entity.DashboardConfigIndex; import com.linkedin.thirdeye.datalayer.entity.DataCompletenessConfigIndex; import com.linkedin.thirdeye.datalayer.entity.DatasetConfigIndex; import com.linkedin.thirdeye.datalayer.entity.DetectionStatusIndex; import com.linkedin.thirdeye.datalayer.entity.EmailConfigurationIndex; import com.linkedin.thirdeye.datalayer.entity.EntityToEntityMappingIndex; import com.linkedin.thirdeye.datalayer.entity.GenericJsonEntity; import com.linkedin.thirdeye.datalayer.entity.IngraphDashboardConfigIndex; import com.linkedin.thirdeye.datalayer.entity.IngraphMetricConfigIndex; import com.linkedin.thirdeye.datalayer.entity.JobIndex; import com.linkedin.thirdeye.datalayer.entity.MergedAnomalyResultIndex; import com.linkedin.thirdeye.datalayer.entity.MetricConfigIndex; import com.linkedin.thirdeye.datalayer.entity.RawAnomalyResultIndex; import com.linkedin.thirdeye.datalayer.entity.TaskIndex; public abstract class DaoProviderUtil { private static DataSource dataSource; private static ManagerProvider provider; public static void init(File localConfigFile) { PersistenceConfig configuration = createConfiguration(localConfigFile); dataSource = new DataSource(); dataSource.setInitialSize(10); dataSource.setDefaultAutoCommit(false); dataSource.setMaxActive(100); dataSource.setUsername(configuration.getDatabaseConfiguration().getUser()); dataSource.setPassword(configuration.getDatabaseConfiguration().getPassword()); dataSource.setUrl(configuration.getDatabaseConfiguration().getUrl()); dataSource.setDriverClassName(configuration.getDatabaseConfiguration().getDriver()); dataSource.setValidationQuery("select 1"); dataSource.setTestWhileIdle(true); dataSource.setTestOnBorrow(true); // when returning connection to pool dataSource.setTestOnReturn(true); dataSource.setRollbackOnReturn(true); // Timeout before an abandoned(in use) connection can be removed. dataSource.setRemoveAbandonedTimeout(600_000); dataSource.setRemoveAbandoned(true); init(dataSource); } public static void init (DataSource ds) { dataSource = ds; provider = new ManagerProvider(dataSource); } public static PersistenceConfig createConfiguration(File configFile) { ConfigurationFactory<PersistenceConfig> factory = new ConfigurationFactory<>(PersistenceConfig.class, Validation.buildDefaultValidatorFactory().getValidator(), Jackson.newObjectMapper(), ""); PersistenceConfig configuration; try { configuration = factory.build(configFile); } catch (Exception e) { throw new RuntimeException(e); } return configuration; } public static <T extends AbstractManagerImpl<? extends AbstractDTO>> T getInstance(Class<T> c) { T instance = provider.getInstance(c); return instance; } static class DataSourceModule extends AbstractModule { SqlQueryBuilder builder; DataSource dataSource; private GenericResultSetMapper genericResultSetMapper; EntityMappingHolder entityMappingHolder; DataSourceModule(DataSource dataSource) { this.dataSource = dataSource; entityMappingHolder = new EntityMappingHolder(); try (Connection conn = dataSource.getConnection()) { entityMappingHolder.register(conn, GenericJsonEntity.class, convertCamelCaseToUnderscore(GenericJsonEntity.class.getSimpleName())); entityMappingHolder.register(conn, AnomalyFeedbackIndex.class, convertCamelCaseToUnderscore(AnomalyFeedbackIndex.class.getSimpleName())); entityMappingHolder.register(conn, AnomalyFunctionIndex.class, convertCamelCaseToUnderscore(AnomalyFunctionIndex.class.getSimpleName())); entityMappingHolder.register(conn, JobIndex.class, convertCamelCaseToUnderscore(JobIndex.class.getSimpleName())); entityMappingHolder.register(conn, MergedAnomalyResultIndex.class, convertCamelCaseToUnderscore(MergedAnomalyResultIndex.class.getSimpleName())); entityMappingHolder.register(conn, RawAnomalyResultIndex.class, convertCamelCaseToUnderscore(RawAnomalyResultIndex.class.getSimpleName())); entityMappingHolder.register(conn, TaskIndex.class, convertCamelCaseToUnderscore(TaskIndex.class.getSimpleName())); entityMappingHolder.register(conn, EmailConfigurationIndex.class, convertCamelCaseToUnderscore(EmailConfigurationIndex.class.getSimpleName())); entityMappingHolder.register(conn, DatasetConfigIndex.class, convertCamelCaseToUnderscore(DatasetConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, MetricConfigIndex.class, convertCamelCaseToUnderscore(MetricConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, DashboardConfigIndex.class, convertCamelCaseToUnderscore(DashboardConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, IngraphDashboardConfigIndex.class, convertCamelCaseToUnderscore(IngraphDashboardConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, IngraphMetricConfigIndex.class, convertCamelCaseToUnderscore(IngraphMetricConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, OverrideConfigIndex.class, convertCamelCaseToUnderscore(OverrideConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, AlertConfigIndex.class, convertCamelCaseToUnderscore(AlertConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, DataCompletenessConfigIndex.class, convertCamelCaseToUnderscore(DataCompletenessConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, EventIndex.class, convertCamelCaseToUnderscore(EventIndex.class.getSimpleName())); entityMappingHolder.register(conn, DetectionStatusIndex.class, convertCamelCaseToUnderscore(DetectionStatusIndex.class.getSimpleName())); entityMappingHolder.register(conn, AutotuneConfigIndex.class, convertCamelCaseToUnderscore(AutotuneConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, ClassificationConfigIndex.class, convertCamelCaseToUnderscore(ClassificationConfigIndex.class.getSimpleName())); entityMappingHolder.register(conn, EntityToEntityMappingIndex.class, convertCamelCaseToUnderscore(EntityToEntityMappingIndex.class.getSimpleName())); entityMappingHolder.register(conn, GroupedAnomalyResultsIndex.class, convertCamelCaseToUnderscore(GroupedAnomalyResultsIndex.class.getSimpleName())); } catch (Exception e) { throw new RuntimeException(e); } builder = new SqlQueryBuilder(entityMappingHolder); genericResultSetMapper = new GenericResultSetMapper(entityMappingHolder); } public static String convertCamelCaseToUnderscore(String str) { return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, str); } @Override protected void configure() { } @Provides javax.sql.DataSource getDataSource() { return dataSource; } @Provides SqlQueryBuilder getBuilder() { return builder; } @Provides GenericResultSetMapper getResultSetMapper() { return genericResultSetMapper; } } }