Package com.taobao.tddl.jdbc.atom

Source Code of com.taobao.tddl.jdbc.atom.TAtomDsConfHandle

/*(C) 2007-2012 Alibaba Group Holding Limited. 
*This program is free software; you can redistribute it and/or modify 
*it under the terms of the GNU General Public License version 2 as 
* published by the Free Software Foundation. 
* Authors: 
*   junyu <junyu@taobao.com> , shenxun <shenxun@taobao.com>, 
*   linxuan <linxuan@taobao.com> ,qihao <qihao@taobao.com>  
*/ 
package com.taobao.tddl.jdbc.atom;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.taobao.datasource.LocalTxDataSourceDO;
import com.taobao.datasource.TaobaoDataSourceFactory;
import com.taobao.datasource.resource.adapter.jdbc.local.LocalTxDataSource;
import com.taobao.tddl.common.Monitor;
import com.taobao.tddl.common.config.ConfigDataListener;
import com.taobao.tddl.common.util.TStringUtil;
import com.taobao.tddl.jdbc.atom.common.TAtomConURLTools;
import com.taobao.tddl.jdbc.atom.common.TAtomConfParser;
import com.taobao.tddl.jdbc.atom.common.TAtomConstants;
import com.taobao.tddl.jdbc.atom.config.DbConfManager;
import com.taobao.tddl.jdbc.atom.config.DbPasswdManager;
import com.taobao.tddl.jdbc.atom.config.DiamondDbConfManager;
import com.taobao.tddl.jdbc.atom.config.DiamondDbPasswdManager;
import com.taobao.tddl.jdbc.atom.config.object.AtomDbStatusEnum;
import com.taobao.tddl.jdbc.atom.config.object.AtomDbTypeEnum;
import com.taobao.tddl.jdbc.atom.config.object.TAtomDsConfDO;
import com.taobao.tddl.jdbc.atom.exception.AtomAlreadyInitException;
import com.taobao.tddl.jdbc.atom.exception.AtomIllegalException;
import com.taobao.tddl.jdbc.atom.exception.AtomInitialException;
import com.taobao.tddl.jdbc.atom.jdbc.TDataSourceWrapper;
import com.taobao.tddl.jdbc.atom.listener.TAtomDbStatusListener;

/**
* ���ݿ⶯̬�л���Handle�࣬�������ݿ�Ķ�̬�л� ��������������
*
* @author qihao
*
*/
class TAtomDsConfHandle {
  private static Log logger = LogFactory.getLog(TAtomDsConfHandle.class);

  private String appName;

  private String dbKey;

  /**
   * ����ʱ����
   */
  private volatile TAtomDsConfDO runTimeConf = new TAtomDsConfDO();

  /**
   * �������ã����������͵Ķ�̬����
   */
  private TAtomDsConfDO localConf = new TAtomDsConfDO();

  /**
   * ȫ�����ã�Ӧ�����ö��Ĺ���
   */
  private DbConfManager dbConfManager;

  /**
   * �������ö��Ĺ���
   */
  private DbPasswdManager dbPasswdManager;

  /**
   * Jboss����Դͨ��init��ʼ��
   */
  private volatile LocalTxDataSource jbossDataSource;

  /**
   * ���ݿ�״̬�ı�ص�
   */
  private volatile List<TAtomDbStatusListener> dbStatusListeners;

  /**
   * ��ʼ�����Ϊһ����ʼ���������б��ص����ý�ֹ�Ķ�
   */
  private volatile boolean initFalg;

  /**
   * ����Դ������������Ҫ������Դ�����ؽ�����ˢ��ʱ��Ҫ�Ȼ�ø���
   */
  private final ReentrantLock lock = new ReentrantLock();

