Search in sources :

Example 1 with CJCommunicationsException

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();
        }
    }
}
Also used : JdbcStatement(com.mysql.cj.jdbc.JdbcStatement) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement) ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) IOException(java.io.IOException) Properties(java.util.Properties) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) CommunicationsException(com.mysql.cj.jdbc.exceptions.CommunicationsException) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) StatementsTest(testsuite.simple.StatementsTest) Test(org.junit.jupiter.api.Test)

Example 2 with CJCommunicationsException

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();
        }
    }
}
Also used : JdbcStatement(com.mysql.cj.jdbc.JdbcStatement) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement) ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) IOException(java.io.IOException) Properties(java.util.Properties) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) CommunicationsException(com.mysql.cj.jdbc.exceptions.CommunicationsException) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) StatementsTest(testsuite.simple.StatementsTest) Test(org.junit.jupiter.api.Test)

Example 3 with CJCommunicationsException

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);
    }
}
Also used : HashMap(java.util.HashMap) CJConnectionFeatureNotAvailableException(com.mysql.cj.exceptions.CJConnectionFeatureNotAvailableException) IOException(java.io.IOException) SSLParamsException(com.mysql.cj.exceptions.SSLParamsException) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) FeatureNotAvailableException(com.mysql.cj.exceptions.FeatureNotAvailableException) CJConnectionFeatureNotAvailableException(com.mysql.cj.exceptions.CJConnectionFeatureNotAvailableException)

Example 4 with CJCommunicationsException

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);
    }
}
Also used : XWarning(com.mysql.cj.protocol.x.Notice.XWarning) Frame(com.mysql.cj.x.protobuf.MysqlxNotice.Frame) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) WrongArgumentException(com.mysql.cj.exceptions.WrongArgumentException) IOException(java.io.IOException) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) Parser(com.google.protobuf.Parser)

Example 5 with CJCommunicationsException

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.");
                }
            }
        }
    }
}
Also used : CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException)

Aggregations

CJCommunicationsException (com.mysql.cj.exceptions.CJCommunicationsException)40 IOException (java.io.IOException)21 WrongArgumentException (com.mysql.cj.exceptions.WrongArgumentException)13 FeatureNotAvailableException (com.mysql.cj.exceptions.FeatureNotAvailableException)9 Test (org.junit.jupiter.api.Test)9 CommunicationsException (com.mysql.cj.jdbc.exceptions.CommunicationsException)7 MysqlConnection (com.mysql.cj.MysqlConnection)6 CJConnectionFeatureNotAvailableException (com.mysql.cj.exceptions.CJConnectionFeatureNotAvailableException)6 CJPacketTooBigException (com.mysql.cj.exceptions.CJPacketTooBigException)6 SSLParamsException (com.mysql.cj.exceptions.SSLParamsException)6 JdbcConnection (com.mysql.cj.jdbc.JdbcConnection)6 ServerPreparedStatement (com.mysql.cj.jdbc.ServerPreparedStatement)6 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)4 Parser (com.google.protobuf.Parser)4 ConnectionIsClosedException (com.mysql.cj.exceptions.ConnectionIsClosedException)4 CallableStatement (java.sql.CallableStatement)4 Connection (java.sql.Connection)4 PreparedStatement (java.sql.PreparedStatement)4 Statement (java.sql.Statement)4 Properties (java.util.Properties)4