From 12cbfe02a88ffbd8c63340ee1f2123117a832bea Mon Sep 17 00:00:00 2001 From: Alexandr Gorshenin Date: Wed, 30 Sep 2026 16:13:37 +0100 Subject: [PATCH 1/3] Removed deprecated methods from GrpcTransportBuilder --- .../ydb/core/grpc/GrpcTransportBuilder.java | 72 +++---------------- .../tech/ydb/core/impl/YdbTransportImpl.java | 28 +------- .../ydb/core/impl/YdbTransportImplTest.java | 47 ------------ .../ydb/core/impl/pool/EndpointPoolTest.java | 2 - 4 files changed, 10 insertions(+), 139 deletions(-) diff --git a/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java b/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java index 66365d9bd..45645f34c 100644 --- a/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java +++ b/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java @@ -148,12 +148,20 @@ public Supplier getSchedulerFactory() { return schedulerFactory; } + @Deprecated public String getLocalDc() { return localDc; } public BalancingSettings getBalancingSettings() { - return balancingSettings; + if (balancingSettings != null) { + return balancingSettings; + } + if (localDc != null) { + return BalancingSettings.fromLocation(localDc); + } + + return BalancingSettings.defaultInstance(); } public Executor getCallExecutor() { @@ -236,24 +244,6 @@ public GrpcTransportBuilder addChannelInitializer(Consumer - * This method is deprecated. Use - * {@link GrpcTransportBuilder#withChannelFactoryBuilder(tech.ydb.core.impl.pool.ManagedChannelFactory.Builder)} - * instead - * - * @param ci custom NettyChannelBuilder initializer - * @return this - * @deprecated - */ - @Deprecated - public GrpcTransportBuilder withChannelInitializer( - Consumer ci - ) { - this.channelFactoryBuilder = tech.ydb.core.impl.pool.ShadedNettyChannelFactory.withInterceptor(ci); - return this; - } - /** * use {@link GrpcTransportBuilder#withBalancingSettings(tech.ydb.core.grpc.BalancingSettings) } instead * @param dc preferable location @@ -347,16 +337,6 @@ public GrpcTransportBuilder withReadTimeout(long timeout, TimeUnit unit) { return this; } - @Deprecated - public GrpcTransportBuilder withConnectTimeout(Duration timeout) { - return this; - } - - @Deprecated - public GrpcTransportBuilder withConnectTimeout(long timeout, TimeUnit unit) { - return this; - } - public GrpcTransportBuilder withDiscoveryTimeout(Duration timeout) { this.discoveryTimeoutMillis = timeout.toMillis(); Preconditions.checkArgument(discoveryTimeoutMillis > 0, "discoveryTimeoutMillis must be greater than 0"); @@ -444,28 +424,6 @@ public GrpcTransportBuilder withExtraBuildInfo(String extraBuildInfo) { return this; } - /** - * use {@link GrpcTransportBuilder#withGrpcRetry(boolean) } instead - * @return this - * @deprecated - */ - @Deprecated - public GrpcTransportBuilder enableRetry() { - this.grpcRetry = true; - return this; - } - - /** - * use {@link GrpcTransportBuilder#withGrpcRetry(boolean) } instead - * @return this - * @deprecated - */ - @Deprecated - public GrpcTransportBuilder disableRetry() { - this.grpcRetry = false; - return this; - } - public GrpcTransport build() { YdbTransportImpl impl = new YdbTransportImpl(this); try { @@ -476,16 +434,4 @@ public GrpcTransport build() { throw ex; } } - - @Deprecated - public GrpcTransport buildAsync(Runnable ready) { - YdbTransportImpl impl = new YdbTransportImpl(this); - try { - impl.startAsync(ready); - return impl; - } catch (RuntimeException ex) { - impl.close(); - throw ex; - } - } } diff --git a/core/src/main/java/tech/ydb/core/impl/YdbTransportImpl.java b/core/src/main/java/tech/ydb/core/impl/YdbTransportImpl.java index d0d8e1e4d..3de092607 100644 --- a/core/src/main/java/tech/ydb/core/impl/YdbTransportImpl.java +++ b/core/src/main/java/tech/ydb/core/impl/YdbTransportImpl.java @@ -41,7 +41,7 @@ public class YdbTransportImpl extends BaseGrpcTransport { public YdbTransportImpl(GrpcTransportBuilder builder) { super(builder); - BalancingSettings balancingSettings = getBalancingSettings(builder); + BalancingSettings balancingSettings = builder.getBalancingSettings(); Duration discoveryTimeout = Duration.ofMillis(builder.getDiscoveryTimeoutMillis()); this.database = Strings.nullToEmpty(builder.getDatabase()); @@ -77,18 +77,6 @@ public String toString() { return "YdbTransport{endpoint=" + serverEndpoint + ", database=" + database + "}"; } - @Deprecated - public void startAsync(Runnable readyWatcher) { - endpointPool.setNewState(null, Collections.singletonList(serverEndpoint)); - discovery.start(); - if (readyWatcher != null) { - scheduler.execute(() -> { - discovery.waitReady(-1); - readyWatcher.run(); - }); - } - } - @Override protected void shutdown() { discovery.stop(); @@ -98,20 +86,6 @@ protected void shutdown() { YdbSchedulerFactory.shutdownScheduler(scheduler); } - private static BalancingSettings getBalancingSettings(GrpcTransportBuilder builder) { - BalancingSettings balancingSettings = builder.getBalancingSettings(); - if (balancingSettings != null) { - return balancingSettings; - } - - String localDc = builder.getLocalDc(); - if (localDc != null) { - return BalancingSettings.fromLocation(builder.getLocalDc()); - } - - return BalancingSettings.defaultInstance(); - } - @Override public ScheduledExecutorService getScheduler() { return scheduler; diff --git a/core/src/test/java/tech/ydb/core/impl/YdbTransportImplTest.java b/core/src/test/java/tech/ydb/core/impl/YdbTransportImplTest.java index e5fc1c5ab..087566642 100644 --- a/core/src/test/java/tech/ydb/core/impl/YdbTransportImplTest.java +++ b/core/src/test/java/tech/ydb/core/impl/YdbTransportImplTest.java @@ -2,7 +2,6 @@ import java.time.Duration; -import java.time.ZoneId; import java.util.HashMap; import java.util.Map; import java.util.Queue; @@ -140,52 +139,6 @@ public void defaultBuildNotReadyTest() { Assert.assertNull(ex.getCause()); } - @Test - public void asyncBuildGoodTest() { - Ticker tickerRequests = new Ticker(); - MockedScheduler scheduler = new MockedScheduler(MockedClock.create(ZoneId.of("UTC"))); - - Mockito.when(discoveryChannel.newCall(Mockito.eq(DiscoveryServiceGrpc.getListEndpointsMethod()), Mockito.any())) - .thenReturn(MockedCall.discovery("self", new EndpointRecord("node", 2136))); - - Mockito.when(discoveryChannel.newCall(Mockito.eq(DiscoveryServiceGrpc.getWhoAmIMethod()), Mockito.any())) - .thenReturn(MockedCall.whoAmICall(tickerRequests, "i am discovery")); - Mockito.when(transportChannel.newCall(Mockito.eq(DiscoveryServiceGrpc.getWhoAmIMethod()), Mockito.any())) - .thenReturn(MockedCall.whoAmICall(tickerRequests, "i am node")); - - CompletableFuture isReady = new CompletableFuture<>(); - - @SuppressWarnings("deprecation") - GrpcTransport transport = GrpcTransport.forConnectionString("grpc://mocked:2136/local") - .withSchedulerFactory(() -> scheduler) - .withChannelFactoryBuilder(builder -> channelFactory) - .buildAsync(() -> isReady.complete(null)); - - Assert.assertNotNull(transport); - Assert.assertFalse(isReady.isDone()); - - // before discovery completed we send requests to discovery endpoint - tickerRequests.noTasks(); - CompletableFuture> f1 = whoAmI(transport); - Assert.assertFalse(f1.isDone()); - - tickerRequests.runNextTask().noTasks(); - Assert.assertTrue(f1.isDone()); - Assert.assertEquals("i am discovery", f1.join().getValue().getUser()); - - // Complete discovery - Assert.assertFalse(isReady.isDone()); - scheduler.hasTasksCount(2).runNextTask().runNextTask(); - - CompletableFuture> f2 = whoAmI(transport); - Assert.assertFalse(f2.isDone()); - tickerRequests.runNextTask().noTasks(); - Assert.assertTrue(f2.isDone()); - Assert.assertEquals("i am node", f2.join().getValue().getUser()); - - Assert.assertTrue(isReady.isDone()); - } - @Test @SuppressWarnings("SleepWhileInLoop") public void asyncWaitingForReadyTest() throws Exception { diff --git a/core/src/test/java/tech/ydb/core/impl/pool/EndpointPoolTest.java b/core/src/test/java/tech/ydb/core/impl/pool/EndpointPoolTest.java index c0f343243..0af168638 100644 --- a/core/src/test/java/tech/ydb/core/impl/pool/EndpointPoolTest.java +++ b/core/src/test/java/tech/ydb/core/impl/pool/EndpointPoolTest.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.net.Socket; -import java.net.SocketAddress; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -43,7 +42,6 @@ public class EndpointPoolTest { public void setUp() throws IOException { mocks = MockitoAnnotations.openMocks(this); threadLocalStaticMock.when(ThreadLocalRandom::current).thenReturn(random); - Mockito.doNothing().when(socket).connect(Mockito.any(SocketAddress.class)); Mockito.when(socketFactory.createSocket()).thenReturn(socket); } From 308b35fc067610bc3f2925984d5ab1bd9f297cc3 Mon Sep 17 00:00:00 2001 From: Alexandr Gorshenin Date: Thu, 1 Oct 2026 15:05:50 +0100 Subject: [PATCH 2/3] Added tests --- .../ydb/core/grpc/GrpcTransportBuilder.java | 6 +- .../ydb/core/impl/auth/AuthCallOptions.java | 1 + .../core/grpc/GrpcTransportBuilderTest.java | 54 ++++ .../impl/pool/NettyChannelFactoryTest.java | 256 ++++++++++++++++++ core/src/test/resources/log4j2.xml | 6 + 5 files changed, 318 insertions(+), 5 deletions(-) create mode 100644 core/src/test/java/tech/ydb/core/grpc/GrpcTransportBuilderTest.java create mode 100644 core/src/test/java/tech/ydb/core/impl/pool/NettyChannelFactoryTest.java diff --git a/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java b/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java index 45645f34c..b0f2b5d32 100644 --- a/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java +++ b/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java @@ -172,15 +172,11 @@ public AuthRpcProvider getAuthProvider() { return authProvider; } + @Deprecated public long getReadTimeoutMillis() { return readTimeoutMillis; } - @Deprecated - public long getConnectTimeoutMillis() { - return 10_000; - } - public long getDiscoveryTimeoutMillis() { return discoveryTimeoutMillis; } diff --git a/core/src/main/java/tech/ydb/core/impl/auth/AuthCallOptions.java b/core/src/main/java/tech/ydb/core/impl/auth/AuthCallOptions.java index f30529c4c..30d4a1932 100644 --- a/core/src/main/java/tech/ydb/core/impl/auth/AuthCallOptions.java +++ b/core/src/main/java/tech/ydb/core/impl/auth/AuthCallOptions.java @@ -29,6 +29,7 @@ public AuthCallOptions() { this.readTimeoutMillis = 0; } + @SuppressWarnings("deprecation") public AuthCallOptions( ScheduledExecutorService scheduler, List endpoints, diff --git a/core/src/test/java/tech/ydb/core/grpc/GrpcTransportBuilderTest.java b/core/src/test/java/tech/ydb/core/grpc/GrpcTransportBuilderTest.java new file mode 100644 index 000000000..64880f96f --- /dev/null +++ b/core/src/test/java/tech/ydb/core/grpc/GrpcTransportBuilderTest.java @@ -0,0 +1,54 @@ +package tech.ydb.core.grpc; + +import org.junit.Assert; +import org.junit.Test; + +/** + * + * @author Aleksandr Gorshenin + */ +public class GrpcTransportBuilderTest { + private final static String YDB = "grpcs://some-host:3456/database"; + + @Test + public void defaultValuesTest() { + GrpcTransportBuilder builder = GrpcTransport.forConnectionString(YDB); + + Assert.assertEquals("/database", builder.getDatabase()); + Assert.assertEquals("some-host:3456", builder.getEndpoint()); + Assert.assertNull(builder.getCert()); + Assert.assertEquals(GrpcTransportBuilder.InitMode.SYNC, builder.getInitMode()); + Assert.assertNotNull(builder.getManagedChannelFactory()); + } + + @Test + public void balancingSettingsTest() { + BalancingSettings def = GrpcTransport.forConnectionString(YDB).getBalancingSettings(); + Assert.assertNotNull(def); + Assert.assertEquals(BalancingSettings.Policy.USE_ALL_NODES, def.getPolicy()); + Assert.assertNull(def.getPreferableLocation()); + + @SuppressWarnings("deprecation") + BalancingSettings localDc = GrpcTransport.forConnectionString(YDB) + .withLocalDataCenter("ca").getBalancingSettings(); + Assert.assertNotNull(localDc); + Assert.assertEquals(BalancingSettings.Policy.USE_PREFERABLE_LOCATION, localDc.getPolicy()); + Assert.assertEquals("ca", localDc.getPreferableLocation()); + + BalancingSettings detect = GrpcTransport.forConnectionString(YDB) + .withBalancingSettings(BalancingSettings.detectLocalDs()).getBalancingSettings(); + Assert.assertNotNull(detect); + Assert.assertEquals(BalancingSettings.Policy.USE_DETECT_LOCAL_DC, detect.getPolicy()); + Assert.assertNull(detect.getPreferableLocation()); + + @SuppressWarnings("deprecation") + BalancingSettings mixed = GrpcTransport.forConnectionString(YDB) + .withBalancingSettings(BalancingSettings.detectLocalDs()) + .withLocalDataCenter("ca") + .getBalancingSettings(); + + Assert.assertNotNull(mixed); + Assert.assertEquals(BalancingSettings.Policy.USE_DETECT_LOCAL_DC, mixed.getPolicy()); + Assert.assertNull(mixed.getPreferableLocation()); + } +} diff --git a/core/src/test/java/tech/ydb/core/impl/pool/NettyChannelFactoryTest.java b/core/src/test/java/tech/ydb/core/impl/pool/NettyChannelFactoryTest.java new file mode 100644 index 000000000..1edf8e2e5 --- /dev/null +++ b/core/src/test/java/tech/ydb/core/impl/pool/NettyChannelFactoryTest.java @@ -0,0 +1,256 @@ +package tech.ydb.core.impl.pool; + + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.security.cert.CertificateException; + +import com.google.common.io.ByteStreams; +import io.grpc.ClientInterceptor; +import io.grpc.ForwardingChannelBuilder2; +import io.grpc.ManagedChannel; +import io.grpc.Metadata; +import io.grpc.netty.NegotiationType; +import io.grpc.netty.NettyChannelBuilder; +import io.grpc.stub.MetadataUtils; +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.ChannelOption; +import io.netty.handler.ssl.util.SelfSignedCertificate; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import tech.ydb.core.grpc.GrpcTransport; +import tech.ydb.core.grpc.GrpcTransportBuilder; +import tech.ydb.core.grpc.YdbHeaders; + +/** + * + * @author Aleksandr Gorshenin + */ +public class NettyChannelFactoryTest { + private final static String MOCKED_HOST = "ydb.tech"; + private final static int MOCKED_PORT = 3345; + private final static MockedStatic.Verification FOR_ADDRESS = () -> NettyChannelBuilder + .forAddress(MOCKED_HOST, MOCKED_PORT); + + private AutoCloseable mocks; + private MockedStatic channelStaticMock; + private MockedStatic metadataUtilsStaticMock; + private final NettyChannelBuilder channelBuilderMock = Mockito.mock(NettyChannelBuilder.class); + private final ManagedChannel channelMock = Mockito.mock(ManagedChannel.class); + private final ArgumentCaptor metadataCapture = ArgumentCaptor.forClass(Metadata.class); + private final ClientInterceptor clientInterceptor = Mockito.mock(ClientInterceptor.class); + + @Before + @SuppressWarnings("deprecation") + public void setUp() { + mocks = MockitoAnnotations.openMocks(this); + channelStaticMock = Mockito.mockStatic(NettyChannelBuilder.class); + channelStaticMock.when(FOR_ADDRESS).thenReturn(channelBuilderMock); + metadataUtilsStaticMock = Mockito.mockStatic(MetadataUtils.class); + metadataUtilsStaticMock.when(() -> MetadataUtils.newAttachHeadersInterceptor(metadataCapture.capture())) + .thenReturn(clientInterceptor); + + Mockito.when(channelBuilderMock.negotiationType(ArgumentMatchers.any())) + .thenReturn(channelBuilderMock); + Mockito.when(channelBuilderMock.maxInboundMessageSize(ArgumentMatchers.anyInt())) + .thenReturn(channelBuilderMock); + Mockito.when(channelBuilderMock.withOption(ArgumentMatchers.any(), ArgumentMatchers.any())) + .thenReturn(channelBuilderMock); + Mockito.when(channelBuilderMock.intercept(ArgumentMatchers.any(ClientInterceptor.class))) + .thenReturn(channelBuilderMock); + Mockito.when(channelBuilderMock.nameResolverFactory(ArgumentMatchers.any())) + .thenReturn(channelBuilderMock); + Mockito.when(channelBuilderMock.keepAliveTime(ArgumentMatchers.anyLong(), ArgumentMatchers.any())) + .thenReturn(channelBuilderMock); + + Mockito.when(channelBuilderMock.build()).thenReturn(channelMock); + } + + @After + public void tearDown() throws Exception { + channelStaticMock.close(); + metadataUtilsStaticMock.close(); + mocks.close(); + } + + @Test + public void defaultParams() { + GrpcTransportBuilder builder = GrpcTransport.forHost(MOCKED_HOST, MOCKED_PORT, "/Root"); + ManagedChannelFactory factory = NettyChannelFactory.build().buildFactory(builder); + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(0)); + + Assert.assertSame(channelMock, factory.newManagedChannel(MOCKED_HOST, MOCKED_PORT, null)); + + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(1)); + + Mockito.verify(channelBuilderMock, Mockito.times(0)).negotiationType(NegotiationType.TLS); + Mockito.verify(channelBuilderMock, Mockito.times(1)).negotiationType(NegotiationType.PLAINTEXT); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .maxInboundMessageSize(NettyChannelFactory.INBOUND_MESSAGE_SIZE); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .defaultLoadBalancingPolicy(NettyChannelFactory.DEFAULT_BALANCER_POLICY); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .withOption(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT); + Mockito.verify(channelBuilderMock, Mockito.times(0)).enableRetry(); + Mockito.verify(channelBuilderMock, Mockito.times(1)).disableRetry(); + + + Metadata metadata = metadataCapture.getValue(); + Assert.assertEquals("/Root", metadata.get(YdbHeaders.DATABASE)); + Assert.assertNull(metadata.get(YdbHeaders.APPLICATION_NAME)); + Assert.assertNull(metadata.get(YdbHeaders.CLIENT_PROCESS_ID)); + } + + @Test + public void defaultSslFactory() { + GrpcTransportBuilder builder = GrpcTransport.forHost(MOCKED_HOST, MOCKED_PORT, "/Root") + .withSecureConnection() + .withGrpcRetry(true); + + ManagedChannelFactory factory = NettyChannelFactory.build().buildFactory(builder); + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(0)); + + Assert.assertSame(channelMock, factory.newManagedChannel(MOCKED_HOST, MOCKED_PORT, null)); + + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(1)); + + Mockito.verify(channelBuilderMock, Mockito.times(1)).negotiationType(NegotiationType.TLS); + Mockito.verify(channelBuilderMock, Mockito.times(0)).negotiationType(NegotiationType.PLAINTEXT); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .maxInboundMessageSize(NettyChannelFactory.INBOUND_MESSAGE_SIZE); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .defaultLoadBalancingPolicy(NettyChannelFactory.DEFAULT_BALANCER_POLICY); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .withOption(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT); + Mockito.verify(channelBuilderMock, Mockito.times(1)).enableRetry(); + Mockito.verify(channelBuilderMock, Mockito.times(0)).disableRetry(); + } + + @Test + public void customHeadersTest() { + GrpcTransportBuilder builder = GrpcTransport.forHost(MOCKED_HOST, MOCKED_PORT, "/Root") + .withApplicationName("test-application") + .withClientProcessId("client-hostname"); + ManagedChannelFactory factory = NettyChannelFactory.build().buildFactory(builder); + + Assert.assertSame(channelMock, factory.newManagedChannel(MOCKED_HOST, MOCKED_PORT, null)); + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(1)); + + Metadata metadata = metadataCapture.getValue(); + Assert.assertEquals("/Root", metadata.get(YdbHeaders.DATABASE)); + Assert.assertEquals("test-application", metadata.get(YdbHeaders.APPLICATION_NAME)); + Assert.assertEquals("client-hostname", metadata.get(YdbHeaders.CLIENT_PROCESS_ID)); + } + + @Test + public void customChannelInitializer() { + GrpcTransportBuilder builder = GrpcTransport.forHost(MOCKED_HOST, MOCKED_PORT, "/Root") + .withUseDefaultGrpcResolver(true); + + ManagedChannelFactory factory = NettyChannelFactory + .withInterceptor(ForwardingChannelBuilder2::useTransportSecurity) + .buildFactory(builder); + + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(0)); + + Assert.assertSame(channelMock, factory.newManagedChannel(MOCKED_HOST, MOCKED_PORT, null)); + + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(1)); + + Mockito.verify(channelBuilderMock, Mockito.times(1)).negotiationType(NegotiationType.PLAINTEXT); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .maxInboundMessageSize(NettyChannelFactory.INBOUND_MESSAGE_SIZE); + Mockito.verify(channelBuilderMock, Mockito.times(0)) + .defaultLoadBalancingPolicy(NettyChannelFactory.DEFAULT_BALANCER_POLICY); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .withOption(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT); + Mockito.verify(channelBuilderMock, Mockito.times(1)).withOption(ChannelOption.TCP_NODELAY, Boolean.TRUE); + Mockito.verify(channelBuilderMock, Mockito.times(1)).useTransportSecurity(); + } + + @Test + public void addChannelInitializerTest() { + GrpcTransportBuilder builder = GrpcTransport.forHost(MOCKED_HOST, MOCKED_PORT, "/Root") + .withUseDefaultGrpcResolver(true) + .addChannelInitializer(ci -> ci.usePlaintext()) + .addChannelInitializer(ci -> ci.userAgent("TEST")); + + ManagedChannelFactory factory = NettyChannelFactory.build().buildFactory(builder); + + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(0)); + + Assert.assertSame(channelMock, factory.newManagedChannel(MOCKED_HOST, MOCKED_PORT, null)); + + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(1)); + + Mockito.verify(channelBuilderMock, Mockito.times(1)).negotiationType(NegotiationType.PLAINTEXT); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .maxInboundMessageSize(NettyChannelFactory.INBOUND_MESSAGE_SIZE); + Mockito.verify(channelBuilderMock, Mockito.times(0)) + .defaultLoadBalancingPolicy(NettyChannelFactory.DEFAULT_BALANCER_POLICY); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .withOption(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT); + Mockito.verify(channelBuilderMock, Mockito.times(1)).withOption(ChannelOption.TCP_NODELAY, Boolean.TRUE); + Mockito.verify(channelBuilderMock, Mockito.times(1)).usePlaintext(); + Mockito.verify(channelBuilderMock, Mockito.times(1)).userAgent("TEST"); + } + + @Test + public void customSslFactory() throws CertificateException, IOException { + SelfSignedCertificate selfSignedCert = new SelfSignedCertificate(MOCKED_HOST); + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteStreams.copy(Files.newInputStream(selfSignedCert.certificate().toPath()), baos); + + GrpcTransportBuilder builder = GrpcTransport.forHost(MOCKED_HOST, MOCKED_PORT, "/Root") + .withSecureConnection(baos.toByteArray()) + .withGrpcRetry(false); + + ManagedChannelFactory factory = NettyChannelFactory.build().buildFactory(builder); + + Assert.assertSame(channelMock, factory.newManagedChannel(MOCKED_HOST, MOCKED_PORT, null)); + + } finally { + selfSignedCert.delete(); + } + + channelStaticMock.verify(FOR_ADDRESS, Mockito.times(1)); + + Mockito.verify(channelBuilderMock, Mockito.times(1)).negotiationType(NegotiationType.TLS); + Mockito.verify(channelBuilderMock, Mockito.times(0)).negotiationType(NegotiationType.PLAINTEXT); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .maxInboundMessageSize(NettyChannelFactory.INBOUND_MESSAGE_SIZE); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .defaultLoadBalancingPolicy(NettyChannelFactory.DEFAULT_BALANCER_POLICY); + Mockito.verify(channelBuilderMock, Mockito.times(1)) + .withOption(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT); + Mockito.verify(channelBuilderMock, Mockito.times(0)).enableRetry(); + Mockito.verify(channelBuilderMock, Mockito.times(1)).disableRetry(); + } + + @Test + public void invalidSslCert() { + byte[] cert = new byte[] { 0x01, 0x02, 0x03 }; + GrpcTransportBuilder builder = GrpcTransport.forHost(MOCKED_HOST, MOCKED_PORT, "/Root") + .withSecureConnection(cert); + + ManagedChannelFactory factory = ChannelFactoryLoader.load().buildFactory(builder); + + RuntimeException ex = Assert.assertThrows(RuntimeException.class, + () -> factory.newManagedChannel(MOCKED_HOST, MOCKED_PORT, null)); + + Assert.assertEquals("cannot create ssl context", ex.getMessage()); + Assert.assertNotNull(ex.getCause()); + Assert.assertTrue(ex.getCause() instanceof IllegalArgumentException); + Assert.assertEquals("Input stream does not contain valid certificates.", ex.getCause().getMessage()); + } +} diff --git a/core/src/test/resources/log4j2.xml b/core/src/test/resources/log4j2.xml index 048bbff75..3dd9d6322 100644 --- a/core/src/test/resources/log4j2.xml +++ b/core/src/test/resources/log4j2.xml @@ -10,6 +10,9 @@ + + + @@ -21,6 +24,9 @@ + + + From a147fe6597e70ad1eb3caa8492f786dc0512eca2 Mon Sep 17 00:00:00 2001 From: Alexandr Gorshenin Date: Fri, 2 Oct 2026 10:30:50 +0100 Subject: [PATCH 3/3] Updated javadoc --- .../tech/ydb/core/grpc/GrpcTransportBuilder.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java b/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java index b0f2b5d32..a014bf782 100644 --- a/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java +++ b/core/src/main/java/tech/ydb/core/grpc/GrpcTransportBuilder.java @@ -148,6 +148,11 @@ public Supplier getSchedulerFactory() { return schedulerFactory; } + /** + * use {@link GrpcTransportBuilder#getBalancingSettings()} instead + * @deprecated + * @return current local dc + */ @Deprecated public String getLocalDc() { return localDc; @@ -172,6 +177,11 @@ public AuthRpcProvider getAuthProvider() { return authProvider; } + /** + * use {@link tech.ydb.core.settings.BaseRequestSettings#getRequestTimeout()} instead + * @return default request timeout + * @deprecated + */ @Deprecated public long getReadTimeoutMillis() { return readTimeoutMillis; @@ -307,7 +317,7 @@ public GrpcTransportBuilder withGrpcCompression(@Nonnull GrpcCompression compres } /** - * use tech.ydb.table.settings.RequestSettings#setTimeout(java.time.Duration) instead + * use {@link tech.ydb.core.settings.BaseRequestSettings.BaseBuilder#withRequestTimeout(java.time.Duration)} instead * @param timeout global timeout for grpc calls * @return this * @deprecated @@ -320,7 +330,7 @@ public GrpcTransportBuilder withReadTimeout(Duration timeout) { } /** - * use tech.ydb.table.settings.RequestSettings#setTimeout(long, java.time.TimeUnit) instead + * use {@link tech.ydb.core.settings.BaseRequestSettings.BaseBuilder#withRequestTimeout(java.time.Duration)} instead * @param timeout size of global timeout for grpc calls * @param unit time unit of global timeout for grpc calls * @return this