  /**
   * ��ʼ��������������Ӧ������Դ��ֻ�ܱ�����һ��
   *
   * @throws Exception
   */
  protected void init() throws Exception {
    if (initFalg) {
      throw new AtomAlreadyInitException(
          "[AlreadyInit] double call Init !");
    }
    // 1.��ʼ���������
    if (TStringUtil.isBlank(this.appName) || TStringUtil.isBlank(this.dbKey)) {
      String errorMsg = "[attributeError] TAtomDatasource of appName Or dbKey is Empty !";
      logger.error(errorMsg);
      throw new AtomIllegalException(errorMsg);
    }
    // 2.����dbConfManager
    DiamondDbConfManager defaultDbConfManager = new DiamondDbConfManager();
    defaultDbConfManager.setGlobalConfigDataId(TAtomConstants
        .getGlobalDataId(this.dbKey));
    defaultDbConfManager.setAppConfigDataId(TAtomConstants.getAppDataId(
        this.appName, this.dbKey));
    // ��ʼ��dbConfManager
    defaultDbConfManager.init();
    dbConfManager = defaultDbConfManager;
    // 3.��ȡȫ������
    String globaConfStr = dbConfManager.getGlobalDbConf();
    // ע��ȫ�����ü���
    registerGlobaDbConfListener(defaultDbConfManager);
    if (TStringUtil.isBlank(globaConfStr)) {
      String errorMsg = "[ConfError] read globalConfig is Empty !";
      logger.error(errorMsg);
      throw new AtomInitialException(errorMsg);
    }
    // 4.��ȡӦ������
    String appConfStr = dbConfManager.getAppDbDbConf();
    // ע��Ӧ�����ü���
    registerAppDbConfListener(defaultDbConfManager);
    if (TStringUtil.isBlank(appConfStr)) {
      String errorMsg = "[ConfError] read appConfig is Empty !";
      logger.error(errorMsg);
      throw new AtomInitialException(errorMsg);
    }
    lock.lock();
    try {
      // 5.��������string��TAtomDsConfDO
      runTimeConf = TAtomConfParser.parserTAtomDsConfDO(globaConfStr,
          appConfStr);
      // 6.��������������
      overConfByLocal(localConf, runTimeConf);
      // 7.���û�����ñ������룬���ö������룬��ʼ��passwdManager
      if (TStringUtil.isBlank(this.runTimeConf.getPasswd())) {
        // ���dbKey�Ͷ�Ӧ��userName�Ƿ�Ϊ��
        if (TStringUtil.isBlank(runTimeConf.getUserName())) {
          String errorMsg = "[attributeError] TAtomDatasource of UserName is Empty !";
          logger.error(errorMsg);
          throw new AtomIllegalException(errorMsg);
        }
        DiamondDbPasswdManager diamondDbPasswdManager = new DiamondDbPasswdManager();
        diamondDbPasswdManager.setPasswdConfDataId(TAtomConstants
            .getPasswdDataId(runTimeConf.getDbName(),
                runTimeConf.getDbType(),
                runTimeConf.getUserName()));
        diamondDbPasswdManager.init();
        dbPasswdManager = diamondDbPasswdManager;
        // ��ȡ����
        String passwd = dbPasswdManager.getPasswd();
        registerPasswdConfListener(diamondDbPasswdManager);
        if (TStringUtil.isBlank(passwd)) {
          String errorMsg = "[PasswdError] read passwd is Empty !";
          logger.error(errorMsg);
          throw new AtomInitialException(errorMsg);
        }
        runTimeConf.setPasswd(passwd);
      }
      // 8.ת��tAtomDsConfDO
      LocalTxDataSourceDO localTxDataSourceDO = convertTAtomDsConf2JbossConf(
          this.runTimeConf,
          TAtomConstants.getDbNameStr(this.appName, this.dbKey));
      // 9.������������������ȷֱ���׳��쳣
      if (!checkLocalTxDataSourceDO(localTxDataSourceDO)) {
        String errorMsg = "[ConfigError]init dataSource Prams Error! config is : "
            + localTxDataSourceDO.toString();
        logger.error(errorMsg);
        throw new AtomInitialException(errorMsg);
      }
      // 10.��������Դ
      // �ر�TB-DATASOURCE��JMXע��
      localTxDataSourceDO.setUseJmx(false);
      LocalTxDataSource localTxDataSource = TaobaoDataSourceFactory
          .createLocalTxDataSource(localTxDataSourceDO);
      // 11.�������õ�����Դ��ָ��TAtomDatasource��
      this.jbossDataSource = localTxDataSource;
      clearDataSourceWrapper();
      initFalg = true;
    } finally {
      lock.unlock();
    }
  }

  private void clearDataSourceWrapper() {
    Monitor.removeSnapshotValuesCallback(wrapDataSource);
    wrapDataSource = null;
  }

