use of com.mysql.cj.exceptions.CJCommunicationsException in project JavaSegundasQuintas by ecteruel.
the class StatementRegressionTest method testBug74998.
/**
* Tests fix for BUG#74998 - readRemainingMultiPackets not computed correctly for rows larger than 16 MB.
*
* This bug is observed only when a multipacket uses packets 127 and 128. It happens due to the transition from positive to negative values in a signed byte
* numeric value (127 + 1 == -128).
*
* The test case forces a multipacket to use packets 127, 128 and 129, where packet 129 is 0-length, this being another boundary case.
* Query (*1) generates the following MySQL protocol packets from the server:
* - Packets 1 to 4 contain protocol control data and results metadata info. (*2)
* - Packets 5 to 126 contain each row "X". (*3)
* - Packets 127 to 129 contain row "Y..." as a multipacket (size("Y...") = 32*1024*1024-15 requires 3 packets). (*4)
* - Packet 130 contains row "Z". (*5)
*
* @throws Exception
*/
@Test
public void testBug74998() throws Exception {
int maxAllowedPacketAtServer = Integer.parseInt(((JdbcConnection) this.conn).getSession().getServerSession().getServerVariable("max_allowed_packet"));
int maxAllowedPacketMinimumForTest = 32 * 1024 * 1024;
boolean changeMaxAllowedPacket = maxAllowedPacketAtServer < maxAllowedPacketMinimumForTest;
if (!versionMeetsMinimum(5, 7)) {
this.rs = this.stmt.executeQuery("SHOW VARIABLES LIKE 'innodb_log_file_size'");
this.rs.next();
long defaultInnodbLogFileSize = this.rs.getInt(2);
assumeFalse(defaultInnodbLogFileSize < maxAllowedPacketMinimumForTest * 10, "This test requires innodb_log_file_size > " + (maxAllowedPacketMinimumForTest * 10));
}
// (*2)
createTable("testBug74998", "(id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, data LONGBLOB)");
Connection con1 = null;
try {
if (changeMaxAllowedPacket) {
this.stmt.executeUpdate("SET GLOBAL max_allowed_packet=" + maxAllowedPacketMinimumForTest);
}
StringBuilder query = new StringBuilder("INSERT INTO testBug74998 (data) VALUES ('X')");
for (int i = 0; i < 121; i++) {
query.append(",('X')");
}
Properties props = new Properties();
props.setProperty(PropertyKey.useSSL.getKeyName(), "false");
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
con1 = getConnectionWithProps(props);
Statement st = con1.createStatement();
// (*3)
assertEquals(122, st.executeUpdate(query.toString()));
// 32MB - 15Bytes causes an empty packet at the end of the multipacket sequence
int lengthOfRowForMultiPacket = maxAllowedPacketMinimumForTest - 15;
// (*4)
st.executeUpdate("INSERT INTO testBug74998 (data) VALUES (REPEAT('Y', " + lengthOfRowForMultiPacket + "))");
// (*5)
st.executeUpdate("INSERT INTO testBug74998 (data) VALUES ('Z')");
try {
// (*1)
this.rs = st.executeQuery("SELECT id, data FROM testBug74998 ORDER BY id");
} catch (CJCommunicationsException | CommunicationsException e) {
assertFalse(e.getCause() instanceof IOException && "Packets received out of order".compareTo(e.getCause().getMessage()) == 0, "Failed to correctly fetch all data from communications layer due to wrong processing of muli-packet number.");
}
// safety check
for (int i = 1; i <= 122; i++) {
assertTrue(this.rs.next());
assertEquals(i, this.rs.getInt(1));
assertEquals("X", this.rs.getString(2));
}
assertTrue(this.rs.next());
assertEquals(123, this.rs.getInt(1));
assertEquals("YYYYY", this.rs.getString(2).substring(0, 5));
assertEquals("YYYYY", this.rs.getString(2).substring(lengthOfRowForMultiPacket - 5));
assertTrue(this.rs.next());
assertEquals(124, this.rs.getInt(1));
assertEquals("Z", this.rs.getString(2));
assertFalse(this.rs.next());
} finally {
if (changeMaxAllowedPacket) {
this.stmt.executeUpdate("SET GLOBAL max_allowed_packet=" + maxAllowedPacketAtServer);
}
if (con1 != null) {
con1.close();
}
}
}
use of com.mysql.cj.exceptions.CJCommunicationsException in project ABC by RuiPinto96274.
the class StatementRegressionTest method testBug74998.
/**
* Tests fix for BUG#74998 - readRemainingMultiPackets not computed correctly for rows larger than 16 MB.
*
* This bug is observed only when a multipacket uses packets 127 and 128. It happens due to the transition from positive to negative values in a signed byte
* numeric value (127 + 1 == -128).
*
* The test case forces a multipacket to use packets 127, 128 and 129, where packet 129 is 0-length, this being another boundary case.
* Query (*1) generates the following MySQL protocol packets from the server:
* - Packets 1 to 4 contain protocol control data and results metadata info. (*2)
* - Packets 5 to 126 contain each row "X". (*3)
* - Packets 127 to 129 contain row "Y..." as a multipacket (size("Y...") = 32*1024*1024-15 requires 3 packets). (*4)
* - Packet 130 contains row "Z". (*5)
*
* @throws Exception
*/
@Test
public void testBug74998() throws Exception {
int maxAllowedPacketAtServer = Integer.parseInt(((JdbcConnection) this.conn).getSession().getServerSession().getServerVariable("max_allowed_packet"));
int maxAllowedPacketMinimumForTest = 32 * 1024 * 1024;
boolean changeMaxAllowedPacket = maxAllowedPacketAtServer < maxAllowedPacketMinimumForTest;
if (!versionMeetsMinimum(5, 7)) {
this.rs = this.stmt.executeQuery("SHOW VARIABLES LIKE 'innodb_log_file_size'");
this.rs.next();
long defaultInnodbLogFileSize = this.rs.getInt(2);
assumeFalse(defaultInnodbLogFileSize < maxAllowedPacketMinimumForTest * 10, "This test requires innodb_log_file_size > " + (maxAllowedPacketMinimumForTest * 10));
}
// (*2)
createTable("testBug74998", "(id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, data LONGBLOB)");
Connection con1 = null;
try {
if (changeMaxAllowedPacket) {
this.stmt.executeUpdate("SET GLOBAL max_allowed_packet=" + maxAllowedPacketMinimumForTest);
}
StringBuilder query = new StringBuilder("INSERT INTO testBug74998 (data) VALUES ('X')");
for (int i = 0; i < 121; i++) {
query.append(",('X')");
}
Properties props = new Properties();
props.setProperty(PropertyKey.useSSL.getKeyName(), "false");
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
con1 = getConnectionWithProps(props);
Statement st = con1.createStatement();
// (*3)
assertEquals(122, st.executeUpdate(query.toString()));
// 32MB - 15Bytes causes an empty packet at the end of the multipacket sequence
int lengthOfRowForMultiPacket = maxAllowedPacketMinimumForTest - 15;
// (*4)
st.executeUpdate("INSERT INTO testBug74998 (data) VALUES (REPEAT('Y', " + lengthOfRowForMultiPacket + "))");
// (*5)
st.executeUpdate("INSERT INTO testBug74998 (data) VALUES ('Z')");
try {
// (*1)
this.rs = st.executeQuery("SELECT id, data FROM testBug74998 ORDER BY id");
} catch (CJCommunicationsException | CommunicationsException e) {
assertFalse(e.getCause() instanceof IOException && "Packets received out of order".compareTo(e.getCause().getMessage()) == 0, "Failed to correctly fetch all data from communications layer due to wrong processing of muli-packet number.");
}
// safety check
for (int i = 1; i <= 122; i++) {
assertTrue(this.rs.next());
assertEquals(i, this.rs.getInt(1));
assertEquals("X", this.rs.getString(2));
}
assertTrue(this.rs.next());
assertEquals(123, this.rs.getInt(1));
assertEquals("YYYYY", this.rs.getString(2).substring(0, 5));
assertEquals("YYYYY", this.rs.getString(2).substring(lengthOfRowForMultiPacket - 5));
assertTrue(this.rs.next());
assertEquals(124, this.rs.getInt(1));
assertEquals("Z", this.rs.getString(2));
assertFalse(this.rs.next());
} finally {
if (changeMaxAllowedPacket) {
this.stmt.executeUpdate("SET GLOBAL max_allowed_packet=" + maxAllowedPacketAtServer);
}
if (con1 != null) {
con1.close();
}
}
}
use of com.mysql.cj.exceptions.CJCommunicationsException in project ABC by RuiPinto96274.
the class XProtocol method negotiateSSLConnection.
public void negotiateSSLConnection() {
if (!ExportControlled.enabled()) {
throw new CJConnectionFeatureNotAvailableException();
}
if (!((XServerCapabilities) this.serverSession.getCapabilities()).hasCapability(XServerCapabilities.KEY_TLS)) {
throw new CJCommunicationsException("A secure connection is required but the server is not configured with SSL.");
}
// the message reader is async and is always "reading". we need to stop it to use the socket for the TLS handshake
this.reader.stopAfterNextMessage();
Map<String, Object> tlsCapabilities = new HashMap<>();
tlsCapabilities.put(XServerCapabilities.KEY_TLS, true);
sendCapabilities(tlsCapabilities);
try {
this.socketConnection.performTlsHandshake(null, this.log);
} catch (SSLParamsException | FeatureNotAvailableException | IOException e) {
throw new CJCommunicationsException(e);
}
try {
this.sender = new SyncMessageSender(this.socketConnection.getMysqlOutput());
this.reader = new SyncMessageReader(this.socketConnection.getMysqlInput(), this);
} catch (IOException e) {
throw new XProtocolError(e.getMessage(), e);
}
}
use of com.mysql.cj.exceptions.CJCommunicationsException in project ABC by RuiPinto96274.
the class SyncMessageReader method readMessageLocal.
@SuppressWarnings("unchecked")
private <T extends GeneratedMessageV3> T readMessageLocal(Class<T> messageClass, boolean fromQueue) {
XMessageHeader header;
if (fromQueue) {
header = this.headersQueue.poll();
T msg = (T) this.messagesQueue.poll();
if (msg != null) {
return msg;
}
} else {
header = this.headersQueue.getLast();
}
Parser<T> parser = (Parser<T>) MessageConstants.MESSAGE_CLASS_TO_PARSER.get(messageClass);
byte[] packet = new byte[header.getMessageSize()];
try {
this.inputStream.readFully(packet);
} catch (IOException ex) {
// TODO close socket?
throw new CJCommunicationsException("Cannot read packet payload", ex);
}
try {
T msg = parser.parseFrom(packet);
if (msg instanceof Frame && ((Frame) msg).getType() == Frame.Type.WARNING_VALUE && ((Frame) msg).getScope() == Frame.Scope.GLOBAL) {
XWarning w = new XWarning((Frame) msg);
int code = (int) w.getCode();
if (code == MysqlErrorNumbers.ER_SERVER_SHUTDOWN || code == MysqlErrorNumbers.ER_IO_READ_ERROR || code == MysqlErrorNumbers.ER_SESSION_WAS_KILLED) {
CJCommunicationsException ex = new CJCommunicationsException(w.getMessage());
ex.setVendorCode(code);
if (this.protocolEventHandler != null) {
this.protocolEventHandler.invokeListeners(code == MysqlErrorNumbers.ER_SERVER_SHUTDOWN ? EventType.SERVER_SHUTDOWN : EventType.SERVER_CLOSED_SESSION, ex);
}
throw ex;
}
}
return msg;
} catch (InvalidProtocolBufferException ex) {
throw new WrongArgumentException(ex);
}
}
use of com.mysql.cj.exceptions.CJCommunicationsException in project ABC by RuiPinto96274.
the class SyncMessageReader method pushMessageListener.
public void pushMessageListener(final MessageListener<XMessage> listener) {
try {
this.messageListenerQueue.put(listener);
} catch (InterruptedException e) {
throw new CJCommunicationsException("Cannot queue message listener.", e);
}
synchronized (this.dispatchingThreadMonitor) {
if (this.dispatchingThread == null) {
ListenersDispatcher ld = new ListenersDispatcher();
this.dispatchingThread = new Thread(ld, "Message listeners dispatching thread");
this.dispatchingThread.start();
// We must ensure that ListenersDispatcher is really started before leaving
// the synchronized block. Otherwise the race condition is possible: if next
// operation is executed synchronously it could consume results of the previous
// asynchronous operation.
// TODO expose via properties ?
int millis = 5000;
while (!ld.started) {
try {
Thread.sleep(10);
millis = millis - 10;
} catch (InterruptedException e) {
throw new XProtocolError(e.getMessage(), e);
}
if (millis <= 0) {
throw new XProtocolError("Timeout for starting ListenersDispatcher exceeded.");
}
}
}
}
}
Aggregations