/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* 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.druid.support.monitor.dao;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.sql.DataSource;
import com.alibaba.druid.DruidRuntimeException;
import com.alibaba.druid.pool.DruidDataSourceStatValue;
import com.alibaba.druid.stat.JdbcSqlStatValue;
import com.alibaba.druid.support.http.stat.WebAppStatValue;
import com.alibaba.druid.support.http.stat.WebURIStatValue;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.support.monitor.MonitorContext;
import com.alibaba.druid.support.monitor.annotation.AggregateType;
import com.alibaba.druid.support.monitor.annotation.MField;
import com.alibaba.druid.support.monitor.annotation.MTable;
import com.alibaba.druid.support.monitor.entity.MonitorApp;
import com.alibaba.druid.support.monitor.entity.MonitorCluster;
import com.alibaba.druid.support.monitor.entity.MonitorInstance;
import com.alibaba.druid.support.spring.stat.SpringMethodStatValue;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.druid.util.Utils;
import com.alibaba.druid.wall.WallFunctionStatValue;
import com.alibaba.druid.wall.WallProviderStatValue;
import com.alibaba.druid.wall.WallSqlStatValue;
import com.alibaba.druid.wall.WallTableStatValue;
public class MonitorDaoJdbcImpl implements MonitorDao {
private final static Log LOG = LogFactory.getLog(MonitorDaoJdbcImpl.class);
private DataSource dataSource;
private BeanInfo dataSourceStatBeanInfo = new BeanInfo(
DruidDataSourceStatValue.class);
private BeanInfo sqlStatBeanInfo = new BeanInfo(
JdbcSqlStatValue.class);
private BeanInfo springMethodStatBeanInfo = new BeanInfo(
SpringMethodStatValue.class);
private BeanInfo webURIStatBeanInfo = new BeanInfo(
WebURIStatValue.class);
private BeanInfo webAppStatBeanInfo = new BeanInfo(
WebAppStatValue.class);
private BeanInfo wallProviderStatBeanInfo = new BeanInfo(
WallProviderStatValue.class);
private BeanInfo wallSqlStatBeanInfo = new BeanInfo(
WallSqlStatValue.class);
private BeanInfo wallTableStatBeanInfo = new BeanInfo(
WallTableStatValue.class);
private BeanInfo wallFunctionStatBeanInfo = new BeanInfo(
WallFunctionStatValue.class);
private ConcurrentMap<String, ConcurrentMap<Long, String>> cacheMap = new ConcurrentHashMap<String, ConcurrentMap<Long, String>>();
public MonitorDaoJdbcImpl(){
}
public void createTables(String dbType) {
String[] resources = new String[] { "basic.sql", //
"const.sql", //
"datasource.sql", //
"springmethod.sql", //
"sql.sql", //
"webapp.sql", //
"weburi.sql", "wall.sql" };
for (String item : resources) {
String path = "/support/monitor/" + dbType + "/" + item;
try {
String text = Utils.readFromResource(path);
String[] sqls = text.split(";");
for (String sql : sqls) {
JdbcUtils.execute(dataSource, sql);
}
} catch (Exception ex) {
LOG.error("create table error", ex);
}
}
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void saveSql(MonitorContext ctx, List<DruidDataSourceStatValue> dataSourceList) {
save(dataSourceStatBeanInfo, ctx, dataSourceList);
for (DruidDataSourceStatValue dataSourceStatValue : dataSourceList) {
List<JdbcSqlStatValue> sqlList = dataSourceStatValue.getSqlList();
save(sqlStatBeanInfo, ctx, sqlList);
}
}
@Override
public void saveSpringMethod(MonitorContext ctx, List<SpringMethodStatValue> list) {
save(springMethodStatBeanInfo, ctx, list);
}
@Override
public void saveWebURI(MonitorContext ctx, List<WebURIStatValue> list) {
save(webURIStatBeanInfo, ctx, list);
}
@Override
public void saveSqlWall(MonitorContext ctx, List<WallProviderStatValue> statList) {
save(wallProviderStatBeanInfo, ctx, statList);
for (WallProviderStatValue providerStat : statList) {
save(wallSqlStatBeanInfo, ctx, providerStat.getWhiteList());
save(wallSqlStatBeanInfo, ctx, providerStat.getBlackList());
save(wallTableStatBeanInfo, ctx, providerStat.getTables());
save(wallFunctionStatBeanInfo, ctx, providerStat.getFunctions());
}
}
@Override
public void saveWebApp(MonitorContext ctx, List<WebAppStatValue> list) {
save(webAppStatBeanInfo, ctx, list);
}
@SuppressWarnings("unchecked")
public List<JdbcSqlStatValue> loadSqlList(Map<String, Object> filters) {
return ((List<JdbcSqlStatValue>) load(sqlStatBeanInfo, filters));
}
static Integer getInteger(Map<String, Object> filters, String key) {
Object value = filters.get(key);
if (value == null) {
return null;
}
if (value instanceof Integer) {
return (Integer) value;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
if (value instanceof String) {
String text = (String) value;
if (StringUtils.isEmpty(text)) {
return null;
}
return Integer.parseInt(text);
}
return null;
}
static Date getDate(Map<String, Object> filters, String key) {
Object value = filters.get(key);
if (value == null) {
return null;
}
if (value instanceof Number) {
long millis = ((Number) value).longValue();
return new Date(millis);
}
if (value instanceof String) {
String text = (String) value;
if (StringUtils.isEmpty(text)) {
return null;
}
try {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(text);
} catch (ParseException e) {
LOG.error("parse filter error", e);
return null;
}
}
return null;
}
private List<?> load(BeanInfo beanInfo, Map<String, Object> filters) {
List<Object> list = new ArrayList<Object>();
StringBuilder buf = new StringBuilder();
buf.append("SELECT ");
List<FieldInfo> fields = beanInfo.getFields();
for (int i = 0; i < fields.size(); ++i) {
FieldInfo fieldInfo = fields.get(i);
if (i != 0) {
buf.append(", ");
}
AggregateType aggregateType = fieldInfo.getField().getAnnotation(MField.class).aggregate();
switch (aggregateType) {
case Sum:
buf.append("SUM(");
buf.append(fieldInfo.getColumnName());
buf.append(")");
break;
case Max:
buf.append("MAX(");
buf.append(fieldInfo.getColumnName());
buf.append(")");
break;
case None:
case Last:
default:
buf.append(fieldInfo.getColumnName());
break;
}
}
buf.append("\nFROM ");
buf.append(getTableName(beanInfo));
buf.append("\nWHERE collectTime >= ? AND collectTime <= ? AND domain = ? AND app = ? AND cluster = ?");
Date startTime = getDate(filters, "startTime");
if (startTime == null) {
long now = System.currentTimeMillis();
startTime = new Date(now - 1000 * 60 * 30); // 3 hours
}
Date endTime = getDate(filters, "endTime");
if (endTime == null) {
endTime = new Date(); // now
}
String domain = (String) filters.get("domain");
if (StringUtils.isEmpty(domain)) {
domain = "default";
}
String app = (String) filters.get("app");
if (StringUtils.isEmpty(app)) {
app = "default";
}
String cluster = (String) filters.get("cluster");
if (StringUtils.isEmpty(cluster)) {
cluster = "default";
}
String host = (String) filters.get("host");
if (!StringUtils.isEmpty(host)) {
buf.append("\nAND host = ?");
}
Integer pid = getInteger(filters, "pid");
if (pid != null) {
buf.append("\nAND pid = ?");
}
List<FieldInfo> groupByFields = beanInfo.getGroupByFields();
for (int i = 0; i < groupByFields.size(); ++i) {
if (i == 0) {
buf.append("\nGROUP BY ");
} else {
buf.append(", ");
}
FieldInfo fieldInfo = groupByFields.get(i);
buf.append(fieldInfo.getColumnName());
}
{
Integer offset = (Integer) filters.get("offset");
Integer limit = (Integer) filters.get("limit");
if (limit == null) {
limit = 1000;
}
buf.append("\nLIMIT ");
if (offset != null) {
buf.append(offset);
buf.append(", ");
}
buf.append(limit);
}
String sql = buf.toString();
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
int paramIndex = 1;
stmt.setTimestamp(paramIndex++, new Timestamp(startTime.getTime()));
stmt.setTimestamp(paramIndex++, new Timestamp(endTime.getTime()));
stmt.setString(paramIndex++, domain);
stmt.setString(paramIndex++, app);
stmt.setString(paramIndex++, cluster);
if (!StringUtils.isEmpty(host)) {
stmt.setString(paramIndex++, host);
}
if (pid != null) {
stmt.setInt(paramIndex++, pid);
}
rs = stmt.executeQuery();
while (rs.next()) {
Object object = createInstance(beanInfo);
for (int i = 0; i < fields.size(); ++i) {
FieldInfo field = fields.get(i);
readFieldValue(object, field, rs, i + 1);
}
list.add(object);
}
stmt.close();
} catch (SQLException ex) {
LOG.error("save sql error", ex);
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
for (FieldInfo hashField : beanInfo.getHashFields()) {
loadHashValue(hashField, list, filters);
}
return list;
}
protected void readFieldValue(Object object, FieldInfo field, ResultSet rs, int paramIndex) throws SQLException {
Class<?> fieldType = field.getFieldType();
Object fieldValue = null;
if (fieldType.equals(int.class) || fieldType.equals(Integer.class)) {
fieldValue = rs.getInt(paramIndex);
} else if (fieldType.equals(long.class) || fieldType.equals(Long.class)) {
fieldValue = rs.getLong(paramIndex);
} else if (fieldType.equals(String.class)) {
fieldValue = rs.getString(paramIndex);
} else if (fieldType.equals(Date.class)) {
Timestamp timestamp = rs.getTimestamp(paramIndex);
if (timestamp != null) {
fieldValue = new Date(timestamp.getTime());
}
} else {
throw new UnsupportedOperationException();
}
try {
field.getField().set(object, fieldValue);
} catch (IllegalArgumentException e) {
throw new DruidRuntimeException("set field error" + field.getField(), e);
} catch (IllegalAccessException e) {
throw new DruidRuntimeException("set field error" + field.getField(), e);
}
}
private void loadHashValue(FieldInfo hashField, List<?> list, Map<String, Object> filters) {
String domain = (String) filters.get("domain");
if (StringUtils.isEmpty(domain)) {
domain = "default";
}
String app = (String) filters.get("app");
if (StringUtils.isEmpty(app)) {
app = "default";
}
for (Object statValue : list) {
try {
Long hash = (Long) hashField.field.get(statValue);
String value = cacheGet(hashField.getHashForType(), hash);
if (value == null) {
value = getConstValueFromDb(domain, app, hashField.getHashForType(), hash);
}
hashField.getHashFor().set(statValue, value);
} catch (IllegalArgumentException e) {
throw new DruidRuntimeException("set field error" + hashField.getField(), e);
} catch (IllegalAccessException e) {
throw new DruidRuntimeException("set field error" + hashField.getField(), e);
}
}
}
protected String getConstValueFromDb(String domain, String app, String type, Long hash) {
String sql = "select value from druid_const where domain = ? AND app = ? and type = ? and hash = ?";
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
stmt.setString(1, domain);
stmt.setString(2, app);
stmt.setString(3, type);
stmt.setLong(4, hash);
rs = stmt.executeQuery();
if (rs.next()) {
return rs.getString(1);
}
} catch (SQLException ex) {
LOG.error("save const error error", ex);
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
return null;
}
private void saveHash(FieldInfo hashField, MonitorContext ctx, List<?> list) {
final String hashType = hashField.getHashForType();
for (Object statValue : list) {
try {
Long hash = (Long) hashField.field.get(statValue);
if (!cacheContains(hashField.getHashForType(), hash)) {
String value = (String) hashField.getHashFor().get(statValue);
final String sql = "insert into druid_const (domain, app, type, hash, value) values (?, ?, ?, ?, ?)";
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
stmt.setString(1, ctx.getDomain());
stmt.setString(2, ctx.getApp());
stmt.setString(3, hashType);
stmt.setLong(4, hash);
stmt.setString(5, value);
stmt.execute();
stmt.close();
} catch (SQLException ex) {
// LOG.error("save const error error", ex);
} finally {
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
cachePut(hashField.getHashForType(), hash, value);
}
} catch (IllegalArgumentException e) {
throw new DruidRuntimeException("set field error" + hashField.getField(), e);
} catch (IllegalAccessException e) {
throw new DruidRuntimeException("set field error" + hashField.getField(), e);
}
}
}
private void save(BeanInfo beanInfo, MonitorContext ctx, List<?> list) {
if (list.size() == 0) {
return;
}
for (FieldInfo hashField : beanInfo.getHashFields()) {
saveHash(hashField, ctx, list);
}
String sql = buildInsertSql(beanInfo);
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
for (Object statValue : list) {
setParameterForSqlStat(beanInfo, ctx, stmt, statValue);
stmt.addBatch();
}
stmt.executeBatch();
stmt.close();
} catch (SQLException ex) {
LOG.error("save sql error", ex);
} finally {
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
}
protected void setParameterForSqlStat(BeanInfo beanInfo, //
MonitorContext ctx, //
PreparedStatement stmt, //
Object sqlStat) throws SQLException {
int paramIndex = 1;
setParam(stmt, paramIndex++, ctx.getDomain());
setParam(stmt, paramIndex++, ctx.getApp());
setParam(stmt, paramIndex++, ctx.getCluster());
setParam(stmt, paramIndex++, ctx.getHost());
setParam(stmt, paramIndex++, ctx.getPID());
setParam(stmt, paramIndex++, ctx.getCollectTime());
try {
List<FieldInfo> fields = beanInfo.getFields();
for (FieldInfo field : fields) {
Class<?> fieldType = field.getFieldType();
Object value = field.getField().get(sqlStat);
if (fieldType.equals(int.class) || fieldType.equals(Integer.class)) {
setParam(stmt, paramIndex, (Integer) value);
} else if (fieldType.equals(long.class) || fieldType.equals(Long.class)) {
setParam(stmt, paramIndex, (Long) value);
} else if (fieldType.equals(String.class)) {
setParam(stmt, paramIndex, (String) value);
} else if (fieldType.equals(Date.class)) {
setParam(stmt, paramIndex, (Date) value);
} else if (fieldType.equals(boolean.class) || fieldType.equals(Boolean.class)) {
setParam(stmt, paramIndex, (Boolean) value);
} else {
throw new UnsupportedOperationException("not support type : " + fieldType);
}
paramIndex++;
}
} catch (RuntimeException ex) {
throw ex;
} catch (Exception ex) {
throw new DruidRuntimeException("setParam error", ex);
}
}
public Object createInstance(BeanInfo beanInfo) {
try {
return beanInfo.getClazz().newInstance();
} catch (InstantiationException ex) {
throw new DruidRuntimeException("create instance error", ex);
} catch (IllegalAccessException ex) {
throw new DruidRuntimeException("create instance error", ex);
}
}
public String buildInsertSql(BeanInfo beanInfo) {
String sql = beanInfo.insertSql;
if (sql != null) {
return sql;
}
StringBuilder buf = new StringBuilder();
buf.append("INSERT INTO ") //
.append(getTableName(beanInfo));
buf.append(" (domain, app, cluster, host, pid, collectTime");
List<FieldInfo> fields = beanInfo.getFields();
for (FieldInfo field : fields) {
buf.append(", ");
buf.append(field.getColumnName());
}
buf.append(")\nVALUES (?, ?, ?, ?, ?, ?");
for (int i = 0; i < fields.size(); ++i) {
buf.append(", ?");
}
buf.append(")");
sql = buf.toString();
beanInfo.setInsertSql(sql);
return sql;
}
public String getTableName(BeanInfo beanInfo) {
return beanInfo.getTableName();
}
protected long getSqlHash(String sql) {
return Utils.murmurhash2_64(sql);
}
static void setParam(PreparedStatement stmt, int paramIndex, String value) throws SQLException {
if (value == null) {
stmt.setNull(paramIndex, Types.VARCHAR);
} else {
stmt.setString(paramIndex, value);
}
}
static void setParam(PreparedStatement stmt, int paramIndex, Boolean value) throws SQLException {
if (value == null) {
stmt.setNull(paramIndex, Types.BOOLEAN);
} else {
stmt.setBoolean(paramIndex, value);
}
}
static void setParam(PreparedStatement stmt, int paramIndex, Long value) throws SQLException {
if (value == null || value == 0) {
stmt.setNull(paramIndex, Types.BIGINT);
} else {
stmt.setLong(paramIndex, value);
}
}
static void setParam(PreparedStatement stmt, int paramIndex, Integer value) throws SQLException {
if (value == null || value == 0) {
stmt.setNull(paramIndex, Types.INTEGER);
} else {
stmt.setInt(paramIndex, value);
}
}
static void setParam(PreparedStatement stmt, int paramIndex, Date value) throws SQLException {
if (value == null) {
stmt.setNull(paramIndex, Types.TIMESTAMP);
} else {
stmt.setTimestamp(paramIndex, new Timestamp(value.getTime()));
}
}
public static class BeanInfo {
private final Class<?> clazz;
private final List<FieldInfo> fields = new ArrayList<FieldInfo>();
private final List<FieldInfo> groupByFields = new ArrayList<FieldInfo>();
private final List<FieldInfo> hashFields = new ArrayList<FieldInfo>();
private final String tableName;
private String insertSql;
public BeanInfo(Class<?> clazz){
this.clazz = clazz;
{
MTable annotation = clazz.getAnnotation(MTable.class);
if (annotation == null) {
throw new IllegalArgumentException(clazz.getName() + " not contains @MTable");
}
tableName = annotation.name();
}
for (Field field : clazz.getDeclaredFields()) {
MField annotation = field.getAnnotation(MField.class);
if (annotation == null) {
continue;
}
String columnName = annotation.name();
if (StringUtils.isEmpty(columnName)) {
columnName = field.getName();
}
Field hashFor = null;
String hashForType = null;
if (!StringUtils.isEmpty(annotation.hashFor())) {
try {
hashFor = clazz.getDeclaredField(annotation.hashFor());
hashForType = annotation.hashForType();
} catch (Exception e) {
throw new IllegalStateException("hashFor error", e);
}
}
FieldInfo fieldInfo = new FieldInfo(field, columnName, hashFor, hashForType);
fields.add(fieldInfo);
if (annotation.groupBy()) {
groupByFields.add(fieldInfo);
}
if (hashFor != null) {
hashFields.add(fieldInfo);
}
}
}
public String getTableName() {
return tableName;
}
public Class<?> getClazz() {
return clazz;
}
public String getInsertSql() {
return insertSql;
}
public void setInsertSql(String insertSql) {
this.insertSql = insertSql;
}
public List<FieldInfo> getFields() {
return fields;
}
public List<FieldInfo> getGroupByFields() {
return groupByFields;
}
public List<FieldInfo> getHashFields() {
return hashFields;
}
}
public boolean cacheContains(String type, Long hash) {
Map<Long, String> cache = cacheMap.get(type);
if (cache == null) {
return false;
}
return cache.containsKey(hash);
}
public String cacheGet(String type, Long hash) {
Map<Long, String> cache = cacheMap.get(type);
if (cache == null) {
return null;
}
return cache.get(hash);
}
public void cachePut(String type, Long hash, String value) {
ConcurrentMap<Long, String> cache = cacheMap.get(type);
if (cache == null) {
cacheMap.putIfAbsent(type, new ConcurrentHashMap<Long, String>(16, 0.75f, 1));
cache = cacheMap.get(type);
}
cache.putIfAbsent(hash, value);
}
public static class FieldInfo {
private final Field field;
private final String columnName;
private final Field hashFor;
private final String hashForType;
public FieldInfo(Field field, String columnName, Field hashFor, String hashForType){
this.field = field;
this.columnName = columnName;
this.hashFor = hashFor;
this.hashForType = hashForType;
field.setAccessible(true);
if (hashFor != null) {
hashFor.setAccessible(true);
}
}
public String getHashForType() {
return hashForType;
}
public Field getField() {
return field;
}
public Field getHashFor() {
return hashFor;
}
public String getColumnName() {
return columnName;
}
public Class<?> getFieldType() {
return field.getType();
}
}
public void insertAppIfNotExits(String domain, String app) throws SQLException {
MonitorApp monitorApp = findApp(domain, app);
if (monitorApp != null) {
return;
}
String sql = "insert druid_app (domain, app) values (?, ?)";
JdbcUtils.execute(dataSource, sql, domain, app);
}
public List<MonitorApp> listApp(String domain) throws SQLException {
List<MonitorApp> list = new ArrayList<MonitorApp>();
String sql = "select id, domain, app from druid_app " //
+ " where domain = ?";
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
stmt.setString(1, domain);
rs = stmt.executeQuery();
if (rs.next()) {
list.add(readApp(rs));
}
return list;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
}
public MonitorApp findApp(String domain, String app) throws SQLException {
String sql = "select id, domain, app from druid_app " //
+ " where domain = ? and app = ?";
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
stmt.setString(1, domain);
stmt.setString(2, app);
rs = stmt.executeQuery();
if (rs.next()) {
return readApp(rs);
}
return null;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
}
private MonitorApp readApp(ResultSet rs) throws SQLException {
MonitorApp app = new MonitorApp();
app.setId(rs.getLong(1));
app.setDomain(rs.getString(2));
app.setApp(rs.getString(3));
return app;
}
public List<MonitorCluster> listCluster(String domain, String app) throws SQLException {
List<MonitorCluster> list = new ArrayList<MonitorCluster>();
String sql = "select id, domain, app, cluster from druid_cluster " //
+ " where domain = ?";
if (app != null) {
sql += " and app = ?";
}
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
stmt.setString(1, domain);
if (app != null) {
stmt.setString(2, app);
}
rs = stmt.executeQuery();
if (rs.next()) {
list.add(readCluster(rs));
}
return list;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
}
public void insertClusterIfNotExits(String domain, String app, String cluster) throws SQLException {
MonitorCluster monitorApp = findCluster(domain, app, cluster);
if (monitorApp != null) {
return;
}
String sql = "insert druid_cluster (domain, app, cluster) values (?, ?, ?)";
JdbcUtils.execute(dataSource, sql, domain, app, cluster);
}
public MonitorCluster findCluster(String domain, String app, String cluster) throws SQLException {
String sql = "select id, domain, app, cluster from druid_cluster " //
+ " where domain = ? and app = ? and cluster = ?";
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
stmt.setString(1, domain);
stmt.setString(2, app);
stmt.setString(3, cluster);
rs = stmt.executeQuery();
if (rs.next()) {
return readCluster(rs);
}
return null;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
}
private MonitorCluster readCluster(ResultSet rs) throws SQLException {
MonitorCluster app = new MonitorCluster();
app.setId(rs.getLong(1));
app.setDomain(rs.getString(2));
app.setApp(rs.getString(3));
app.setCluster(rs.getString(4));
return app;
}
public void insertOrUpdateInstance(String domain, String app, String cluster, String host, String ip,
Date startTime, long pid) throws SQLException {
MonitorInstance monitorInst = findInst(domain, app, cluster, host);
if (monitorInst == null) {
String sql = "insert into druid_inst (domain, app, cluster, host, ip, lastActiveTime, lastPID) " //
+ " values (?, ?, ?, ?, ?, ?, ?)";
JdbcUtils.execute(dataSource, sql, domain, app, cluster, host, ip, startTime, pid);
} else {
String sql = "update druid_inst set ip = ?, lastActiveTime = ?, lastPID = ? " //
+ " where domain = ? and app = ? and cluster = ? and host = ? ";
JdbcUtils.execute(dataSource, sql, ip, startTime, pid, domain, app, cluster, host);
}
}
public MonitorInstance findInst(String domain, String app, String cluster, String host) throws SQLException {
String sql = "select id, domain, app, cluster, host, ip, lastActiveTime, lastPID from druid_inst " //
+ " where domain = ? and app = ? and cluster = ? and host = ? " //
+ " limit 1";
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
stmt.setString(1, domain);
stmt.setString(2, app);
stmt.setString(3, cluster);
stmt.setString(4, host);
rs = stmt.executeQuery();
if (rs.next()) {
return readInst(rs);
}
return null;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
}
public List<MonitorInstance> listInst(String domain, String app, String cluster) throws SQLException {
List<MonitorInstance> list = new ArrayList<MonitorInstance>();
String sql = "select id, domain, app, cluster, host, ip, lastActiveTime, lastPID from druid_inst " //
+ "where domain = ?";
if (app != null) {
sql += " and app = ?";
}
if (cluster != null) {
sql += " and cluster = ?";
}
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
int paramIndex = 1;
stmt.setString(paramIndex++, domain);
if (app != null) {
stmt.setString(paramIndex++, app);
}
if (cluster != null) {
stmt.setString(paramIndex++, cluster);
}
rs = stmt.executeQuery();
if (rs.next()) {
list.add(readInst(rs));
}
return list;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
JdbcUtils.close(conn);
}
}
private MonitorInstance readInst(ResultSet rs) throws SQLException {
MonitorInstance inst = new MonitorInstance();
inst.setId(rs.getLong(1));
inst.setDomain(rs.getString(2));
inst.setApp(rs.getString(3));
inst.setCluster(rs.getString(4));
inst.setHost(rs.getString(5));
inst.setIp(rs.getString(6));
inst.setLastActiveTime(rs.getTimestamp(7));
inst.setLastPID(rs.getLong(8));
return inst;
}
}