  /**
   * ע������仯������
   *
   * @param dbPasswdManager
   */
  private void registerPasswdConfListener(DbPasswdManager dbPasswdManager) {
    dbPasswdManager.registerPasswdConfListener(new ConfigDataListener() {
      public void onDataRecieved(String dataId, String data) {
        logger.error("[Passwd HandleData] dataId : " + dataId
            + " data: " + data);
        if (null == data ||TStringUtil.isBlank(data)) {
          return;
        }
        lock.lock();
        try {
          String localPasswd = TAtomDsConfHandle.this.localConf
              .getPasswd();
          if (TStringUtil.isNotBlank(localPasswd)) {
            // �������������passwdֱ�ӷ��ز�֧�ֶ�̬�޸�
            return;
          }
          String newPasswd = TAtomConfParser.parserPasswd(data);
          String runPasswd = TAtomDsConfHandle.this.runTimeConf
              .getPasswd();
          if (!TStringUtil.equals(runPasswd, newPasswd)) {
            TAtomDsConfHandle.this.jbossDataSource
                .setPassword(newPasswd);
            try {
              // ��������Դ
              TAtomDsConfHandle.this.flushDataSource();
              // �����µ����ø�������ʱ������
              TAtomDsConfHandle.this.runTimeConf
                  .setPasswd(newPasswd);
            } catch (Exception e) {
              logger.error(
                  "[Flsh Passwd Error] flush dataSource Error !",
                  e);
            }
          }
        } finally {
          lock.unlock();
        }
      }
    });
  }

  /**
   * ȫ�����ü���,ȫ�����÷����仯�� ��Ҫ����FLUSH����Դ
   *
   * @param defaultDbConfManager
   */
  private void registerGlobaDbConfListener(DbConfManager dbConfManager) {
    dbConfManager.registerGlobaDbConfListener(new ConfigDataListener() {
      public void onDataRecieved(String dataId, String data) {
        logger.error("[GlobaConf HandleData] dataId : " + dataId
            + " data: " + data);
        if (null == data || TStringUtil.isBlank(data)) {
          return;
        }
        lock.lock();
        try {
          String globaConfStr = data;
          // �����ȫ�����÷����仯��������IP,PORT,DBNAME,DBTYPE,STATUS
          TAtomDsConfDO tmpConf = TAtomConfParser
              .parserTAtomDsConfDO(globaConfStr, null);
          TAtomDsConfDO newConf = TAtomDsConfHandle.this.runTimeConf
              .clone();
          // �������͵����ã����ǵ�ǰ������
          newConf.setIp(tmpConf.getIp());
          newConf.setPort(tmpConf.getPort());
          newConf.setDbName(tmpConf.getDbName());
          newConf.setDbType(tmpConf.getDbType());
          newConf.setDbStatus(tmpConf.getDbStatus());
          // ��������������
          overConfByLocal(TAtomDsConfHandle.this.localConf, newConf);
          // ������͹��������ݿ�״̬�� RW/R->NA,ֱ�����ٵ�����Դ������ҵ���߼���������
          if (AtomDbStatusEnum.NA_STATUS != TAtomDsConfHandle.this.runTimeConf
              .getDbStautsEnum()
              && AtomDbStatusEnum.NA_STATUS == tmpConf
                  .getDbStautsEnum()) {
            try {
              TAtomDsConfHandle.this.jbossDataSource.destroy();
              logger.warn("[NA STATUS PUSH] destroy DataSource !");
            } catch (Exception e) {
              logger.error(
                  "[NA STATUS PUSH] destroy DataSource  Error!",
                  e);
            }
          } else {
            // ת��tAtomDsConfDO
            LocalTxDataSourceDO localTxDataSourceDO = convertTAtomDsConf2JbossConf(
                newConf, TAtomConstants.getDbNameStr(
                    TAtomDsConfHandle.this.appName,
                    TAtomDsConfHandle.this.dbKey));
            // ���ת�������Ƿ���ȷ
            if (!checkLocalTxDataSourceDO(localTxDataSourceDO)) {
              logger.error("[GlobaConfError] dataSource Prams Error! dataId : "
                  + dataId + " config : " + data);
              return;
            }
            // ������͵�״̬ʱ NA->RW/R ʱ��Ҫ���´�������Դ��������ˢ��
            if (TAtomDsConfHandle.this.runTimeConf
                .getDbStautsEnum() == AtomDbStatusEnum.NA_STATUS
                && (newConf.getDbStautsEnum() == AtomDbStatusEnum.RW_STATUS || newConf
                    .getDbStautsEnum() == AtomDbStatusEnum.R_STAUTS)) {
              // ��������Դ
              try {
                // �ر�TB-DATASOURCE��JMXע��
                localTxDataSourceDO.setUseJmx(false);
                LocalTxDataSource localTxDataSource = TaobaoDataSourceFactory
                    .createLocalTxDataSource(localTxDataSourceDO);
                TAtomDsConfHandle.this.jbossDataSource = localTxDataSource;
                logger.warn("[NA->RW/R STATUS PUSH] ReCreate DataSource !");
              } catch (Exception e) {
                logger.error(
                    "[NA->RW/R STATUS PUSH] ReCreate DataSource Error!",
                    e);
              }
            } else {
              boolean needFlush = checkGlobaConfChange(
                  TAtomDsConfHandle.this.runTimeConf, newConf);
              // ������������ñ仯�Ƿ���Ҫ�ؽ�����Դ
              if (needFlush) {
                TAtomDsConfHandle.this.jbossDataSource
                    .setConnectionURL(localTxDataSourceDO
                        .getConnectionURL());
                TAtomDsConfHandle.this.jbossDataSource
                    .setDriverClass(localTxDataSourceDO
                        .getDriverClass());
                TAtomDsConfHandle.this.jbossDataSource
                    .setExceptionSorterClassName(localTxDataSourceDO
                        .getExceptionSorterClassName());
                try {
                  // ��������Դ
                  TAtomDsConfHandle.this.flushDataSource();
                } catch (Exception e) {
                  logger.error(
                      "[Flsh GlobaConf Error] flush dataSource Error !",
                      e);
                }
              }
            }
          }
          //�������ݿ�״̬������
          processDbStatusListener(TAtomDsConfHandle.this.runTimeConf.getDbStautsEnum(),
              newConf.getDbStautsEnum());
          //�����µ����ø�������ʱ������
          TAtomDsConfHandle.this.runTimeConf = newConf;
          clearDataSourceWrapper();
        } finally {
          lock.unlock();
        }
      }

      private boolean checkGlobaConfChange(TAtomDsConfDO runConf,
          TAtomDsConfDO newConf) {
        boolean needFlush = false;
        if (!TStringUtil.equals(runConf.getIp(), newConf.getIp())) {
          needFlush = true;
          return needFlush;
        }
        if (!TStringUtil.equals(runConf.getPort(), newConf.getPort())) {
          needFlush = true;
          return needFlush;
        }
        if (!TStringUtil.equals(runConf.getDbName(), newConf.getDbName())) {
          needFlush = true;
          return needFlush;
        }
        if (runConf.getDbTypeEnum() != newConf.getDbTypeEnum()) {
          needFlush = true;
          return needFlush;
        }
        return needFlush;
      }
    });
  }

