public class CobarFailureDetecter extends DefaultDataSourceFailureDetecter { private static final Log LOG = LogFactory.getLog(CobarFailureDetecter.class); private int queryTimeoutSeconds = 30; public CobarFailureDetecter() { this.setValidateSql("SHOW COBAR_STATUS"); } public int getQueryTimeoutSeconds() { return queryTimeoutSeconds; } public void setQueryTimeoutSeconds(int queryTimeoutSeconds) { this.queryTimeoutSeconds = queryTimeoutSeconds; } public boolean isValidConnection(DruidDataSource dataSource, Connection conn) { Statement stmt = null; ResultSet rs = null; try { stmt = conn.createStatement(); stmt.setQueryTimeout(queryTimeoutSeconds); rs = stmt.executeQuery(getValidateSql()); if (!rs.next()) { return false; } String status = rs.getString(1); if ("on".equalsIgnoreCase(status)) { return true; } else { return false; } } catch (Exception ex) { LOG.error("check datasource valid errror", ex); return false; } finally { JdbcUtils.close(rs); JdbcUtils.close(stmt); } } }
public class MockDriver implements Driver, MockDriverMBean { private static final Log LOG = LogFactory.getLog(MockDriver.class); public static final MockExecuteHandler DEFAULT_HANDLER = new MySqlMockExecuteHandlerImpl(); private String prefix = "jdbc:fake:"; private String mockPrefix = "jdbc:mock:"; private MockExecuteHandler executeHandler = DEFAULT_HANDLER; public static final MockDriver instance = new MockDriver(); private final AtomicLong connectCount = new AtomicLong(); private final AtomicLong connectionCloseCount = new AtomicLong(); private final AtomicLong connectionIdSeed = new AtomicLong(1000L); private final List<MockConnection> connections = new CopyOnWriteArrayList<MockConnection>(); private long idleTimeCount = 1000 * 60 * 3; private boolean logExecuteQueryEnable = true; private static final String MBEAN_NAME = "com.alibaba.druid:type=MockDriver"; static { registerDriver(instance); } public boolean isLogExecuteQueryEnable() { return logExecuteQueryEnable; } public void setLogExecuteQueryEnable(boolean logExecuteQueryEnable) { this.logExecuteQueryEnable = logExecuteQueryEnable; } public long getIdleTimeCount() { return idleTimeCount; } public void setIdleTimeCount(long idleTimeCount) { this.idleTimeCount = idleTimeCount; } public long generateConnectionId() { return connectionIdSeed.incrementAndGet(); } public void closeAllConnections() throws SQLException { for (int i = 0, size = this.connections.size(); i < size; ++i) { Connection conn = this.connections.get(size - i - 1); conn.close(); } } public int getConnectionsSize() { return this.connections.size(); } public List<MockConnection> getConnections() { return connections; } protected void incrementConnectionCloseCount() { connectionCloseCount.incrementAndGet(); } public long getConnectionCloseCount() { return connectionCloseCount.get(); } protected void afterConnectionClose(MockConnection conn) { connectionCloseCount.incrementAndGet(); connections.remove(conn); if (LOG.isDebugEnabled()) { LOG.debug("conn-" + conn.getId() + " close"); } } public static boolean registerDriver(Driver driver) { try { DriverManager.registerDriver(driver); try { MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); ObjectName objectName = new ObjectName(MBEAN_NAME); if (!mbeanServer.isRegistered(objectName)) { mbeanServer.registerMBean(instance, objectName); } } catch (Exception ex) { LOG.error("register druid-driver mbean error", ex); } return true; } catch (Exception e) { LOG.error("registerDriver error", e); } return false; } public MockExecuteHandler getExecuteHandler() { return executeHandler; } public void setExecuteHandler(MockExecuteHandler executeHandler) { this.executeHandler = executeHandler; } @Override public Connection connect(String url, Properties info) throws SQLException { if (!acceptsURL(url)) { return null; } if (info != null) { Object val = info.get("connectSleep"); if (val != null) { long millis = Long.parseLong(val.toString()); try { Thread.sleep(millis); } catch (InterruptedException e) { // skip } } } MockConnection conn = new MockConnection(this, url, info); if (LOG.isDebugEnabled()) { LOG.debug("connect, url " + url + ", id " + conn.getId()); } if (url == null) { connectCount.incrementAndGet(); connections.add(conn); return conn; } if (url.startsWith(prefix)) { String catalog = url.substring(prefix.length()); conn.setCatalog(catalog); connectCount.incrementAndGet(); connections.add(conn); return conn; } if (url.startsWith(mockPrefix)) { String catalog = url.substring(mockPrefix.length()); conn.setCatalog(catalog); connectCount.incrementAndGet(); connections.add(conn); return conn; } return null; } @Override public boolean acceptsURL(String url) throws SQLException { if (url == null) { return false; } return url.startsWith(prefix) || url.startsWith(mockPrefix); } @Override public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { return null; } @Override public int getMajorVersion() { return 0; } @Override public int getMinorVersion() { return 0; } @Override public boolean jdbcCompliant() { return true; } protected ResultSet executeQuery(MockStatement stmt, String sql) throws SQLException { if (logExecuteQueryEnable && LOG.isDebugEnabled()) { LOG.debug("executeQuery " + sql); } MockConnection conn = stmt.getMockConnection(); long idleTimeMillis = System.currentTimeMillis() - conn.getLastActiveTimeMillis(); if (idleTimeMillis >= this.idleTimeCount) { throw new SQLException("connection is idle time count"); } conn.setLastActiveTimeMillis(System.currentTimeMillis()); if (conn != null) { if (conn.getConnectProperties() != null) { Object propertyValue = conn.getConnectProperties().get("executeSleep"); if (propertyValue != null) { long millis = Long.parseLong(propertyValue.toString()); try { Thread.sleep(millis); } catch (InterruptedException e) { // skip } } } } if ("SELECT value FROM _int_1000_".equalsIgnoreCase(sql)) { MockResultSet rs = new MockResultSet(stmt); for (int i = 0; i < 1000; ++i) { rs.getRows().add(new Object[] {i}); } return rs; } return this.executeHandler.executeQuery(stmt, sql); } protected ResultSet createResultSet(MockPreparedStatement stmt) { MockResultSet rs = new MockResultSet(stmt); String sql = stmt.getSql(); if ("SELECT 1".equalsIgnoreCase(sql)) { rs.getRows().add(new Object[] {1}); } else if ("SELECT NOW()".equalsIgnoreCase(sql)) { rs.getRows().add(new Object[] {new java.sql.Timestamp(System.currentTimeMillis())}); } else if ("SELECT ?".equalsIgnoreCase(sql)) { rs.getRows().add(new Object[] {stmt.getParameters().get(0)}); } return rs; } protected Clob createClob(MockConnection conn) throws SQLException { return new MockClob(); } protected Blob createBlob(MockConnection conn) throws SQLException { return new MockBlob(); } protected NClob createNClob(MockConnection conn) throws SQLException { return new MockNClob(); } protected SQLXML createSQLXML(MockConnection conn) throws SQLException { return new MockSQLXML(); } public Logger getParentLogger() throws SQLFeatureNotSupportedException { throw new SQLFeatureNotSupportedException(); } }