com.alibaba.otter.common.push.datasource.media.MediaPushDataSource.java Source code

Java tutorial

Introduction

Here is the source code for com.alibaba.otter.common.push.datasource.media.MediaPushDataSource.java

Source

/*
 * Copyright (C) 2010-2101 Alibaba Group Holding Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.otter.common.push.datasource.media;

import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;

import javax.sql.CommonDataSource;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.otter.common.push.supplier.DatasourceChangeCallback;
import com.alibaba.otter.common.push.supplier.DatasourceInfo;
import com.alibaba.otter.common.push.supplier.DatasourceSupplier;
import com.alibaba.otter.common.push.supplier.media.MediaDatasourceSupplier;
import com.alibaba.otter.shared.common.model.config.data.DataMediaType;

/**
 * media datasource support
 * 
 * @author jianghang 2013-4-18 ?03:45:44
 * @version 4.1.8
 */
public class MediaPushDataSource implements DataSource {

    private static final Logger logger = LoggerFactory.getLogger(MediaPushDataSource.class);

    private volatile DataSource delegate;
    private String dbGroupKey;
    private DatasourceSupplier dataSourceSupplier;

    private int maxWait = 60 * 1000;

    private int minIdle = 0;

    private int initialSize = 0;

    private int maxActive = 32;

    private int maxIdle = 32;

    private int numTestsPerEvictionRun = -1;

    private int timeBetweenEvictionRunsMillis = 60 * 1000;

    private int removeAbandonedTimeout = 5 * 60;

    private int minEvictableIdleTimeMillis = 5 * 60 * 1000;

    private String originalUrl;
    private String userName;
    private String password;
    private String driverClassName;
    private DataMediaType dataMediaType;
    private String encoding;

    public MediaPushDataSource(String originalUrl, String userName, String password, String driverClassName,
            DataMediaType dataMediaType, String encoding) {
        this.originalUrl = originalUrl;
        this.userName = userName;
        this.password = password;
        this.driverClassName = driverClassName;
        this.dataMediaType = dataMediaType;
        this.encoding = encoding;
    }

    public synchronized void init() {
        if (!dataMediaType.isMysql()) {
            throw new UnsupportedOperationException("currently only support mysql type");
        }

        if (delegate != null) {
            return;
        }
        if (dataSourceSupplier == null) {
            dataSourceSupplier = MediaDatasourceSupplier.newInstance(dbGroupKey);
            dataSourceSupplier.start();
            dataSourceSupplier.addSwtichCallback(new DatasourceChangeCallback() {

                public void masterChanged(DatasourceInfo newMaster) {
                    String newUrl = buildMysqlUrl(newMaster.getAddress().getAddress().getHostAddress(),
                            newMaster.getAddress().getPort());
                    try {
                        ((BasicDataSource) delegate).close();
                        DataSource newDelegate = doCreateDataSource(newUrl);
                        delegate = newDelegate;
                    } catch (SQLException e) {
                        logger.error("switch master error with url : " + originalUrl, e);
                    }

                }
            });
        }

        DatasourceInfo datasourceInfo = dataSourceSupplier.fetchMaster();
        String url = buildMysqlUrl(datasourceInfo.getAddress().getAddress().getHostAddress(),
                datasourceInfo.getAddress().getPort());

        delegate = doCreateDataSource(url);
    }

    private String buildMysqlUrl(String hostIp, int port) {
        StringBuilder sb = new StringBuilder("jdbc:mysql://");
        sb.append(hostIp).append(":").append(port);
        return sb.toString();
    }