  /**
   * Ӧ�����ü�������Ӧ�����÷����仯ʱ�����ַ��� �仯�����ã�������������flush����reCreate
   *
   * @param defaultDbConfManager
   */
  private void registerAppDbConfListener(DbConfManager dbConfManager) {
    dbConfManager.registerAppDbConfListener(new ConfigDataListener() {
      public void onDataRecieved(String dataId, String data) {
        logger.error("[AppConf HandleData] dataId : " + dataId
            + " data: " + data);
        if (null == data || TStringUtil.isBlank(data)) {
          return;
        }
        lock.lock();
        try {
          String appConfStr = data;
          TAtomDsConfDO tmpConf = TAtomConfParser
              .parserTAtomDsConfDO(null, appConfStr);
          TAtomDsConfDO newConf = TAtomDsConfHandle.this.runTimeConf
              .clone();
          // ��Щ�������ò��ܱ�������Կ�¡�ϵ����ã�Ȼ���µ�set��ȥ
          newConf.setUserName(tmpConf.getUserName());
          newConf.setMinPoolSize(tmpConf.getMinPoolSize());
          newConf.setMaxPoolSize(tmpConf.getMaxPoolSize());
          newConf.setIdleTimeout(tmpConf.getIdleTimeout());
          newConf.setBlockingTimeout(tmpConf.getBlockingTimeout());
          newConf.setPreparedStatementCacheSize(tmpConf
              .getPreparedStatementCacheSize());
          newConf.setConnectionProperties(tmpConf
              .getConnectionProperties());
          newConf.setOracleConType(tmpConf.getOracleConType());
          // ����3�������ʵ��
          newConf.setWriteRestrictTimes(tmpConf
              .getWriteRestrictTimes());
          newConf.setReadRestrictTimes(tmpConf.getReadRestrictTimes());
          newConf.setThreadCountRestrict(tmpConf
              .getThreadCountRestrict());
          newConf.setTimeSliceInMillis(tmpConf.getTimeSliceInMillis());
          // ��������������
          overConfByLocal(TAtomDsConfHandle.this.localConf, newConf);
          // ת��tAtomDsConfDO
          LocalTxDataSourceDO localTxDataSourceDO = convertTAtomDsConf2JbossConf(
              newConf, TAtomConstants.getDbNameStr(
                  TAtomDsConfHandle.this.appName,
                  TAtomDsConfHandle.this.dbKey));
          // ���ת�������Ƿ���ȷ
          if (!checkLocalTxDataSourceDO(localTxDataSourceDO)) {
            logger.error("[GlobaConfError] dataSource Prams Error! dataId : "
                + dataId + " config : " + data);
            return;
          }
          boolean isNeedReCreate = isNeedReCreate(
              TAtomDsConfHandle.this.runTimeConf, newConf);
          if (isNeedReCreate) {
            try {
              TAtomDsConfHandle.this.jbossDataSource.destroy();
              logger.warn("[destroy OldDataSource] dataId : "
                  + dataId);
              LocalTxDataSource localTxDataSource = TaobaoDataSourceFactory
                  .createLocalTxDataSource(localTxDataSourceDO);
              logger.warn("[create newDataSource] dataId : "
                  + dataId);
              TAtomDsConfHandle.this.jbossDataSource = localTxDataSource;
              clearDataSourceWrapper();
              TAtomDsConfHandle.this.runTimeConf = newConf;
            } catch (Exception e) {
              logger.error(
                  "[Flsh AppConf Error] reCreate dataSource Error ! dataId: "
                      + dataId, e);
            }
          } else {
            boolean isNeedFlush = isNeedFlush(
                TAtomDsConfHandle.this.runTimeConf, newConf);
            /**
             * ��ֵ�仯����ˢ�³��е�����Դ��ֻҪ����runTimeConf���������wrapDataSource
             */
            boolean isRestrictChange = isRestrictChange(
                TAtomDsConfHandle.this.runTimeConf, newConf);
            if (isNeedFlush) {
              TAtomDsConfHandle.this.jbossDataSource
                  .setConnectionURL(localTxDataSourceDO
                      .getConnectionURL());
              TAtomDsConfHandle.this.jbossDataSource
                  .setUserName(localTxDataSourceDO
                      .getUserName());
              try {
                // ��������Դ
                TAtomDsConfHandle.this.flushDataSource();
                // �����µ����ø�������ʱ������
                TAtomDsConfHandle.this.runTimeConf = newConf;
                clearDataSourceWrapper();
              } catch (Exception e) {
                logger.error(
                    "[Flash GlobaConf Error] flush dataSource Error !",
                    e);
              }
            } else if (isRestrictChange) {
              TAtomDsConfHandle.this.runTimeConf = newConf;
              clearDataSourceWrapper();
            }
          }
        } finally {
          lock.unlock();
        }
      }

      private boolean isNeedReCreate(TAtomDsConfDO runConf,
          TAtomDsConfDO newConf) {
        boolean needReCreate = false;
        if (AtomDbTypeEnum.ORACLE == newConf.getDbTypeEnum()) {
          Map<String, String> newProp = newConf
              .getConnectionProperties();
          Map<String, String> runProp = runConf
              .getConnectionProperties();
          if (!runProp.equals(newProp)) {
            return true;
          }
        }
        if (runConf.getMinPoolSize() != newConf.getMinPoolSize()) {
          return true;
        }
        if (runConf.getMaxPoolSize() != newConf.getMaxPoolSize()) {
          return true;
        }
        if (runConf.getBlockingTimeout() != newConf
            .getBlockingTimeout()) {
          return true;
        }
        if (runConf.getIdleTimeout() != newConf.getIdleTimeout()) {
          return true;
        }
        if (runConf.getPreparedStatementCacheSize() != newConf
            .getPreparedStatementCacheSize()) {
          return true;
        }
        return needReCreate;
      }

      private boolean isNeedFlush(TAtomDsConfDO runConf,
          TAtomDsConfDO newConf) {
        boolean needFlush = false;
        if (AtomDbTypeEnum.MYSQL == newConf.getDbTypeEnum()) {
          Map<String, String> newProp = newConf
              .getConnectionProperties();
          Map<String, String> runProp = runConf
              .getConnectionProperties();
          if (!runProp.equals(newProp)) {
            return true;
          }
        }
        if (!TStringUtil.equals(runConf.getUserName(),
            newConf.getUserName())) {
          return true;
        }
        if (!TStringUtil.equals(runConf.getPasswd(), newConf.getPasswd())) {
          return true;
        }
        return needFlush;
      }

      private boolean isRestrictChange(TAtomDsConfDO runConf,
          TAtomDsConfDO newConf) {
        if (runConf.getReadRestrictTimes() != newConf
            .getReadRestrictTimes()) {
          return true;
        }

        if (runConf.getWriteRestrictTimes() != newConf
            .getWriteRestrictTimes()) {
          return true;
        }

        if (runConf.getThreadCountRestrict() != newConf
            .getThreadCountRestrict()) {
          return true;
        }

        if (runConf.getTimeSliceInMillis() != newConf
            .getTimeSliceInMillis()) {
          return true;
        }

        return false;
      }
    });
  }

