org.redkalex.source.mysql.MyPoolSource Maven / Gradle / Ivy
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkalex.source.mysql;
import java.nio.ByteBuffer;
import java.sql.SQLException;
import java.util.Properties;
import java.util.concurrent.*;
import java.util.logging.Logger;
import org.redkale.net.AsyncConnection;
import org.redkale.source.PoolTcpSource;
import org.redkale.util.*;
import static org.redkalex.source.mysql.MySQLs.*;
/**
*
* @author zhangjx
*/
public class MyPoolSource extends PoolTcpSource {
protected static final String CONN_ATTR_BYTESBAME = "BYTESBAME";
public MyPoolSource(String rwtype, ArrayBlockingQueue queue, Semaphore semaphore, Properties prop,
Logger logger, ObjectPool bufferPool, ThreadPoolExecutor executor) {
super(rwtype, queue, semaphore, prop, logger, bufferPool, executor);
}
@Override
protected ByteBuffer reqConnectBuffer(AsyncConnection conn) {
if (conn.getAttribute(CONN_ATTR_BYTESBAME) == null) conn.setAttribute(CONN_ATTR_BYTESBAME, new byte[1024]);
return null;
}
protected static final String CONN_ATTR_PROTOCOL_VERSION = "PROTOCOL_VERSION";
@Override
protected void respConnectBuffer(final ByteBuffer buffer, CompletableFuture future, AsyncConnection conn) {
final byte[] bytes = conn.getAttribute(CONN_ATTR_BYTESBAME);
if (true) {
//MySQLIO.doHandshake
final int packetLength = (buffer.get() & 0xff) + ((buffer.get() & 0xff) << 8) + ((buffer.get() & 0xff) << 16);
final byte multiPacketSeq = buffer.get();
final int pkgstart = buffer.position();
long clientParam = 0;
int protocolVersion = buffer.get();
if (protocolVersion < 10) { //小于10的版本暂不实现
bufferPool.accept(buffer);
conn.dispose();
future.completeExceptionally(new SQLException("Not supported protocolVersion(" + protocolVersion + "), must greaterthan 10"));
return;
}
String serverVersion = readASCIIString(buffer, bytes);
if (serverVersion.startsWith("0.") || serverVersion.startsWith("1.")
|| serverVersion.startsWith("2.") || serverVersion.startsWith("3.") || serverVersion.startsWith("4.")) {
bufferPool.accept(buffer);
conn.dispose();
future.completeExceptionally(new SQLException("Not supported serverVersion(" + serverVersion + "), must greaterthan 5.0"));
return;
}
final boolean useNewLargePackets = true;
final long threadId = readLong(buffer);
String seed = null;
if (protocolVersion > 9) {
// read auth-plugin-data-part-1 (string[8])
seed = readASCIIString(buffer, 8);
// read filler ([00])
byte b = buffer.get();
System.out.println("-------------b: " + (int) b);
} else {
// read scramble (string[NUL])
seed = readASCIIString(buffer, bytes);
}
int authPluginDataLength = 0;
boolean hasLongColumnInfo = false;
int serverCapabilities = buffer.hasRemaining() ? readInt(buffer) : 0;
final int serverCharsetIndex = buffer.get() & 0xff;
final int serverStatus = readInt(buffer);
serverCapabilities |= readInt(buffer) << 16;
if ((serverCapabilities & CLIENT_PLUGIN_AUTH) != 0) {
// read length of auth-plugin-data (1 byte)
authPluginDataLength = buffer.get() & 0xff;
} else {
// read filler ([00])
buffer.get();
}
// next 10 bytes are reserved (all [00])
buffer.position(buffer.position() + 10);
if ((serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) {
String seedPart2;
StringBuilder newSeed;
// read string[$len] auth-plugin-data-part-2 ($len=MAX(13, length of auth-plugin-data - 8))
if (authPluginDataLength > 0) {
// TODO: disabled the following check for further clarification
// if (this.authPluginDataLength < 21) {
// forceClose();
// throw SQLError.createSQLException(Messages.getString("MysqlIO.103"),
// SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, getExceptionInterceptor());
// }
seedPart2 = readASCIIString(buffer, authPluginDataLength - 8); //buf.readString("ASCII", getExceptionInterceptor(), this.authPluginDataLength - 8);
newSeed = new StringBuilder(authPluginDataLength);
} else {
seedPart2 = readASCIIString(buffer, bytes);
newSeed = new StringBuilder(SEED_LENGTH);
}
newSeed.append(seed);
newSeed.append(seedPart2);
seed = newSeed.toString();
}
if (((serverCapabilities & CLIENT_COMPRESS) != 0)) {
clientParam |= CLIENT_COMPRESS;
}
if (this.database != null && !this.database.isEmpty()) {
clientParam |= CLIENT_CONNECT_WITH_DB;
}
if ((serverCapabilities & CLIENT_LONG_FLAG) != 0) {
// We understand other column flags, as well
clientParam |= CLIENT_LONG_FLAG;
hasLongColumnInfo = true;
}
clientParam |= CLIENT_LONG_PASSWORD; // for long passwords
//
// 4.1 has some differences in the protocol
//
boolean has41NewNewProt = false;
boolean use41Extensions = false;
if ((serverCapabilities & CLIENT_RESERVED) != 0) {
if ((serverCapabilities & CLIENT_PROTOCOL_41) != 0) {
clientParam |= CLIENT_PROTOCOL_41;
has41NewNewProt = true;
// Need this to get server status values
clientParam |= CLIENT_TRANSACTIONS;
// We always allow multiple result sets
clientParam |= CLIENT_MULTI_RESULTS;
// We allow the user to configure whether
// or not they want to support multiple queries
// (by default, this is disabled).
//if (this.connection.getAllowMultiQueries()) {
clientParam |= CLIENT_MULTI_STATEMENTS;
//}
} else {
clientParam |= CLIENT_RESERVED;
has41NewNewProt = false;
}
use41Extensions = true;
}
int passwordLength = 16;
int userLength = (this.username != null) ? this.username.length() : 0;
int databaseLength = (this.database != null) ? database.length() : 0;
int packLength = ((userLength + passwordLength + databaseLength) * 3) + 7 + HEADER_LENGTH + AUTH_411_OVERHEAD;
boolean ssl = false;
if (!ssl) {
if ((serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) {
clientParam |= CLIENT_SECURE_CONNECTION;
//secureAuth411(null, packLength, username, password, database, true, false);
{ //start secureAuth411
buffer.clear();
if (use41Extensions) {
buffer.putLong(clientParam);
buffer.putLong(255 * 255 * 255);
{ //appendCharsetByteForHandshake
int charsetIndex = CharsetMapping.getCollationIndexForJavaEncoding(this.encoding == null || this.encoding.isEmpty() ? "UTF-8" : this.encoding);
if (charsetIndex == 0) charsetIndex = CharsetMapping.MYSQL_COLLATION_INDEX_utf8;
buffer.put((byte) charsetIndex);
System.out.println("charsetIndex = " + charsetIndex);
}
// Set of bytes reserved for future use.
buffer.put(new byte[23]);
} else {
buffer.putInt((int) clientParam);
buffer.putInt(255 * 255 * 255);
}
{ // User/Password data
MySQLs.writeUTF8String(buffer, this.username);
if (this.password.length() != 0) {
buffer.put((byte) 0x14);
try {
buffer.put(scramble411(password, seed, this.encoding));
} catch (Exception se) {
bufferPool.accept(buffer);
conn.dispose();
future.completeExceptionally(se);
return;
}
} else {
/* For empty password */
buffer.put((byte) 0);
}
}
if (databaseLength > 0) {
MySQLs.writeUTF8String(buffer, this.database);
}
buffer.flip();
try {
conn.write(buffer);
System.out.println("----------------发送完成: " + buffer.remaining());
buffer.clear();
conn.read(buffer);
System.out.println("----------------读取完成: " + buffer.position());
buffer.flip();
try {
checkErrorPacket(buffer, bytes);
} catch (Exception se) {
bufferPool.accept(buffer);
conn.dispose();
future.completeExceptionally(se);
se.printStackTrace();
return;
}
bufferPool.accept(buffer);
future.complete(conn);
if (true) return;
} catch (Exception ee) {
bufferPool.accept(buffer);
conn.dispose();
future.completeExceptionally(ee);
ee.printStackTrace();
return;
}
}
//end secureAuth411
} else {
// Passwords can be 16 chars long
bufferPool.accept(buffer);
conn.dispose();
future.completeExceptionally(new SQLException("mysql connect error"));
return;
}
} else {
bufferPool.accept(buffer);
conn.dispose();
future.completeExceptionally(new SQLException("not supported ssl connect mysql"));
return;
}
System.out.println("(serverCapabilities & CLIENT_PROTOCOL_41) = " + (serverCapabilities & CLIENT_PROTOCOL_41));
System.out.println("(serverCapabilities & CLIENT_SECURE_CONNECTION) = " + (serverCapabilities & CLIENT_SECURE_CONNECTION));
System.out.println("protocolVersion = " + protocolVersion);
System.out.println("serverVersion = " + serverVersion);
System.out.println("threadId = " + threadId);
System.out.println("seed = " + seed);
System.out.println("has41NewNewProt = " + has41NewNewProt);
System.out.println("use41Extensions = " + use41Extensions);
System.out.println("authPluginDataLength = " + authPluginDataLength);
System.out.println("serverCapabilities = 0x" + Long.toHexString(serverCapabilities));
bufferPool.accept(buffer);
conn.dispose();
future.completeExceptionally(new SQLException("mysql connect error"));
return;
}
char cmd = (char) buffer.get();
int length = buffer.getInt();
if (cmd == 'Z') { //ReadyForQuery
bufferPool.accept(buffer);
future.complete(conn);
return;
}
bufferPool.accept(buffer);
conn.dispose();
future.completeExceptionally(new SQLException("mysql connect resp error"));
}
@Override
protected int getDefaultPort() {
return 3306;
}
@Override
protected CompletableFuture sendCloseCommand(AsyncConnection conn) {
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy