下面列出了 io.netty.handler.codec.http2.Http2FrameLogger #reactor.util.annotation.Nullable 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
@Nullable
@SuppressWarnings("unchecked")
public <T> T decode(Value value, Type spannerType, Class<? extends T> type) {
Assert.requireNonNull(value, "value must not be null");
Assert.requireNonNull(spannerType, "spannerType must not be null");
Assert.requireNonNull(type, "type must not be null");
for (Codec<?> codec : this.codecs) {
if (codec.canDecode(spannerType, type)) {
return ((Codec<T>) codec).decode(value, spannerType);
}
}
throw new IllegalArgumentException(
String.format("Cannot decode value of type %s to %s", spannerType, type.getName()));
}
@Nullable
private static SyntheticMetadataMessage decodeInMetadata(ByteBuf buf, short header, ConnectionContext context, MetadataDecodeContext decodeContext) {
ServerMessage message;
if (EOF == header && EofMessage.isValidSize(buf.readableBytes())) {
message = EofMessage.decode(buf);
} else {
message = DefinitionMetadataMessage.decode(buf, context);
}
if (message instanceof ServerStatusMessage) {
context.setServerStatuses(((ServerStatusMessage) message).getServerStatuses());
}
return decodeContext.putPart(message);
}
/**
* Visible for unit tests.
*/
MySqlConnection(
Client client, ConnectionContext context, Codecs codecs, IsolationLevel level,
@Nullable String product, @Nullable Predicate<String> prepare
) {
this.client = client;
this.context = context;
this.deprecateEof = (this.context.getCapabilities() & Capabilities.DEPRECATE_EOF) != 0;
this.sessionLevel = level;
this.currentLevel = level;
this.codecs = codecs;
this.metadata = new MySqlConnectionMetadata(context.getServerVersion().toString(), product);
this.batchSupported = (context.getCapabilities() & Capabilities.MULTI_STATEMENTS) != 0;
this.prepare = prepare;
if (this.batchSupported) {
logger.debug("Batch is supported by server");
} else {
logger.warn("The MySQL server does not support batch executing, fallback to executing one-by-one");
}
}
private static IsolationLevel convertIsolationLevel(@Nullable String name) {
if (name == null) {
logger.warn("Isolation level is null in current session, fallback to repeatable read");
return IsolationLevel.REPEATABLE_READ;
}
switch (name) {
case "READ-UNCOMMITTED":
return IsolationLevel.READ_UNCOMMITTED;
case "READ-COMMITTED":
return IsolationLevel.READ_COMMITTED;
case "REPEATABLE-READ":
return IsolationLevel.REPEATABLE_READ;
case "SERIALIZABLE":
return IsolationLevel.SERIALIZABLE;
default:
logger.warn("Unknown isolation level {} in current session, fallback to repeatable read", name);
return IsolationLevel.REPEATABLE_READ;
}
}
static MySqlSslConfiguration create(
SslMode sslMode, String[] tlsVersion, @Nullable String sslCa,
@Nullable String sslKey, @Nullable CharSequence sslKeyPassword, @Nullable String sslCert,
@Nullable Function<SslContextBuilder, SslContextBuilder> sslContextBuilderCustomizer
) {
requireNonNull(sslMode, "sslMode must not be null");
if (!sslMode.startSsl()) {
return DISABLED;
}
requireNonNull(tlsVersion, "tlsVersion must not be null");
require(!sslMode.verifyCertificate() || sslCa != null, "sslCa must not be null when verifying mode has set");
require((sslKey == null && sslCert == null) || (sslKey != null && sslCert != null), "sslKey and cert must be both null or both non-null");
return new MySqlSslConfiguration(sslMode, tlsVersion, sslCa, sslKey, sslKeyPassword, sslCert, sslContextBuilderCustomizer);
}
private MySqlConnectionConfiguration(
boolean isHost, String domain, int port, @Nullable MySqlSslConfiguration ssl,
@Nullable Duration connectTimeout, ZeroDateOption zeroDateOption, @Nullable ZoneId serverZoneId,
String user, @Nullable CharSequence password, @Nullable String database,
@Nullable Predicate<String> preferPrepareStatement, Extensions extensions
) {
this.isHost = isHost;
this.domain = domain;
this.port = port;
this.connectTimeout = connectTimeout;
this.ssl = requireNonNull(ssl, "ssl must not be null");
this.serverZoneId = serverZoneId;
this.zeroDateOption = requireNonNull(zeroDateOption, "zeroDateOption must not be null");
this.user = requireNonNull(user, "user must not be null");
this.password = password;
this.database = database == null || database.isEmpty() ? "" : database;
this.preferPrepareStatement = preferPrepareStatement;
this.extensions = requireNonNull(extensions, "extensions must not be null");
}
@Nullable
private static LocalDateTime decodeBinary(ByteBuf buf) {
int bytes = buf.readableBytes();
LocalDate date = LocalDateCodec.readDateBinary(buf, bytes);
if (date == null) {
return null;
}
if (bytes < DateTimes.DATETIME_SIZE) {
return LocalDateTime.of(date, LocalTime.MIDNIGHT);
}
byte hour = buf.readByte();
byte minute = buf.readByte();
byte second = buf.readByte();
if (bytes < DateTimes.MICRO_DATETIME_SIZE) {
return LocalDateTime.of(date, LocalTime.of(hour, minute, second));
}
int nano = (int) (buf.readUnsignedIntLE() * DateTimes.NANOS_OF_MICRO);
return LocalDateTime.of(date, LocalTime.of(hour, minute, second, nano));
}
@Nullable
static LocalDate readDateBinary(ByteBuf buf, int bytes) {
if (bytes < DateTimes.DATE_SIZE) {
return null;
}
short year = buf.readShortLE();
byte month = buf.readByte();
byte day = buf.readByte();
if (month == 0 || day == 0) {
return null;
}
return LocalDate.of(year, month, day);
}
static JdbcTemplate jdbc(MySqlConnectionConfiguration configuration, @Nullable String timezone) {
HikariDataSource source = new HikariDataSource();
source.setJdbcUrl(String.format("jdbc:mysql://%s:%d/%s", configuration.getDomain(), configuration.getPort(), configuration.getDatabase()));
source.setUsername(configuration.getUser());
source.setPassword(Optional.ofNullable(configuration.getPassword()).map(Object::toString).orElse(null));
source.setMaximumPoolSize(1);
source.setConnectionTimeout(Optional.ofNullable(configuration.getConnectTimeout()).map(Duration::toMillis).orElse(0L));
if (timezone != null) {
source.addDataSourceProperty("serverTimezone", timezone);
}
return new JdbcTemplate(source);
}
private static R2dbcException mappingSqlState(String errorMessage, String sqlState, int errorCode, @Nullable String sql) {
if (sqlState.startsWith(SYNTAX_ERROR_PREFIX)) {
return new R2dbcBadGrammarException(errorMessage, sqlState, errorCode, sql);
} else if (sqlState.startsWith(CONSTRAINT_VIOLATION_PREFIX)) {
return new R2dbcDataIntegrityViolationException(errorMessage, sqlState, errorCode);
} else if (sqlState.startsWith(TRANSACTION_ROLLBACK_PREFIX)) {
return new R2dbcRollbackException(errorMessage, sqlState, errorCode);
}
// Uncertain SQL state, all exceptions mismatch, fallback.
return new R2dbcNonTransientResourceException(errorMessage, null, errorCode);
}
@Override
public ParameterWriter append(@Nullable CharSequence csq, int start, int end) {
CharSequence s = csq == null ? "null" : csq;
if (start < 0 || start > s.length() || end < start || end > s.length()) {
throw new IndexOutOfBoundsException("start: " + start + ", end: " + end + ", str length: " + s.length());
}
return append0(s, start, end);
}
@Override
public void write(@Nullable String str, int off, int len) {
String s = str == null ? "null" : str;
if (off < 0 || off > s.length() || len < 0 || off + len > s.length() || off + len < 0) {
throw new IndexOutOfBoundsException("off: " + off + ", len: " + len + ", str length: " + s.length());
}
write0(s, off, len);
}
@Override
public void write(@Nullable char[] c) {
if (c == null) {
write((String) null);
return;
}
write0(c, 0, c.length);
}
@Override
public void write(@Nullable char[] c, int off, int len) {
if (c == null) {
write((String) null, off, len);
return;
}
if (off < 0 || off > c.length || len < 0 || off + len > c.length || off + len < 0) {
throw new IndexOutOfBoundsException("off: " + off + ", len: " + len + ", chars length: " + c.length);
}
write0(c, off, len);
}
@Nullable
private static ServerMessage decodeMessage(List<ByteBuf> buffers, ConnectionContext context, DecodeContext decodeContext) {
if (decodeContext instanceof ResultDecodeContext) {
// Maybe very large.
return decodeResult(buffers, context, (ResultDecodeContext) decodeContext);
} else if (decodeContext instanceof FetchDecodeContext) {
// Maybe very large.
return decodeFetch(buffers, context);
}
ByteBuf joined = JOINER.join(buffers);
try {
if (decodeContext instanceof CommandDecodeContext) {
return decodeCommandMessage(joined, context);
} else if (decodeContext instanceof PreparedMetadataDecodeContext) {
return decodePreparedMetadata(joined, context, (PreparedMetadataDecodeContext) decodeContext);
} else if (decodeContext instanceof PrepareQueryDecodeContext) {
return decodePrepareQuery(joined);
} else if (decodeContext instanceof ConnectionDecodeContext) {
return decodeConnectionMessage(joined, context);
}
} finally {
joined.release();
}
throw new IllegalStateException("unknown decode context type: " + decodeContext.getClass());
}
/**
* @param isBinary rows is binary.
* @param messages must include complete signal.
*/
MySqlResult(boolean isBinary, Codecs codecs, ConnectionContext context, @Nullable String generatedKeyName, Flux<ServerMessage> messages) {
this.isBinary = isBinary;
this.codecs = requireNonNull(codecs, "codecs must not be null");
this.context = requireNonNull(context, "context must not be null");
this.generatedKeyName = generatedKeyName;
this.messages = new AtomicReference<>(requireNonNull(messages, "messages must not be null"));
}
static MySqlConnectionConfiguration configuration(boolean autodetectExtensions, @Nullable ZoneId serverZoneId, @Nullable Predicate<String> preferPrepared) {
String password = System.getProperty("test.mysql.password");
assertThat(password).withFailMessage("Property test.mysql.password must exists and not be empty")
.isNotNull()
.isNotEmpty();
MySqlConnectionConfiguration.Builder builder = MySqlConnectionConfiguration.builder()
.host("127.0.0.1")
.connectTimeout(Duration.ofSeconds(3))
.user("root")
.password(password)
.database("r2dbc")
.autodetectExtensions(autodetectExtensions);
if (serverZoneId != null) {
builder.serverZoneId(serverZoneId);
}
if (preferPrepared == null) {
builder.useClientPrepareStatement();
} else {
builder.useServerPrepareStatement(preferPrepared);
}
return builder.build();
}
private static MySqlConnectionConfiguration hostedSslMode(SslMode sslMode, @Nullable String sslCa) {
return MySqlConnectionConfiguration.builder()
.host(HOST)
.user(USER)
.sslMode(sslMode)
.sslCa(sslCa)
.build();
}
/**
* @param client must be logged-in
* @param codecs built-in {@link Codecs}
* @param context capabilities must be initialized
* @param prepare judging for prefer use prepare statement to execute simple query
*/
static Mono<MySqlConnection> create(Client client, Codecs codecs, ConnectionContext context, @Nullable Predicate<String> prepare) {
requireNonNull(client, "client must not be null");
requireNonNull(codecs, "codecs must not be null");
requireNonNull(context, "context must not be null");
ServerVersion version = context.getServerVersion();
StringBuilder query = new StringBuilder(128);
// Maybe create a InitFlow for data initialization after login?
if (version.isGreaterThanOrEqualTo(TRAN_LEVEL_8X) || (version.isGreaterThanOrEqualTo(TRAN_LEVEL_5X) && version.isLessThan(TX_LEVEL_8X))) {
query.append("SELECT @@transaction_isolation AS i, @@version_comment AS v");
} else {
query.append("SELECT @@tx_isolation AS i, @@version_comment AS v");
}
Function<MySqlResult, Publisher<InitData>> handler;
if (context.shouldSetServerZoneId()) {
handler = FULL_INIT_HANDLER;
query.append(", @@system_time_zone AS s, @@time_zone AS t");
} else {
handler = INIT_HANDLER;
}
return new TextSimpleStatement(client, codecs, context, query.toString())
.execute()
.flatMap(handler)
.last()
.map(data -> {
ZoneId serverZoneId = data.serverZoneId;
if (serverZoneId != null) {
logger.debug("Set server time zone to {} from init query", serverZoneId);
context.setServerZoneId(serverZoneId);
}
return new MySqlConnection(client, context, codecs, data.level, data.product, prepare);
});
}
/**
* @param index the column index starting at 0
* @param type must be {@link ParameterizedType} linked {@code T}
* @param <T> generic type, like {@code Set<String>}, {@code List<String>} or JSON-Serializable type when JSON serializer valid.
* @return {@code type} specified generic instance.
*/
@Nullable
public <T> T get(int index, ParameterizedType type) {
requireNonNull(type, "type must not be null");
MySqlColumnMetadata info = rowMetadata.getColumnMetadata(index);
return codecs.decode(fields[index], info, type, binary, context);
}
@Nullable
public <T> T get(String name, ParameterizedType type) {
requireNonNull(type, "type must not be null");
MySqlColumnMetadata info = rowMetadata.getColumnMetadata(name);
return codecs.decode(fields[info.getIndex()], info, type, binary, context);
}
/**
* SHA1(password) all bytes xor SHA1( "random data from MySQL server" + SHA1(SHA1(password)) )
* <p>
* {@inheritDoc}
*/
@Override
public byte[] authentication(@Nullable CharSequence password, @Nullable byte[] salt, CharCollation collation) {
if (password == null || password.length() <= 0) {
return EMPTY_BYTES;
}
requireNonNull(salt, "salt must not be null when password exists");
requireNonNull(collation, "collation must not be null when password exists");
return AuthUtils.generalHash(ALGORITHM, IS_LEFT_SALT, password, salt, collation);
}
@Override
public byte[] authentication(@Nullable CharSequence password, @Nullable byte[] salt, CharCollation collation) {
if (password == null || password.length() <= 0) {
return new byte[]{TERMINAL};
}
requireNonNull(collation, "collation must not be null when password exists");
return AuthUtils.encodeTerminal(CharBuffer.wrap(password), collation.getCharset());
}
/**
* SHA256(password) `all bytes xor` SHA256( SHA256( ~SHA256(password) ) + "random data from MySQL server" )
* <p>
* {@inheritDoc}
*/
@Override
public byte[] authentication(@Nullable CharSequence password, @Nullable byte[] salt, CharCollation collation) {
if (password == null || password.length() <= 0) {
return new byte[]{TERMINAL};
}
requireNonNull(salt, "salt must not be null when password exists");
requireNonNull(collation, "collation must not be null when password exists");
return AuthUtils.generalHash(ALGORITHM, IS_LEFT_SALT, password, salt, collation);
}
@Override
public byte[] authentication(@Nullable CharSequence password, @Nullable byte[] salt, CharCollation collation) {
if (password == null || password.length() <= 0) {
return new byte[]{TERMINAL};
}
requireNonNull(collation, "collation must not be null when password exists");
return AuthUtils.encodeTerminal(CharBuffer.wrap(password), collation.getCharset());
}
@Nullable
private static Integer determineSubjectType(Object type) {
if (type instanceof Integer) {
return (Integer) type;
} else {
try {
return Integer.parseInt(type.toString());
} catch (NumberFormatException e) {
return null;
}
}
}
static Mono<Client> connect(SocketAddress address, MySqlSslConfiguration ssl, ConnectionContext context, @Nullable Duration connectTimeout) {
requireNonNull(address, "address must not be null");
requireNonNull(ssl, "ssl must not be null");
requireNonNull(context, "context must not be null");
TcpClient tcpClient = TcpClient.newConnection();
if (connectTimeout != null) {
tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.toIntExact(connectTimeout.toMillis()));
}
return tcpClient.remoteAddress(() -> address).connect()
.map(conn -> new ReactorNettyClient(conn, ssl, context));
}
static WriteSubscriber create(ChannelHandlerContext ctx, ChannelPromise promise, @Nullable SequenceIdProvider provider) {
if (provider == null) {
// Used by this message ByteBuf stream only, can be unsafe.
provider = SequenceIdProvider.unsafe();
}
return new WriteSubscriber(ctx, promise, provider);
}
private MySqlSslConfiguration(
SslMode sslMode, String[] tlsVersion, @Nullable String sslCa,
@Nullable String sslKey, @Nullable CharSequence sslKeyPassword, @Nullable String sslCert,
@Nullable Function<SslContextBuilder, SslContextBuilder> sslContextBuilderCustomizer
) {
this.sslMode = sslMode;
this.tlsVersion = tlsVersion;
this.sslCa = sslCa;
this.sslKey = sslKey;
this.sslKeyPassword = sslKeyPassword;
this.sslCert = sslCert;
this.sslContextBuilderCustomizer = sslContextBuilderCustomizer;
}
@Nullable
private <T> T queryOne(HostAndPort hostAndPort, String schemeName, Class<T> descriptorType) {
List<StoreRecord> records = exporter.getLatestRecords(hostAndPort, schemeName,
TimeUnit.MINUTES.toMillis(SINGLE_QUERY_DURATION));
return records.stream().map(StoreRecord::getValue)
.map(it -> JsonUtils.parseObject(it, descriptorType))
.findFirst()
.orElse(null);
}