/*
* Copyright 1999-2012 Alibaba Group.
*
* 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.cobar.manager.dao.delegate;
import static com.alibaba.cobar.manager.util.SQLDefine.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.StatementCallback;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.alibaba.cobar.manager.dao.CobarAdapterDAO;
import com.alibaba.cobar.manager.dataobject.cobarnode.CommandStatus;
import com.alibaba.cobar.manager.dataobject.cobarnode.ConnectionStatus;
import com.alibaba.cobar.manager.dataobject.cobarnode.DataNodesStatus;
import com.alibaba.cobar.manager.dataobject.cobarnode.DataSources;
import com.alibaba.cobar.manager.dataobject.cobarnode.ProcessorStatus;
import com.alibaba.cobar.manager.dataobject.cobarnode.ServerStatus;
import com.alibaba.cobar.manager.dataobject.cobarnode.ThreadPoolStatus;
import com.alibaba.cobar.manager.dataobject.cobarnode.TimeStamp;
import com.alibaba.cobar.manager.util.Pair;
/**
* @author haiqing.zhuhq 2011-6-20
*/
/**
* ????cobar???????????
*/
@SuppressWarnings("unchecked")
public class CobarAdapter extends JdbcDaoSupport implements DisposableBean, CobarAdapterDAO {
@Override
protected void checkDaoConfig() {
super.checkDaoConfig();
DataSource ds = getDataSource();
if (!(ds instanceof DataSource)) {
throw new IllegalArgumentException("property 'dataSource' is not type of " + DataSource.class.getName());
}
}
@Override
public void destroy() throws Exception {
((BasicDataSource) getDataSource()).close();
}
private static class TimeStampRowMapper implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
TimeStamp ts = new TimeStamp();
ts.setTimestamp(rs.getLong(TIMESTAMP));
return ts;
}
}
private static class ServerStatusRowMapper implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
ServerStatus s = new ServerStatus();
s.setUptime(rs.getString(UPTIME));
s.setStatus(rs.getString(STATUS));
s.setReloadTime(rs.getLong(RELOAD_TIME));
s.setRollbackTime(rs.getLong(ROLLBACK_TIME));
s.setUsedMemory(rs.getLong(USED_MEMORY));
s.setTotalMemory(rs.getLong(TOTAL_MEMORY));
s.setMaxMemory(rs.getLong(MAX_MEMORY));
s.setCharSet(rs.getString(S_CHARSET));
return s;
}
}
private static class ProccessorStatusRowMapper implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
ProcessorStatus p = new ProcessorStatus();
p.setProcessorId(rs.getString(P_NAME));
p.setNetIn(rs.getLong(P_NET_IN));
p.setNetOut(rs.getLong(P_NET_OUT));
p.setrQueue(rs.getInt(R_QUEUE));
p.setwQueue(rs.getInt(W_QUEUE));
p.setConnections(rs.getInt(FC_COUNT));
p.setFreeBuffer(rs.getLong(FREE_BUFFER));
p.setTotalBuffer(rs.getLong(TOTAL_BUFFER));
p.setRequestCount(rs.getLong(REACT_COUNT));
p.setBc_count(rs.getLong(BC_COUNT));
p.setSampleTimeStamp(System.currentTimeMillis());
return p;
}
}
private static class ThreadPoolStatusRowMapper implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
ThreadPoolStatus tp = new ThreadPoolStatus();
tp.setThreadPoolName(rs.getString(TP_NAME));
tp.setActiveSize(rs.getInt(ACTIVE_COUNT));
tp.setCompletedTask(rs.getLong(COMPLETED_TASK));
tp.setPoolSize(rs.getInt(POOL_SIZE));
tp.setTaskQueue(rs.getInt(TASK_QUEUE_SIZE));
tp.setTotalTask(rs.getLong(TOTAL_TASK));
return tp;
}
}
private static class DataNodesStatusRowMapper implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
DataNodesStatus ds = new DataNodesStatus();
ds.setPoolName(rs.getString(POOL_NAME));
ds.setDataSource(rs.getString(DS));
if (null == rs.getString(TYPE)) {
ds.setType("NULL");
ds.setActive(-1);
ds.setIdle(-1);
ds.setIndex(-1);
ds.setSize(-1);
} else {
ds.setType(rs.getString(TYPE));
ds.setActive(rs.getInt(ACTIVE));
ds.setIdle(rs.getInt(IDLE));
ds.setSize(rs.getInt(SIZE));
ds.setIndex(rs.getInt(INDEX));
}
ds.setExecuteCount(rs.getLong(EXECUTE));
ds.setMaxTime(rs.getLong(MAX_TIME));
ds.setMaxSQL(rs.getLong(MAX_SQL));
ds.setRecoveryTime(rs.getLong(RECOVERY_TIME));
ds.setTotalTime(rs.getLong(TOTAL_TIME));
ds.setSampleTimeStamp(System.currentTimeMillis());
return ds;
}
}
private static class ConnectionRowMapper implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
ConnectionStatus c = new ConnectionStatus();
c.setProcessor(rs.getString(C_PROCESSOR));
c.setHost(rs.getString(HOST));
c.setPort(rs.getInt(PORT));
c.setLocal_port(rs.getInt(LOCAL_PORT));
if (null == rs.getString(SCHEMA)) {
c.setSchema("NULL");
} else {
c.setSchema(rs.getString(SCHEMA));
}
c.setCharset(rs.getString(CHARSET));
c.setNetIn(rs.getLong(C_NET_IN));
c.setNetOut(rs.getLong(C_NET_OUT));
c.setAliveTime(rs.getLong(ALIVE_TIME));
c.setAttempsCount(rs.getInt(ATTEMPS_COUNT));
c.setRecvBuffer(rs.getInt(RECV_BUFFER));
c.setSendQueue(rs.getInt(SEND_QUEUE));
c.setId(rs.getLong(ID));
c.setChannel(rs.getInt(CHENNEL));
c.setSampleTimeStamp(System.currentTimeMillis());
return c;
}
}
private static class CommandStatusRowMapper implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
CommandStatus cmd = new CommandStatus();
cmd.setProcessorId(rs.getString(CMD_PROCESSOR));
cmd.setQuery(rs.getLong(QUERY));
cmd.setStmtExecute(rs.getLong(STMT_EXECUTE));
cmd.setStmtPrepared(rs.getLong(STMT_PREPARED));
cmd.setStmtClose(rs.getLong(STMT_CLOSE));
cmd.setQuit(rs.getLong(QUIT));
cmd.setPing(rs.getLong(PING));
cmd.setOther(rs.getLong(OTHER));
cmd.setKill(rs.getLong(KILL));
cmd.setInitDB(rs.getLong(INIT_DB));
cmd.setSampleTimeStamp(System.currentTimeMillis());
return cmd;
}
}
private static class DataSourceRowMapper implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
DataSources ds = new DataSources();
ds.setName(rs.getString(DS_NAME));
ds.setType(rs.getString(DS_TYPE));
ds.setHost(rs.getString(DS_HOST));
ds.setPort(rs.getInt(DS_PORT));
ds.setSchema(rs.getString(DS_SCHEMA));
return ds;
}
}
private TimeStampRowMapper timeStampRowMapper = new TimeStampRowMapper();
private ServerStatusRowMapper serverStatusRowMapper = new ServerStatusRowMapper();
private ProccessorStatusRowMapper proccessorStatusRowMapper = new ProccessorStatusRowMapper();
private ThreadPoolStatusRowMapper threadPoolStatusRowMapper = new ThreadPoolStatusRowMapper();
private DataNodesStatusRowMapper dataNodesStatusRowMapper = new DataNodesStatusRowMapper();
private ConnectionRowMapper connectionRowMapper = new ConnectionRowMapper();
private CommandStatusRowMapper commandStatusRowMapper = new CommandStatusRowMapper();
private DataSourceRowMapper dataSourcesRowMapper = new DataSourceRowMapper();
@Override
public TimeStamp getCurrentTime() {
try {
return (TimeStamp) getJdbcTemplate().queryForObject(SHOW_TIME_CURRENT, timeStampRowMapper);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
@Override
public TimeStamp getStartUpTime() {
try {
return (TimeStamp) getJdbcTemplate().queryForObject(SHOW_TIME_STARTUP, timeStampRowMapper);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
@Override
public String getVersion() {
try {
return (String) getJdbcTemplate().queryForObject(SHOW_VERSION, new RowMapper() {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
String version = rs.getString(VERSION);
return version;
}
});
} catch (EmptyResultDataAccessException e) {
logger.error(e.getMessage(), e);
return null;
}
}
@Override
public ServerStatus getServerStatus() {
try {
return (ServerStatus) getJdbcTemplate().queryForObject(SHOW_SERVER, serverStatusRowMapper);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
@Override
public List<ProcessorStatus> listProccessorStatus() {
return getJdbcTemplate().query(SHOW_PROCESSOR, proccessorStatusRowMapper);
}
@Override
public List<ThreadPoolStatus> listThreadPoolStatus() {
return getJdbcTemplate().query(SHOW_THREADPOOL, threadPoolStatusRowMapper);
}
@Override
public List<String> listDataBases() {
return getJdbcTemplate().query(SHOW_DATABASE, new RowMapper() {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
String db = rs.getString(DATABASE);
return db;
}
});
}
@Override
public List<DataNodesStatus> listDataNodes() {
return getJdbcTemplate().query(SHOW_DATANODE, dataNodesStatusRowMapper);
}
@Override
public List<DataSources> listDataSources() {
return getJdbcTemplate().query(SHOW_DATASOURCE, dataSourcesRowMapper);
}
@Override
public List<ConnectionStatus> listConnectionStatus() {
return getJdbcTemplate().query(SHOW_CONNECTION, connectionRowMapper);
}
@Override
public List<CommandStatus> listCommandStatus() {
return getJdbcTemplate().query(SHOW_COMMAND, commandStatusRowMapper);
}
@Override
public Pair<Long, Long> getCurrentTimeMillis() {
return (Pair<Long, Long>) getJdbcTemplate().execute(new StatementCallback() {
@Override
public Object doInStatement(Statement stmt) throws SQLException, DataAccessException {
ResultSet rs = null;
try {
long time1 = System.currentTimeMillis();
rs = stmt.executeQuery("show @@status.time");
long time2 = System.currentTimeMillis();
if (rs.next()) {
return new Pair<Long, Long>(time1 + (time2 - time1) / 2, rs.getLong(1));
} else {
throw new IncorrectResultSizeDataAccessException(1, 0);
}
} finally {
if (rs != null) {
rs.close();
}
}
}
});
}
@Override
public int switchDataNode(String datanodes, int index) {
StringBuilder sb = new StringBuilder(SWITCH_DATASOURCE);
sb.append(datanodes);
sb.append(":").append(index);
String sql = sb.toString();
return getJdbcTemplate().update(sql);
}
@Override
public int killConnection(long id) {
StringBuilder sb = new StringBuilder(KILL_CONNECTION);
sb.append(id);
String sql = sb.toString();
return getJdbcTemplate().update(sql);
}
@Override
public boolean reloadConfig() {
try {
getJdbcTemplate().update(RELOAD_CONFIG);
} catch (Exception e) {
return false;
}
return true;
}
@Override
public boolean rollbackConfig() {
try {
getJdbcTemplate().update(ROLLBACK_CONFIG);
} catch (Exception e) {
return false;
}
return true;
}
@Override
public int stopHeartbeat(String datanodes, int time) {
int t = time * 3600;
StringBuilder sb = new StringBuilder(STOP_HEARTBEAT);
sb.append(datanodes);
sb.append(":").append(t);
String sql = sb.toString();
return getJdbcTemplate().update(sql);
}
@Override
public boolean checkConnection() {
try {
return null != getVersion();
} catch (CannotGetJdbcConnectionException ex) {
logger.error(new StringBuilder("checkConnection error for Url:").append(((BasicDataSource) this.getDataSource()).getUrl())
.toString());
return false;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return false;
}
}
@Override
public boolean setCobarStatus(boolean status) {
try {
if (status) {
getJdbcTemplate().update(ONLINE);
} else {
getJdbcTemplate().update(OFFLINE);
}
return true;
} catch (Exception e) {
return false;
}
}
}