  /**
   * ��TAtomDsConfDOת����LocalTxDataSourceDO
   *
   * @param tAtomDsConfDO
   * @return
   */
  @SuppressWarnings("rawtypes")
  protected static LocalTxDataSourceDO convertTAtomDsConf2JbossConf(TAtomDsConfDO tAtomDsConfDO, String dbName) {
    LocalTxDataSourceDO localTxDataSourceDO = new LocalTxDataSourceDO();
    if (TStringUtil.isNotBlank(dbName)) {
      localTxDataSourceDO.setJndiName(dbName);
    }
    localTxDataSourceDO.setUserName(tAtomDsConfDO.getUserName());
    localTxDataSourceDO.setPassword(tAtomDsConfDO.getPasswd());
    localTxDataSourceDO.setDriverClass(tAtomDsConfDO.getDriverClass());
    localTxDataSourceDO.setExceptionSorterClassName(tAtomDsConfDO.getSorterClass());
    //�������ݿ���������conURL��setConnectionProperties
    if (AtomDbTypeEnum.ORACLE == tAtomDsConfDO.getDbTypeEnum()) {
      String conUlr = TAtomConURLTools.getOracleConURL(tAtomDsConfDO.getIp(), tAtomDsConfDO.getPort(),
          tAtomDsConfDO.getDbName(), tAtomDsConfDO.getOracleConType());
      localTxDataSourceDO.setConnectionURL(conUlr);
      //�����oracleû������ConnectionProperties����Ը�Ĭ�ϵ�
      if (!tAtomDsConfDO.getConnectionProperties().isEmpty()) {
        localTxDataSourceDO.setConnectionProperties(tAtomDsConfDO.getConnectionProperties());
      } else {
        localTxDataSourceDO.setConnectionProperties(TAtomConstants.DEFAULT_ORACLE_CONNECTION_PROPERTIES);
      }
    } else if (AtomDbTypeEnum.MYSQL == tAtomDsConfDO.getDbTypeEnum()) {
      String conUlr = TAtomConURLTools.getMySqlConURL(tAtomDsConfDO.getIp(), tAtomDsConfDO.getPort(),
          tAtomDsConfDO.getDbName(), tAtomDsConfDO.getConnectionProperties());
      localTxDataSourceDO.setConnectionURL(conUlr);
      //��������ҵ�mysqlDriver�е�Valid��ʹ�ã���������valid
      try {
        Class validClass = Class.forName(TAtomConstants.DEFAULT_MYSQL_VALID_CONNECTION_CHECKERCLASS);
        if (null != validClass) {
          localTxDataSourceDO
              .setValidConnectionCheckerClassName(TAtomConstants.DEFAULT_MYSQL_VALID_CONNECTION_CHECKERCLASS);
        } else {
          logger.warn("MYSQL Driver is Not Suport "
              + TAtomConstants.DEFAULT_MYSQL_VALID_CONNECTION_CHECKERCLASS);
        }
      } catch (ClassNotFoundException e) {
        logger.warn("MYSQL Driver is Not Suport " + TAtomConstants.DEFAULT_MYSQL_VALID_CONNECTION_CHECKERCLASS);
      } catch (NoClassDefFoundError e) {
        logger.warn("MYSQL Driver is Not Suport " + TAtomConstants.DEFAULT_MYSQL_VALID_CONNECTION_CHECKERCLASS);
      }
     
      //��������ҵ�mysqlDriver�е�integrationSorter��ʹ�÷���ʹ��Ĭ�ϵ�
      try {
        Class integrationSorterCalss = Class.forName(TAtomConstants.MYSQL_INTEGRATION_SORTER_CLASS);
        if (null != integrationSorterCalss) {
          localTxDataSourceDO.setExceptionSorterClassName(TAtomConstants.MYSQL_INTEGRATION_SORTER_CLASS);
        } else {
          localTxDataSourceDO.setExceptionSorterClassName(TAtomConstants.DEFAULT_MYSQL_SORTER_CLASS);
          logger.warn("MYSQL Driver is Not Suport " + TAtomConstants.MYSQL_INTEGRATION_SORTER_CLASS
              + " use default sorter " + TAtomConstants.DEFAULT_MYSQL_SORTER_CLASS);
        }
      } catch (ClassNotFoundException e) {
        logger.warn("MYSQL Driver is Not Suport " + TAtomConstants.MYSQL_INTEGRATION_SORTER_CLASS
            + " use default sorter " + TAtomConstants.DEFAULT_MYSQL_SORTER_CLASS);
      } catch (NoClassDefFoundError e){
        logger.warn("MYSQL Driver is Not Suport " + TAtomConstants.MYSQL_INTEGRATION_SORTER_CLASS
            + " use default sorter " + TAtomConstants.DEFAULT_MYSQL_SORTER_CLASS);
      }
    }
    localTxDataSourceDO.setMinPoolSize(tAtomDsConfDO.getMinPoolSize());
    localTxDataSourceDO.setMaxPoolSize(tAtomDsConfDO.getMaxPoolSize());
    localTxDataSourceDO.setPreparedStatementCacheSize(tAtomDsConfDO.getPreparedStatementCacheSize());
    if (tAtomDsConfDO.getIdleTimeout() > 0) {
      localTxDataSourceDO.setIdleTimeoutMinutes(tAtomDsConfDO.getIdleTimeout());
    }
    if (tAtomDsConfDO.getBlockingTimeout() > 0) {
      localTxDataSourceDO.setBlockingTimeoutMillis(tAtomDsConfDO.getBlockingTimeout());
    }
    return localTxDataSourceDO;
  }