    protected DataSource doCreateDataSource(String url) {
        BasicDataSource dbcpDs = new BasicDataSource();

        dbcpDs.setInitialSize(initialSize);// ?
        dbcpDs.setMaxActive(maxActive);// ?????
        dbcpDs.setMaxIdle(maxIdle);// ??
        dbcpDs.setMinIdle(minIdle);// ?0?
        dbcpDs.setMaxWait(maxWait);// ??-1?
        dbcpDs.setRemoveAbandoned(true);// ??removeAbandonedTimeout
        dbcpDs.setLogAbandoned(true);// ??
        dbcpDs.setRemoveAbandonedTimeout(removeAbandonedTimeout); // ?
        dbcpDs.setNumTestsPerEvictionRun(numTestsPerEvictionRun);// ??
        dbcpDs.setTestOnBorrow(false);// ??
        dbcpDs.setTestOnReturn(false);// ??
        dbcpDs.setTestWhileIdle(true);// ????
        dbcpDs.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); // ????????
        dbcpDs.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); // ???????

        // ??
        dbcpDs.setDriverClassName(driverClassName);
        dbcpDs.setUrl(url);
        dbcpDs.setUsername(userName);
        dbcpDs.setPassword(password);

        if (dataMediaType.isOracle()) {
            dbcpDs.addConnectionProperty("restrictGetTables", "true");
            dbcpDs.setValidationQuery("select 1 from dual");
        } else if (dataMediaType.isMysql()) {
            // open the batch mode for mysql since 5.1.8
            dbcpDs.addConnectionProperty("useServerPrepStmts", "false");
            dbcpDs.addConnectionProperty("rewriteBatchedStatements", "true");
            dbcpDs.addConnectionProperty("zeroDateTimeBehavior", "convertToNull");// 0000-00-00null
            dbcpDs.addConnectionProperty("yearIsDateType", "false");// ??year?date?
            if (StringUtils.isNotEmpty(encoding)) {
                dbcpDs.addConnectionProperty("characterEncoding", encoding);
            }
            dbcpDs.setValidationQuery("select 1");
        } else {
            logger.error("ERROR ## Unknow database type");
        }

        return dbcpDs;
    }

    public synchronized void destory() throws SQLException {
        if (delegate != null) {
            BasicDataSource basicDataSource = (BasicDataSource) delegate;
            basicDataSource.close();
            delegate = null;
        }
        if (dataSourceSupplier != null) {
            dataSourceSupplier.stop();
            dataSourceSupplier = null;
        }
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return delegate.getLogWriter();
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        delegate.setLogWriter(out);
    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        delegate.setLoginTimeout(seconds);

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return delegate.getLoginTimeout();
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return delegate.unwrap(iface);
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return delegate.isWrapperFor(iface);
    }

    @Override
    public Connection getConnection() throws SQLException {
        return delegate.getConnection();
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return delegate.getConnection(username, password);
    }

    // implemented from JDK7 @see http://docs.oracle.com/javase/7/docs/api/javax/sql/CommonDataSource.html#getParentLogger()
    public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
        try {
            Method getParentLoggerMethod = CommonDataSource.class.getDeclaredMethod("getParentLogger",
                    new Class<?>[0]);
            return (java.util.logging.Logger) getParentLoggerMethod.invoke(delegate, new Object[0]);
        } catch (NoSuchMethodException e) {
            throw new SQLFeatureNotSupportedException(e);
        } catch (InvocationTargetException e2) {
            throw new SQLFeatureNotSupportedException(e2);
        } catch (IllegalArgumentException e2) {
            throw new SQLFeatureNotSupportedException(e2);
        } catch (IllegalAccessException e2) {
            throw new SQLFeatureNotSupportedException(e2);
        }
    }

    // =============== setter & getter ================
    public DataSource getDelegate() {
        return delegate;
    }

    public String getDbGroupKey() {
        return dbGroupKey;
    }

    public int getMaxWait() {
        return maxWait;
    }

    public int getMinIdle() {
        return minIdle;
    }

    public int getInitialSize() {
        return initialSize;
    }

    public int getMaxActive() {
        return maxActive;
    }

    public int getMaxIdle() {
        return maxIdle;
    }

    public int getNumTestsPerEvictionRun() {
        return numTestsPerEvictionRun;
    }

    public int getTimeBetweenEvictionRunsMillis() {
        return timeBetweenEvictionRunsMillis;
    }

    public int getRemoveAbandonedTimeout() {
        return removeAbandonedTimeout;
    }

    public int getMinEvictableIdleTimeMillis() {
        return minEvictableIdleTimeMillis;
    }

    public String getOriginalUrl() {
        return originalUrl;
    }

    public String getUserName() {
        return userName;
    }

    public String getPassword() {
        return password;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public DataMediaType getDataMediaType() {
        return dataMediaType;
    }

    public String getEncoding() {
        return encoding;
    }

    public void setDelegate(DataSource delegate) {
        this.delegate = delegate;
    }

    public void setDbGroupKey(String dbGroupKey) {
        this.dbGroupKey = dbGroupKey;
    }

    public void setMaxWait(int maxWait) {
        this.maxWait = maxWait;
    }

    public void setMinIdle(int minIdle) {
        this.minIdle = minIdle;
    }

    public void setInitialSize(int initialSize) {
        this.initialSize = initialSize;
    }

    public void setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }

    public void setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }

    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
    }

    public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {
        this.removeAbandonedTimeout = removeAbandonedTimeout;
    }

    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }

    public void setOriginalUrl(String originalUrl) {
        this.originalUrl = originalUrl;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public void setDataMediaType(DataMediaType dataMediaType) {
        this.dataMediaType = dataMediaType;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

}