content: package io.aiven.klaw.config;
  
  import com.zaxxer.hikari.HikariDataSource;
  import io.aiven.klaw.helpers.db.rdbms.JdbcDataSourceCondition;
  import java.sql.SQLException;
  import java.util.Objects;
  import java.util.Properties;
  import javax.sql.DataSource;
  import lombok.extern.slf4j.Slf4j;
  import org.hibernate.jpa.HibernatePersistenceProvider;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.autoconfigure.domain.EntityScan;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Conditional;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.context.annotation.PropertySource;
  import org.springframework.core.env.Environment;
  import org.springframework.orm.jpa.JpaTransactionManager;
  import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
  import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
  
  @Configuration
  @EntityScan
  @PropertySource(value = {"classpath:application.properties"})
  @Slf4j
  public class DataSourceConfig {
  
    @Autowired Environment environment;
  
    @Bean(name = "dataSource")
    @Conditional(JdbcDataSourceCondition.class)
    public DataSource dataSource() throws SQLException {
      log.info("Into Hikari datasource config.");
      final HikariDataSource dataSource = new HikariDataSource();
      dataSource.setDriverClassName(environment.getProperty("spring.datasource.driver.class"));
      dataSource.setJdbcUrl(environment.getProperty("spring.datasource.url"));
      dataSource.setUsername(environment.getProperty("spring.datasource.username"));
      dataSource.setPassword(environment.getProperty("spring.datasource.password"));
      dataSource.setAutoCommit(true);
      dataSource.setConnectionTimeout(
          Long.parseLong(
              Objects.requireNonNull(
                  environment.getProperty("spring.datasource.hikari.connectionTimeout"))));
      dataSource.setIdleTimeout(
          Long.parseLong(
              Objects.requireNonNull(
                  environment.getProperty("spring.datasource.hikari.idleTimeout"))));
      dataSource.setLoginTimeout(60);
      dataSource.setMinimumIdle(100);
      dataSource.setMaximumPoolSize(
          Integer.parseInt(
              Objects.requireNonNull(
                  environment.getProperty("spring.datasource.hikari.maxPoolSize"))));
  
      log.info("Connecting to RDBMS datasource.");
      return dataSource;
    }
  
    @Bean(name = "transactionManager")
    @Conditional(JdbcDataSourceCondition.class)
    public JpaTransactionManager jpaTransactionManager() {
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
      return transactionManager;
    }
  
    private HibernateJpaVendorAdapter vendorAdaptor() {
      HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      vendorAdapter.setShowSql(true);
      return vendorAdapter;
    }
  
    private static final String[] ENTITYMANAGER_PACKAGES_TO_SCAN = {"io.aiven.klaw.dao"};
  
    @Bean(name = "entityManagerFactory")
    @Conditional(JdbcDataSourceCondition.class)
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
      LocalContainerEntityManagerFactoryBean entityManagerFactoryBean =
          new LocalContainerEntityManagerFactoryBean();
      entityManagerFactoryBean.setJpaVendorAdapter(vendorAdaptor());
      try {
        entityManagerFactoryBean.setDataSource(dataSource());
      } catch (SQLException e) {
        log.error("Exception: ", e);
      }
      entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
      entityManagerFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
      entityManagerFactoryBean.setJpaProperties(jpaHibernateProperties());
  
      return entityManagerFactoryBean;
    }
  
    private Properties jpaHibernateProperties() {
      Properties properties = new Properties();
      properties.put(
          "hibernate.dialect", environment.getProperty("spring.jpa.properties.hibernate.dialect"));
      properties.put("hibernate.show_sql", environment.getProperty("spring.jpa.hibernate.show_sql"));
      properties.put(
          "hibernate.generate-ddl", environment.getProperty("spring.jpa.hibernate.generate-ddl"));
      properties.put("hibernate.ddl-auto", environment.getProperty("spring.jpa.hibernate.ddl-auto"));
      properties.put(
          "hibernate.jdbc.lob.non_contextual_creation",
          environment.getProperty("spring.jpa.hibernate.jdbc.lob.non_contextual_creation"));
  
      return properties;
    }
  }
  