  protected static boolean checkLocalTxDataSourceDO(
      LocalTxDataSourceDO localTxDataSourceDO) {
    if (null == localTxDataSourceDO) {
      return false;
    }

    if (TStringUtil.isBlank(localTxDataSourceDO.getConnectionURL())) {
      logger.error("[DsConfig Check] ConnectionURL is Empty !");
      return false;
    }

    if (TStringUtil.isBlank(localTxDataSourceDO.getUserName())) {
      logger.error("[DsConfig Check] UserName is Empty !");
      return false;
    }

    if (TStringUtil.isBlank(localTxDataSourceDO.getPassword())) {
      logger.error("[DsConfig Check] Password is Empty !");
      return false;
    }

    if (TStringUtil.isBlank(localTxDataSourceDO.getDriverClass())) {
      logger.error("[DsConfig Check] DriverClass is Empty !");
      return false;
    }

    if (localTxDataSourceDO.getMinPoolSize() < 1) {
      logger.error("[DsConfig Check] MinPoolSize Error size is:"
          + localTxDataSourceDO.getMinPoolSize());
      return false;
    }

    if (localTxDataSourceDO.getMaxPoolSize() < 1) {
      logger.error("[DsConfig Check] MaxPoolSize Error size is:"
          + localTxDataSourceDO.getMaxPoolSize());
      return false;
    }

    if (localTxDataSourceDO.getMinPoolSize() > localTxDataSourceDO
        .getMaxPoolSize()) {
      logger.error("[DsConfig Check] MinPoolSize Over MaxPoolSize Minsize is:"
          + localTxDataSourceDO.getMinPoolSize()
          + "MaxSize is :"
          + localTxDataSourceDO.getMaxPoolSize());
      return false;
    }
    return true;
  }

