public class BinaryLogClient implementsBinaryLogClientMXBean {private static final SSLSocketFactory DEFAULT_REQUIRED_SSL_MODE_SOCKET_FACTORY = newDefaultSSLSocketFactory() {
@Overrideprotected void initSSLContext(SSLContext sc) throwsGeneralSecurityException {
sc.init(null, newTrustManager[]{newX509TrustManager() {
@Overridepublic voidcheckClientTrusted(X509Certificate[] x509Certificates, String s)throwsCertificateException { }
@Overridepublic voidcheckServerTrusted(X509Certificate[] x509Certificates, String s)throwsCertificateException { }
@OverridepublicX509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];
}
}
},null);
}
};private static final SSLSocketFactory DEFAULT_VERIFY_CA_SSL_MODE_SOCKET_FACTORY = newDefaultSSLSocketFactory();// https://dev.mysql.com/doc/internals/en/sending-more-than-16mbyte.html
private static final int MAX_PACKET_LENGTH = 16777215;private final Logger logger =Logger.getLogger(getClass().getName());private finalString hostname;private final intport;private finalString schema;private finalString username;private finalString password;private boolean blocking = true;private long serverId = 65535;private volatileString binlogFilename;private volatile long binlogPosition = 4;private volatile longconnectionId;private SSLMode sslMode =SSLMode.DISABLED;privateGtidSet gtidSet;private final Object gtidSetAccessLock = newObject();private booleangtidSetFallbackToPurged;private EventDeserializer eventDeserializer = newEventDeserializer();private final List eventListeners = new LinkedList();private final List lifecycleListeners = new LinkedList();privateSocketFactory socketFactory;privateSSLSocketFactory sslSocketFactory;private volatilePacketChannel channel;private volatile booleanconnected;privateThreadFactory threadFactory;private boolean keepAlive = true;private long keepAliveInterval = TimeUnit.MINUTES.toMillis(1);private longheartbeatInterval;private volatile longeventLastSeen;private long connectTimeout = TimeUnit.SECONDS.toMillis(3);private volatileExecutorService keepAliveThreadExecutor;private final Lock connectLock = newReentrantLock();/*** Alias for BinaryLogClient("localhost", 3306, <no schema> = null, username, password).
*@seeBinaryLogClient#BinaryLogClient(String, int, String, String, String)*/
publicBinaryLogClient(String username, String password) {this("localhost", 3306, null, username, password);
}/*** Alias for BinaryLogClient("localhost", 3306, schema, username, password).
*@seeBinaryLogClient#BinaryLogClient(String, int, String, String, String)*/
publicBinaryLogClient(String schema, String username, String password) {this("localhost", 3306, schema, username, password);
}/*** Alias for BinaryLogClient(hostname, port, <no schema> = null, username, password).
*@seeBinaryLogClient#BinaryLogClient(String, int, String, String, String)*/
public BinaryLogClient(String hostname, intport, String username, String password) {this(hostname, port, null, username, password);
}/***@paramhostname mysql server hostname
*@paramport mysql server port
*@paramschema database name, nullable. Note that this parameter has nothing to do with event filtering. It‘s
* used only during the authentication.
*@paramusername login name
*@parampassword password*/
public BinaryLogClient(String hostname, intport, String schema, String username, String password) {this.hostname =hostname;this.port =port;this.schema =schema;this.username =username;this.password =password;
}public booleanisBlocking() {returnblocking;
}/***@paramblocking blocking mode. If set to false - BinaryLogClient will disconnect after the last event.*/
public void setBlocking(booleanblocking) {this.blocking =blocking;
}publicSSLMode getSSLMode() {returnsslMode;
}public voidsetSSLMode(SSLMode sslMode) {if (sslMode == null) {throw new IllegalArgumentException("SSL mode cannot be NULL");
}this.sslMode =sslMode;
}/***@returnserver id (65535 by default)
*@see#setServerId(long)*/
public longgetServerId() {returnserverId;
}/***@paramserverId server id (in the range from 1 to 2^32 - 1). This value MUST be unique across whole replication
* group (that is, different from any other server id being used by any master or slave). Keep in mind that each
* binary log client (mysql-binlog-connector-java/BinaryLogClient, mysqlbinlog, etc) should be treated as a
* simplified slave and thus MUST also use a different server id.
*@see#getServerId()*/
public void setServerId(longserverId) {this.serverId =serverId;
}/***@returnbinary log filename, nullable (and null be default). Note that this value is automatically tracked by
* the client and thus is subject to change (in response to {@linkEventType#ROTATE}, for example).
*@see#setBinlogFilename(String)*/
publicString getBinlogFilename() {returnbinlogFilename;
}/***@parambinlogFilename binary log filename.
* Special values are:
*
*
null, which turns on automatic resolution (resulting in the last known binlog and position). This is what* happens by default when you don‘t specify binary log filename explicitly.
*
"" (empty string), which instructs server to stream events starting from the oldest known binlog.*
*@see#getBinlogFilename()*/
public voidsetBinlogFilename(String binlogFilename) {this.binlogFilename =binlogFilename;
}/***@returnbinary log position of the next event, 4 by default (which is a position of first event). Note that this
* value changes with each incoming event.
*@see#setBinlogPosition(long)*/
public longgetBinlogPosition() {returnbinlogPosition;
}/***@parambinlogPosition binary log position. Any value less than 4 gets automatically adjusted to 4 on connect.
*@see#getBinlogPosition()*/
public void setBinlogPosition(longbinlogPosition) {this.binlogPosition =binlogPosition;
}/***@returnthread id*/
public longgetConnectionId() {returnconnectionId;
}/***@returnGTID set. Note that this value changes with each received GTID event (provided client is in GTID mode).
*@see#setGtidSet(String)*/
publicString getGtidSet() {synchronized(gtidSetAccessLock) {return gtidSet != null ? gtidSet.toString() : null;
}
}/***@paramgtidSet GTID set (can be an empty string).
*
NOTE #1: Any value but null will switch BinaryLogClient into a GTID mode (this will also set binlogFilename
* to "" (provided it‘s null) forcing MySQL to send events starting from the oldest known binlog (keep in mind
* that connection will fail if gtid_purged is anything but empty (unless
* {@link#setGtidSetFallbackToPurged(boolean)} is set to true))).
*
NOTE #2: {@link#setBinlogFilename(String)} and {@link#setBinlogPosition(long)} can be used to specify the
* exact position from which MySQL server should start streaming events (taking into account GTID set).
*
NOTE #3: GTID set is automatically updated with each incoming GTID event (provided GTID mode is on).
*@see#getGtidSet()
*@see#setGtidSetFallbackToPurged(boolean)*/
public voidsetGtidSet(String gtidSet) {if (gtidSet != null && this.binlogFilename == null) {this.binlogFilename = "";
}synchronized(gtidSetAccessLock) {this.gtidSet = gtidSet != null ? new GtidSet(gtidSet) : null;
}