use of com.mysql.cj.protocol.SocketFactory in project aws-mysql-jdbc by awslabs.
the class SessionTest method testBug97269.
/**
* Test fix for Bug#97269 (30438500), POSSIBLE BUG IN COM.MYSQL.CJ.XDEVAPI.STREAMINGDOCRESULTBUILDER.
*
* @throws Exception
*/
@Test
public void testBug97269() throws Exception {
Session sess = null;
try {
String message1 = "W1";
String message2 = "W2";
// create notice message buffers
Frame.Builder notice1 = Frame.newBuilder().setScope(Frame.Scope.LOCAL).setType(Frame.Type.WARNING_VALUE).setPayload(com.mysql.cj.x.protobuf.MysqlxNotice.Warning.newBuilder().setCode(MysqlErrorNumbers.ER_BAD_DB_ERROR).setMsg(message1).build().toByteString());
Frame.Builder notice2 = Frame.newBuilder().setScope(Frame.Scope.GLOBAL).setType(Frame.Type.WARNING_VALUE).setPayload(com.mysql.cj.x.protobuf.MysqlxNotice.Warning.newBuilder().setCode(MysqlErrorNumbers.ER_BAD_DB_ERROR).setMsg(message2).build().toByteString());
byte[] notice1Bytes = makeNoticeBytes(notice1.build());
byte[] notice2Bytes = makeNoticeBytes(notice2.build());
int size = notice1Bytes.length + notice2Bytes.length;
byte[] noticesBytes = new byte[size];
System.arraycopy(notice1Bytes, 0, noticesBytes, 0, notice1Bytes.length);
System.arraycopy(notice2Bytes, 0, noticesBytes, notice1Bytes.length, notice2Bytes.length);
InjectedSocketFactory.flushAllStaticData();
String url = this.baseUrl + (this.baseUrl.contains("?") ? "" : "?") + makeParam(PropertyKey.socketFactory, InjectedSocketFactory.class.getName(), !this.baseUrl.contains("?") || this.baseUrl.endsWith("?")) + makeParam(PropertyKey.xdevapiSslMode, XdevapiSslMode.DISABLED.toString()) + makeParam(PropertyKey.xdevapiCompression, Compression.DISABLED.toString()) + // to allow injection between result rows
makeParam(PropertyKey.useReadAheadInput, "false");
sess = this.fact.getSession(url);
SocketFactory sf = ((SessionImpl) sess).getSession().getProtocol().getSocketConnection().getSocketFactory();
assertTrue(InjectedSocketFactory.class.isAssignableFrom(sf.getClass()));
Collection collection = sess.getDefaultSchema().createCollection("testBug97269");
collection.add("{\"_id\":\"the_id\",\"g\":1}").execute();
// StreamingDocResultBuilder
InjectedSocketFactory.injectedBuffer = noticesBytes;
DocResult docs = collection.find().fields("$._id as _id, $.g as g, 1 + 1 as q").execute();
DbDoc doc = docs.next();
assertEquals("the_id", ((JsonString) doc.get("_id")).getString());
assertEquals(new Integer(1), ((JsonNumber) doc.get("g")).getInteger());
assertEquals(new Integer(2), ((JsonNumber) doc.get("q")).getInteger());
int cnt = 0;
for (Iterator<Warning> warn = docs.getWarnings(); warn.hasNext(); ) {
Warning w = warn.next();
if (w.getMessage().equals(message1) || w.getMessage().equals(message2)) {
cnt++;
}
}
assertEquals(2, cnt);
InjectedSocketFactory.flushAllStaticData();
InjectedSocketFactory.injectedBuffer = noticesBytes;
SqlResult rs1 = sess.sql("select 1").execute();
assertEquals(1, rs1.fetchOne().getInt(0));
cnt = 0;
for (Iterator<Warning> warn = rs1.getWarnings(); warn.hasNext(); ) {
Warning w = warn.next();
if (w.getMessage().equals(message1) || w.getMessage().equals(message2)) {
cnt++;
}
}
assertEquals(2, cnt);
} finally {
InjectedSocketFactory.flushAllStaticData();
dropCollection("testBug97269");
if (sess != null) {
sess.close();
}
}
}
use of com.mysql.cj.protocol.SocketFactory in project aws-mysql-jdbc by awslabs.
the class SessionTest method testConnectionCloseNotification.
@Test
public void testConnectionCloseNotification() throws Exception {
String shutdownMessage = "Server shutdown in progress";
String ioReadErrorMessage = "IO Read error: read_timeout exceeded";
String sessionWasKilledMessage = "Session was killed";
// create notice message buffers
Frame.Builder shutdownNotice = Frame.newBuilder().setScope(Frame.Scope.GLOBAL).setType(Frame.Type.WARNING_VALUE).setPayload(com.mysql.cj.x.protobuf.MysqlxNotice.Warning.newBuilder().setCode(MysqlErrorNumbers.ER_SERVER_SHUTDOWN).setMsg(shutdownMessage).build().toByteString());
Frame.Builder ioReadErrorNotice = Frame.newBuilder().setScope(Frame.Scope.GLOBAL).setType(Frame.Type.WARNING_VALUE).setPayload(com.mysql.cj.x.protobuf.MysqlxNotice.Warning.newBuilder().setCode(MysqlErrorNumbers.ER_IO_READ_ERROR).setMsg(ioReadErrorMessage).build().toByteString());
Frame.Builder sessionWasKilledNotice = Frame.newBuilder().setScope(Frame.Scope.GLOBAL).setType(Frame.Type.WARNING_VALUE).setPayload(com.mysql.cj.x.protobuf.MysqlxNotice.Warning.newBuilder().setCode(MysqlErrorNumbers.ER_SESSION_WAS_KILLED).setMsg(sessionWasKilledMessage).build().toByteString());
byte[] shutdownNoticeBytes = makeNoticeBytes(shutdownNotice.build());
byte[] ioReadErrorNoticeBytes = makeNoticeBytes(ioReadErrorNotice.build());
byte[] sessionWasKilledNoticeBytes = makeNoticeBytes(sessionWasKilledNotice.build());
InjectedSocketFactory.flushAllStaticData();
String url = this.baseUrl + (this.baseUrl.contains("?") ? "" : "?") + makeParam(PropertyKey.socketFactory, InjectedSocketFactory.class.getName(), !this.baseUrl.contains("?") || this.baseUrl.endsWith("?")) + makeParam(PropertyKey.xdevapiSslMode, XdevapiSslMode.DISABLED.toString()) + makeParam(PropertyKey.xdevapiCompression, Compression.DISABLED.toString()) + // to allow injection between result rows
makeParam(PropertyKey.useReadAheadInput, "false");
// ER_SERVER_SHUTDOWN
// 1.1. Shutdown during a sync query execution.
Session sess11 = this.fact.getSession(url);
SocketFactory sf = ((SessionImpl) sess11).getSession().getProtocol().getSocketConnection().getSocketFactory();
assertTrue(InjectedSocketFactory.class.isAssignableFrom(sf.getClass()));
InjectedSocketFactory.injectedBuffer = shutdownNoticeBytes;
assertThrows(CJCommunicationsException.class, shutdownMessage, () -> sess11.sql("SELECT 1").execute());
// 1.2. Shutdown during a sync result set consuming
Session sess12 = this.fact.getSession(url);
SqlResult res0 = sess12.sql("SELECT 1").execute();
assertTrue(res0.hasNext());
Row r = res0.next();
assertEquals("1", r.getString(0));
InjectedSocketFactory.injectedBuffer = shutdownNoticeBytes;
assertThrows(CJCommunicationsException.class, shutdownMessage, () -> res0.next());
// 1.3. Shutdown during an async query execution.
Session sess13 = this.fact.getSession(url);
InjectedSocketFactory.injectedBuffer = shutdownNoticeBytes;
assertThrows(ExecutionException.class, CJCommunicationsException.class.getName() + ": " + shutdownMessage, () -> sess13.sql("SELECT 1").executeAsync().get());
// 1.4. Shutdown during an async result set consuming
Session sess14 = this.fact.getSession(url);
SqlResult res1 = sess14.sql("SELECT 1").executeAsync().get();
InjectedSocketFactory.injectedBuffer = shutdownNoticeBytes;
assertTrue(res1.hasNext());
r = res1.next();
assertEquals("1", r.getString(0));
assertFalse(res1.hasNext());
assertThrows(CJCommunicationsException.class, shutdownMessage, () -> sess14.getSchemas());
// ER_IO_READ_ERROR
// 2.1. ER_IO_READ_ERROR during a sync query execution.
Session sess21 = this.fact.getSession(url);
InjectedSocketFactory.injectedBuffer = ioReadErrorNoticeBytes;
assertThrows(CJCommunicationsException.class, ioReadErrorMessage, () -> sess21.sql("SELECT 1").execute());
// 2.2. ER_IO_READ_ERROR during a sync result set consuming
Session sess22 = this.fact.getSession(url);
SqlResult res2 = sess22.sql("SELECT 1").execute();
assertTrue(res2.hasNext());
r = res2.next();
assertEquals("1", r.getString(0));
InjectedSocketFactory.injectedBuffer = ioReadErrorNoticeBytes;
assertThrows(CJCommunicationsException.class, ioReadErrorMessage, () -> res2.next());
// 2.3. ER_IO_READ_ERROR during an async query execution.
Session sess23 = this.fact.getSession(url);
InjectedSocketFactory.injectedBuffer = ioReadErrorNoticeBytes;
assertThrows(ExecutionException.class, CJCommunicationsException.class.getName() + ": " + ioReadErrorMessage, () -> sess23.sql("SELECT 1").executeAsync().get());
// 2.4. ER_IO_READ_ERROR during an async result set consuming
Session sess24 = this.fact.getSession(url);
res1 = sess24.sql("SELECT 1").executeAsync().get();
InjectedSocketFactory.injectedBuffer = ioReadErrorNoticeBytes;
assertTrue(res1.hasNext());
r = res1.next();
assertEquals("1", r.getString(0));
assertFalse(res1.hasNext());
assertThrows(CJCommunicationsException.class, ioReadErrorMessage, () -> sess24.getSchemas());
// ER_SESSION_WAS_KILLED
// 3.1. ER_SESSION_WAS_KILLED during a sync query execution.
Session sess31 = this.fact.getSession(url);
InjectedSocketFactory.injectedBuffer = sessionWasKilledNoticeBytes;
assertThrows(CJCommunicationsException.class, sessionWasKilledMessage, () -> sess31.sql("SELECT 1").execute());
// 3.2. ER_SESSION_WAS_KILLED during a sync result set consuming
Session sess32 = this.fact.getSession(url);
SqlResult res3 = sess32.sql("SELECT 1").execute();
assertTrue(res3.hasNext());
r = res3.next();
assertEquals("1", r.getString(0));
InjectedSocketFactory.injectedBuffer = sessionWasKilledNoticeBytes;
assertThrows(CJCommunicationsException.class, sessionWasKilledMessage, () -> res3.next());
// 3.3. ER_SESSION_WAS_KILLED during an async query execution.
Session sess33 = this.fact.getSession(url);
InjectedSocketFactory.injectedBuffer = sessionWasKilledNoticeBytes;
assertThrows(ExecutionException.class, CJCommunicationsException.class.getName() + ": " + sessionWasKilledMessage, () -> sess33.sql("SELECT 1").executeAsync().get());
// 3.4. ER_SESSION_WAS_KILLED during an async result set consuming
Session sess34 = this.fact.getSession(url);
res1 = sess34.sql("SELECT 1").executeAsync().get();
InjectedSocketFactory.injectedBuffer = sessionWasKilledNoticeBytes;
assertTrue(res1.hasNext());
r = res1.next();
assertEquals("1", r.getString(0));
assertFalse(res1.hasNext());
assertThrows(CJCommunicationsException.class, sessionWasKilledMessage, () -> sess34.getSchemas());
// TODO use a mock server instead of a real second server instance
// /*
// * With pooling.
// */
//
// if (this.isSetForOpensslXTests) {
//
// this.fact.getSession(this.baseOpensslUrl);
//
// final String testUriPattern = "mysqlx://%s:%s@[%s]/%s?" + makeParam(PropertyKey.socketFactory, InjectedSocketFactory.class.getName())
// + makeParam(PropertyKey.xdevapiSslMode, XdevapiSslMode.DISABLED.toString()) + makeParam(PropertyKey.allowPublicKeyRetrieval, "true")
// + makeParam(PropertyKey.xdevapiCompression, Compression.DISABLED.toString())
// // to allow injection between result rows
// + makeParam(PropertyKey.useReadAheadInput, "false");
//
// String testHosts = "(address=" + getTestHost() + ":" + getTestPort() + "),(address=" + getTestSslHost() + ":" + getTestSslPort() + ")";
// url = String.format(testUriPattern, getTestUser() == null ? "" : getTestUser(), getTestPassword() == null ? "" : getTestPassword(), testHosts,
// getTestDatabase());
//
// Field fProtocol = CoreSession.class.getDeclaredField("protocol");
// fProtocol.setAccessible(true);
//
// Field idleProtocols = ClientImpl.class.getDeclaredField("idleProtocols");
// idleProtocols.setAccessible(true);
// Field activeProtocols = ClientImpl.class.getDeclaredField("activeProtocols");
// activeProtocols.setAccessible(true);
// Field nonPooledSessions = ClientImpl.class.getDeclaredField("nonPooledSessions");
// nonPooledSessions.setAccessible(true);
//
// String host1 = getTestHost();
// String host2 = getTestSslHost();
// int port1 = getTestPort();
// int port2 = getTestSslPort();
//
// final ClientFactory cf = new ClientFactory();
// Client cli0 = cf.getClient(url, "{\"pooling\": {\"enabled\": true}}");
//
// InjectedSocketFactory.downHost(getTestSslHost() + ":" + getTestSslPort());
// Session s1_1 = cli0.getSession();
// Session s1_2 = cli0.getSession();
// Session s1_3 = cli0.getSession();
//
// assertEquals(host1, ((SessionImpl) s1_1).getSession().getProcessHost());
// assertEquals(host1, ((SessionImpl) s1_2).getSession().getProcessHost());
// assertEquals(host1, ((SessionImpl) s1_3).getSession().getProcessHost());
// assertEquals(port1, ((SessionImpl) s1_1).getSession().getPort());
// assertEquals(port1, ((SessionImpl) s1_2).getSession().getPort());
// assertEquals(port1, ((SessionImpl) s1_3).getSession().getPort());
//
// InjectedSocketFactory.dontDownHost(getTestSslHost() + ":" + getTestSslPort());
// InjectedSocketFactory.downHost(getTestHost() + ":" + getTestPort());
// Session s2_1 = cli0.getSession();
// Session s2_2 = cli0.getSession();
// Session s2_3 = cli0.getSession();
//
// assertEquals(host2, ((SessionImpl) s2_1).getSession().getProcessHost());
// assertEquals(host2, ((SessionImpl) s2_2).getSession().getProcessHost());
// assertEquals(host2, ((SessionImpl) s2_3).getSession().getProcessHost());
// assertEquals(port2, ((SessionImpl) s2_1).getSession().getPort());
// assertEquals(port2, ((SessionImpl) s2_2).getSession().getPort());
// assertEquals(port2, ((SessionImpl) s2_3).getSession().getPort());
//
// InjectedSocketFactory.dontDownHost(getTestHost() + ":" + getTestPort());
// InjectedSocketFactory.downHost(getTestSslHost() + ":" + getTestSslPort());
// Session s1 = cli0.getSession();
//
// assertEquals(host1, ((SessionImpl) s1).getSession().getProcessHost());
// assertEquals(port1, ((SessionImpl) s1).getSession().getPort());
//
// s1_1.close();
// s1_2.close();
// s1_3.close();
// s2_1.close();
// s2_2.close();
// s2_3.close();
//
// assertEquals(1, ((Set<WeakReference<PooledXProtocol>>) activeProtocols.get(cli0)).size());
// assertEquals(6, ((BlockingQueue<PooledXProtocol>) idleProtocols.get(cli0)).size());
//
// // ER_IO_READ_ERROR
//
// InjectedSocketFactory.injectedBuffer = ioReadErrorNoticeBytes;
// assertThrows(CJCommunicationsException.class, ioReadErrorMessage, () -> s1.sql("SELECT 1").execute());
//
// assertEquals(0, ((Set<WeakReference<PooledXProtocol>>) activeProtocols.get(cli0)).size());
// assertEquals(6, ((BlockingQueue<PooledXProtocol>) idleProtocols.get(cli0)).size());
// assertThrows(CJCommunicationsException.class, "Unable to write message", () -> s1.sql("SELECT 1").execute());
//
// // ER_SESSION_WAS_KILLED
//
// Session s2 = cli0.getSession();
// assertEquals(host1, ((SessionImpl) s2).getSession().getProcessHost());
// assertEquals(port1, ((SessionImpl) s2).getSession().getPort());
// assertEquals(1, ((Set<WeakReference<PooledXProtocol>>) activeProtocols.get(cli0)).size());
// assertEquals(5, ((BlockingQueue<PooledXProtocol>) idleProtocols.get(cli0)).size());
//
// InjectedSocketFactory.injectedBuffer = sessionWasKilledNoticeBytes;
// assertThrows(CJCommunicationsException.class, sessionWasKilledMessage, () -> s2.sql("SELECT 1").execute());
//
// assertEquals(0, ((Set<WeakReference<PooledXProtocol>>) activeProtocols.get(cli0)).size());
// assertEquals(5, ((BlockingQueue<PooledXProtocol>) idleProtocols.get(cli0)).size());
// assertThrows(CJCommunicationsException.class, "Unable to write message", () -> s2.sql("SELECT 1").execute());
//
// // ER_SERVER_SHUTDOWN
//
// Session s3 = cli0.getSession();
// assertEquals(host1, ((SessionImpl) s3).getSession().getProcessHost());
// assertEquals(port1, ((SessionImpl) s3).getSession().getPort());
// assertEquals(1, ((Set<WeakReference<PooledXProtocol>>) activeProtocols.get(cli0)).size());
// assertEquals(4, ((BlockingQueue<PooledXProtocol>) idleProtocols.get(cli0)).size());
//
// InjectedSocketFactory.injectedBuffer = shutdownNoticeBytes;
// assertThrows(CJCommunicationsException.class, shutdownMessage, () -> s3.sql("SELECT 1").execute());
//
// assertEquals(0, ((Set<WeakReference<PooledXProtocol>>) activeProtocols.get(cli0)).size());
// assertEquals(3, ((BlockingQueue<PooledXProtocol>) idleProtocols.get(cli0)).size());
// }
}
Aggregations