  /**
   * ���ñ������ø��Ǵ����TAtomDsConfDO������
   *
   * @param tAtomDsConfDO
   */
  private void overConfByLocal(TAtomDsConfDO localDsConfDO,
      TAtomDsConfDO newDsConfDO) {
    if (null == newDsConfDO || null == localDsConfDO) {
      return;
    }
    if (TStringUtil.isNotBlank(localDsConfDO.getDriverClass())) {
      newDsConfDO.setDriverClass(localDsConfDO.getDriverClass());
    }
    if (TStringUtil.isNotBlank(localDsConfDO.getSorterClass())) {
      newDsConfDO.setSorterClass(localDsConfDO.getSorterClass());
    }
    if (TStringUtil.isNotBlank(localDsConfDO.getPasswd())) {
      newDsConfDO.setPasswd(localDsConfDO.getPasswd());
    }
    if (null != localDsConfDO.getConnectionProperties()
        && !localDsConfDO.getConnectionProperties().isEmpty()) {
      newDsConfDO.setConnectionProperties(localDsConfDO
          .getConnectionProperties());
    }
  }

  /**
   * Datasource �İ�װ��
   */
  private volatile TDataSourceWrapper wrapDataSource = null;

  public DataSource getDataSource() throws SQLException {
    if (wrapDataSource == null) {
      lock.lock();
      try {
        if (wrapDataSource != null) {
          // ˫�����
          return wrapDataSource;
        }
        String errorMsg = "";
        if (null == jbossDataSource) {
          errorMsg = "[InitError] TAtomDsConfHandle maybe forget init !";
          logger.error(errorMsg);
          throw new SQLException(errorMsg);
        }
        DataSource dataSource = jbossDataSource.getDatasource();
        if (null == dataSource) {
          errorMsg = "[InitError] TAtomDsConfHandle maybe init fail !";
          logger.error(errorMsg);
          throw new SQLException(errorMsg);
        }
        // ������ݿ�״̬������ֱ���׳��쳣
        if (null == this.getStatus()) {
          errorMsg = "[DB Stats Error] DbStatus is Null: "
              + this.getDbKey();
          logger.error(errorMsg);
          throw new SQLException(errorMsg);
        }
        TDataSourceWrapper tDataSourceWrapper = new TDataSourceWrapper(
            dataSource, runTimeConf);
        tDataSourceWrapper.setDatasourceName(dbKey);
        tDataSourceWrapper.setDatasourceIp(runTimeConf.getIp());
        tDataSourceWrapper.setDatasourcePort(runTimeConf.getPort());
        tDataSourceWrapper.setDatasourceRealDbName(runTimeConf.getDbName());
        tDataSourceWrapper.setDbStatus(getStatus());
        logger.warn("set datasource key: " + dbKey);
        wrapDataSource = tDataSourceWrapper;

        return wrapDataSource;

      } finally {
        lock.unlock();
      }
    } else {
      return wrapDataSource;
    }
  }

