/**
* Copyright (C) 2009-2015 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.foundationdb.server.service.monitor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import com.foundationdb.server.service.is.ServerSchemaTablesService;
import com.foundationdb.server.service.is.ServerSchemaTablesServiceImpl;
import com.foundationdb.server.service.metrics.FDBMetricsService;
import com.foundationdb.server.service.metrics.MetricsService;
import com.foundationdb.server.service.monitor.SessionMonitor.StatementTypes;
import com.foundationdb.server.service.servicemanager.GuicedServiceManager;
import com.foundationdb.server.test.it.ITBase;
import com.foundationdb.sql.embedded.EmbeddedJDBCService;
import com.foundationdb.sql.embedded.EmbeddedJDBCServiceImpl;
public class MonitorServiceIT extends ITBase {
@Override
protected GuicedServiceManager.BindingsConfigurationProvider serviceBindingsProvider() {
return super.serviceBindingsProvider()
.bindAndRequire(EmbeddedJDBCService.class, EmbeddedJDBCServiceImpl.class)
.bindAndRequire(MonitorService.class, MonitorServiceImpl.class);
}
public static final String SCHEMA_NAME = "test";
public static final String CONNECTION_URL = "jdbc:default:connection";
public Connection getConnection() throws SQLException {
return DriverManager.getConnection(CONNECTION_URL, SCHEMA_NAME, "");
}
public MonitorService getMonitorService() {
return (MonitorService)serviceManager().getServiceByClass(MonitorService.class);
}
@Before
public void loadDB() throws Exception {
int cid = createTable(SCHEMA_NAME, "c",
"cid int primary key not null",
"name varchar(16) not null");
int oid = createTable(SCHEMA_NAME, "o",
"oid int primary key not null",
"cid int not null",
"grouping foreign key(cid) references c(cid)",
"order_date date not null");
writeRow(cid, 1, "Smith");
writeRow(oid, 101, 1, 2012 * 512 + 1 * 32 + 31);
writeRow(oid, 102, 1, 2012 * 512 + 2 * 32 + 1);
writeRow(cid, 2, "Jones");
writeRow(oid, 201, 2, 2012 * 512 + 4 * 32 + 1);
}
@Test
public void testSelect() throws Exception {
long count = getMonitorService().getCount(StatementTypes.STATEMENT);
long querys = getMonitorService().getCount(StatementTypes.SELECT);
try (Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT name FROM c WHERE cid = 1")) {
assertTrue("has first row", rs.next());
assertEquals("result value", "Smith", rs.getString(1));
assertFalse("has more rows", rs.next());
}
long recount = getMonitorService().getCount(StatementTypes.STATEMENT);
long requerys = getMonitorService().getCount(StatementTypes.SELECT);
assertEquals (1, recount-count);
assertEquals (1, requerys-querys);
assertEquals(0, getMonitorService().getSessionMonitors().size());
}
@Test
public void testDDL() throws Exception {
long count = getMonitorService().getCount(StatementTypes.STATEMENT);
long ddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
stmt.executeUpdate("CREATE TABLE i (iid int primary key not null, count int not null)");
}
long recount = getMonitorService().getCount(StatementTypes.STATEMENT);
long reddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
assertEquals (1, recount-count);
assertEquals (1, reddl-ddl);
assertEquals(0, getMonitorService().getSessionMonitors().size());
}
@Test
public void testDML() throws Exception {
long count = getMonitorService().getCount(StatementTypes.STATEMENT);
long ddl = getMonitorService().getCount(StatementTypes.DML_STMT);
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
stmt.executeUpdate("INSERT INTO c (cid, name) values (3, 'franks')");
}
long recount = getMonitorService().getCount(StatementTypes.STATEMENT);
long reddl = getMonitorService().getCount(StatementTypes.DML_STMT);
assertEquals (1, recount-count);
assertEquals (1, reddl-ddl);
assertEquals(0, getMonitorService().getSessionMonitors().size());
}
@Test
public void testCall() throws Exception {
long count = getMonitorService().getCount(StatementTypes.STATEMENT);
long ddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
stmt.executeUpdate("CREATE PROCEDURE test_clean(OUT total INT) AS $$\n"+
"function fun(total) {\n" +
"var conn = java.sql.DriverManager.getConnection('jdbc:default:connection');\n" +
"var stmt = conn.createStatement();\n"+
"var rs = stmt.executeQuery('SELECT sum(cid) FROM c');\n"+
"rs.next();\n"+
"total[0] = rs.getInt(1);\n"+
"rs.close();\n"+
"stmt.close();\n"+
"conn.close();\n"+
"}\n"+
"$$ LANGUAGE javascript PARAMETER STYLE java EXTERNAL NAME 'fun'");
}
long recount = getMonitorService().getCount(StatementTypes.STATEMENT);
long reddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
assertEquals (1, recount-count);
assertEquals (1, reddl-ddl);
assertEquals(0, getMonitorService().getSessionMonitors().size());
long calls = getMonitorService().getCount(StatementTypes.CALL_STMT);
long querys = getMonitorService().getCount(StatementTypes.SELECT);
try (Connection conn = getConnection();
CallableStatement stmt = conn.prepareCall("CALL test_clean(?)")) {
stmt.registerOutParameter(1, Types.INTEGER);
stmt.execute();
assertEquals(3, stmt.getInt(1));
assertEquals(1, getMonitorService().getSessionMonitors().size());
}
long newCount = getMonitorService().getCount(StatementTypes.STATEMENT);
long recalls = getMonitorService().getCount(StatementTypes.CALL_STMT);
long requerys = getMonitorService().getCount(StatementTypes.SELECT);
assertEquals(2, newCount-recount);
assertEquals(1, recalls-calls);
assertEquals(1, requerys-querys);
assertEquals(0, getMonitorService().getSessionMonitors().size());
}
@Test
public void testCallRS() throws Exception {
long count = getMonitorService().getCount(StatementTypes.STATEMENT);
long ddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
stmt.executeUpdate("CREATE PROCEDURE test_rs() DYNAMIC RESULT SETS 1 AS $$\n"+
"function fun(rs) {\n"+
"var conn = java.sql.DriverManager.getConnection('jdbc:default:connection');\n"+
"var stmt = conn.createStatement();\n"+
"rs[0] = stmt.executeQuery('SELECT sum(cid) FROM c');\n"+
"}\n"+
"$$ LANGUAGE javascript PARAMETER STYLE java EXTERNAL NAME 'fun'");
}
long recount = getMonitorService().getCount(StatementTypes.STATEMENT);
long reddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
assertEquals (1, recount-count);
assertEquals (1, reddl-ddl);
assertEquals(0, getMonitorService().getSessionMonitors().size());
long calls = getMonitorService().getCount(StatementTypes.CALL_STMT);
long querys = getMonitorService().getCount(StatementTypes.SELECT);
try (Connection conn = getConnection();
CallableStatement stmt = conn.prepareCall("CALL test_rs()");
ResultSet rs = stmt.executeQuery()) {
assertNotNull (rs);
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse("has more rows", rs.next());
assertNull(rs.getWarnings());
assertEquals(2, getMonitorService().getSessionMonitors().size());
}
long newCount = getMonitorService().getCount(StatementTypes.STATEMENT);
long recalls = getMonitorService().getCount(StatementTypes.CALL_STMT);
long requerys = getMonitorService().getCount(StatementTypes.SELECT);
assertEquals(2, newCount-recount);
assertEquals(1, recalls-calls);
assertEquals(1, requerys-querys);
assertEquals(0, getMonitorService().getSessionMonitors().size());
try (Connection conn = getConnection();
CallableStatement stmt = conn.prepareCall("CALL test_rs()");
ResultSet rs = stmt.executeQuery()) {
assertNotNull (rs);
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse("has more rows", rs.next());
assertNull(rs.getWarnings());
}
assertEquals(0, getMonitorService().getSessionMonitors().size());
}
@Test
public void testCallRSWithClose() throws Exception {
long count = getMonitorService().getCount(StatementTypes.STATEMENT);
long ddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
stmt.executeUpdate("CREATE PROCEDURE test_rs() DYNAMIC RESULT SETS 1 AS $$\n"+
"function fun(rs) {\n"+
"var conn = java.sql.DriverManager.getConnection('jdbc:default:connection');\n"+
"var stmt = conn.createStatement();\n"+
"rs[0] = stmt.executeQuery('SELECT sum(cid) FROM c');\n"+
"}\n"+
"$$ LANGUAGE javascript PARAMETER STYLE java EXTERNAL NAME 'fun'");
}
long recount = getMonitorService().getCount(StatementTypes.STATEMENT);
long reddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
assertEquals (1, recount-count);
assertEquals (1, reddl-ddl);
assertEquals(0, getMonitorService().getSessionMonitors().size());
long calls = getMonitorService().getCount(StatementTypes.CALL_STMT);
long querys = getMonitorService().getCount(StatementTypes.SELECT);
try (Connection conn = getConnection();
CallableStatement stmt = conn.prepareCall("CALL test_rs()");
ResultSet rs = stmt.executeQuery()) {
assertNotNull (rs);
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse("has more rows", rs.next());
assertNull(rs.getWarnings());
assertEquals(2, getMonitorService().getSessionMonitors().size());
rs.getStatement().getConnection().close();
}
long newCount = getMonitorService().getCount(StatementTypes.STATEMENT);
long recalls = getMonitorService().getCount(StatementTypes.CALL_STMT);
long requerys = getMonitorService().getCount(StatementTypes.SELECT);
assertEquals(2, newCount-recount);
assertEquals(1, recalls-calls);
assertEquals(1, requerys-querys);
assertEquals(0, getMonitorService().getSessionMonitors().size());
}
@Test
public void testCallRSReuseConnection() throws Exception {
long count = getMonitorService().getCount(StatementTypes.STATEMENT);
long ddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
stmt.executeUpdate("CREATE PROCEDURE test_rs() DYNAMIC RESULT SETS 1 AS $$\n"+
"function fun(rs) {\n"+
"var conn = java.sql.DriverManager.getConnection('jdbc:default:connection');\n"+
"var stmt = conn.createStatement();\n"+
"rs[0] = stmt.executeQuery('SELECT sum(cid) FROM c');\n"+
"}\n"+
"$$ LANGUAGE javascript PARAMETER STYLE java EXTERNAL NAME 'fun'");
}
long recount = getMonitorService().getCount(StatementTypes.STATEMENT);
long reddl = getMonitorService().getCount(StatementTypes.DDL_STMT);
assertEquals (1, recount-count);
assertEquals (1, reddl-ddl);
assertEquals(0, getMonitorService().getSessionMonitors().size());
long calls = getMonitorService().getCount(StatementTypes.CALL_STMT);
long querys = getMonitorService().getCount(StatementTypes.SELECT);
try (Connection conn = getConnection();
CallableStatement stmt = conn.prepareCall("CALL test_rs()")) {
ResultSet rs = stmt.executeQuery();
assertNotNull (rs);
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse("has more rows", rs.next());
assertNull(rs.getWarnings());
rs.close();
Statement stmt2 = conn.createStatement();
rs = stmt2.executeQuery("SELECT name FROM c WHERE cid = 1");
assertTrue("has first row", rs.next());
assertEquals("result value", "Smith", rs.getString(1));
assertFalse("has more rows", rs.next());
rs.close();
stmt2.close();
}
long newCount = getMonitorService().getCount(StatementTypes.STATEMENT);
long recalls = getMonitorService().getCount(StatementTypes.CALL_STMT);
long requerys = getMonitorService().getCount(StatementTypes.SELECT);
assertEquals(3, newCount-recount);
assertEquals(1, recalls-calls);
assertEquals(2, requerys-querys);
assertEquals(0, getMonitorService().getSessionMonitors().size());
}
}