  public void flushDataSource() {
    if (null != this.jbossDataSource) {
      logger.warn("[DataSource Flush] Start!");
      this.jbossDataSource.flush();
      logger.warn("[DataSource Flush] End!");
    }
  }

  protected void destroyDataSource() throws Exception {
    if (null != this.jbossDataSource) {
      logger.warn("[DataSource Stop] Start!");
      this.jbossDataSource.destroy();
      if (null != this.dbConfManager) {
        this.dbConfManager.stopDbConfManager();
      }
      if (null != this.dbPasswdManager) {
        this.dbPasswdManager.stopDbPasswdManager();
      }
      logger.warn("[DataSource Stop] End!");
    }

  }

  void setSingleInGroup(boolean isSingleInGroup) {
    this.runTimeConf.setSingleInGroup(isSingleInGroup);
  }

  public void setAppName(String appName) throws AtomAlreadyInitException {
    if (initFalg) {
      throw new AtomAlreadyInitException(
          "[AlreadyInit] couldn't Reset appName !");
    }
    this.appName = appName;
  }

  public void setDbKey(String dbKey) throws AtomAlreadyInitException {
    if (initFalg) {
      throw new AtomAlreadyInitException(
          "[AlreadyInit] couldn't Reset dbKey !");
    }
    this.dbKey = dbKey;
  }

  public void setLocalPasswd(String passwd) throws AtomAlreadyInitException {
    if (initFalg) {
      throw new AtomAlreadyInitException(
          "[AlreadyInit] couldn't Reset passwd !");
    }
    this.localConf.setPasswd(passwd);
  }

  public void setLocalConnectionProperties(Map<String, String> map)
      throws AtomAlreadyInitException {
    if (initFalg) {
      throw new AtomAlreadyInitException(
          "[AlreadyInit] couldn't Reset connectionProperties !");
    }
    this.localConf.setConnectionProperties(map);
  }

  public void setLocalDriverClass(String driverClass)
      throws AtomAlreadyInitException {
    if (initFalg) {
      throw new AtomAlreadyInitException(
          "[AlreadyInit] couldn't Reset driverClass !");
    }
    this.localConf.setDriverClass(driverClass);
  }

  public void setLocalSorterClass(String sorterClass)
      throws AtomAlreadyInitException {
    if (initFalg) {
      throw new AtomAlreadyInitException(
          "[AlreadyInit] couldn't Reset sorterClass !");
    }
    this.localConf.setSorterClass(sorterClass);
  }

  public String getAppName() {
    return appName;
  }

  public String getDbKey() {
    return dbKey;
  }

  public AtomDbStatusEnum getStatus() {
    return this.runTimeConf.getDbStautsEnum();
  }

  public AtomDbTypeEnum getDbType() {
    return this.runTimeConf.getDbTypeEnum();
  }

  public void setDbStatusListeners(
      List<TAtomDbStatusListener> dbStatusListeners) {
    this.dbStatusListeners = dbStatusListeners;
  }

  private void processDbStatusListener(AtomDbStatusEnum oldStatus,
      AtomDbStatusEnum newStatus) {
    if (null != oldStatus && oldStatus != newStatus) {
      if (null != dbStatusListeners) {
        for (TAtomDbStatusListener statusListener : dbStatusListeners) {
          try {
            statusListener.handleData(oldStatus, newStatus);
          } catch (Exception e) {
            logger.error("[call StatusListenner Error] !", e);
            continue;
          }
        }
      }
    }
  }
}
TOP

Related Classes of com.taobao.tddl.jdbc.atom.TAtomDsConfHandle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.