|
24 | 24 | import static org.mockito.Mockito.doReturn; |
25 | 25 | import static org.testng.Assert.assertEquals; |
26 | 26 | import static org.testng.Assert.assertNotNull; |
| 27 | +import io.netty.buffer.ByteBuf; |
27 | 28 | import io.netty.channel.EventLoopGroup; |
28 | 29 | import io.netty.util.concurrent.DefaultThreadFactory; |
29 | 30 | import java.util.ArrayList; |
|
42 | 43 | import org.apache.pulsar.broker.BrokerTestUtil; |
43 | 44 | import org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest; |
44 | 45 | import org.apache.pulsar.broker.authentication.AuthenticationService; |
| 46 | +import org.apache.pulsar.broker.service.ServerCnx; |
45 | 47 | import org.apache.pulsar.client.api.Authentication; |
46 | 48 | import org.apache.pulsar.client.api.AuthenticationFactory; |
47 | 49 | import org.apache.pulsar.client.api.Consumer; |
| 50 | +import org.apache.pulsar.client.api.InjectedClientCnxClientBuilder; |
48 | 51 | import org.apache.pulsar.client.api.Message; |
49 | 52 | import org.apache.pulsar.client.api.MessageRoutingMode; |
50 | 53 | import org.apache.pulsar.client.api.Producer; |
51 | 54 | import org.apache.pulsar.client.api.PulsarClient; |
52 | 55 | import org.apache.pulsar.client.api.Schema; |
53 | 56 | import org.apache.pulsar.client.api.SubscriptionInitialPosition; |
54 | 57 | import org.apache.pulsar.client.api.SubscriptionType; |
| 58 | +import org.apache.pulsar.client.impl.ClientBuilderImpl; |
55 | 59 | import org.apache.pulsar.client.impl.ClientCnx; |
56 | 60 | import org.apache.pulsar.client.impl.ConnectionPool; |
57 | 61 | import org.apache.pulsar.client.impl.PulsarClientImpl; |
58 | 62 | import org.apache.pulsar.client.impl.conf.ClientConfigurationData; |
59 | 63 | import org.apache.pulsar.client.impl.metrics.InstrumentProvider; |
| 64 | +import org.apache.pulsar.common.api.AuthData; |
| 65 | +import org.apache.pulsar.common.api.proto.BaseCommand; |
60 | 66 | import org.apache.pulsar.common.api.proto.CommandActiveConsumerChange; |
| 67 | +import org.apache.pulsar.common.api.proto.FeatureFlags; |
61 | 68 | import org.apache.pulsar.common.api.proto.ProtocolVersion; |
62 | 69 | import org.apache.pulsar.common.configuration.PulsarConfigurationLoader; |
63 | 70 | import org.apache.pulsar.common.naming.TopicName; |
|
66 | 73 | import org.apache.pulsar.common.policies.data.TenantInfo; |
67 | 74 | import org.apache.pulsar.common.policies.data.TenantInfoImpl; |
68 | 75 | import org.apache.pulsar.common.policies.data.TopicType; |
| 76 | +import org.apache.pulsar.common.protocol.Commands; |
69 | 77 | import org.apache.pulsar.common.schema.SchemaInfo; |
70 | 78 | import org.apache.pulsar.common.util.netty.EventLoopUtil; |
71 | 79 | import org.apache.pulsar.metadata.impl.ZKMetadataStore; |
@@ -429,6 +437,64 @@ public void testGetClientVersion() throws Exception { |
429 | 437 | .get(0).getClientVersion(), String.format("Pulsar-Java-v%s", PulsarVersion.getVersion())); |
430 | 438 | } |
431 | 439 |
|
| 440 | + @DataProvider |
| 441 | + public Object[][] booleanValues() { |
| 442 | + return new Object[][]{ |
| 443 | + {true}, |
| 444 | + {false} |
| 445 | + }; |
| 446 | + } |
| 447 | + |
| 448 | + @Test(dataProvider = "booleanValues") |
| 449 | + public void testConnectedWithClientSideFeatures(boolean supported) throws Exception { |
| 450 | + final String topic = BrokerTestUtil.newUniqueName("persistent://public/default/tp"); |
| 451 | + admin.topics().createNonPartitionedTopic(topic); |
| 452 | + |
| 453 | + // Create a client as a old version, which does not support "supportsReplDedupByLidAndEid". |
| 454 | + ClientBuilderImpl clientBuilder2 = |
| 455 | + (ClientBuilderImpl) PulsarClient.builder().serviceUrl(proxyService.getServiceUrl()); |
| 456 | + PulsarClientImpl injectedClient = InjectedClientCnxClientBuilder.create(clientBuilder2, |
| 457 | + (conf, eventLoopGroup) -> { |
| 458 | + return new ClientCnx(InstrumentProvider.NOOP, conf, eventLoopGroup) { |
| 459 | + |
| 460 | + @Override |
| 461 | + protected ByteBuf newConnectCommand() throws Exception { |
| 462 | + authenticationDataProvider = authentication.getAuthData(remoteHostName); |
| 463 | + AuthData authData = authenticationDataProvider.authenticate(AuthData.INIT_AUTH_DATA); |
| 464 | + BaseCommand cmd = |
| 465 | + Commands.newConnectWithoutSerialize(authentication.getAuthMethodName(), authData, |
| 466 | + this.protocolVersion, clientVersion, proxyToTargetBrokerAddress, |
| 467 | + null, null, null, null, null); |
| 468 | + FeatureFlags featureFlags = cmd.getConnect().getFeatureFlags(); |
| 469 | + featureFlags.setSupportsAuthRefresh(supported); |
| 470 | + featureFlags.setSupportsBrokerEntryMetadata(supported); |
| 471 | + featureFlags.setSupportsPartialProducer(supported); |
| 472 | + featureFlags.setSupportsTopicWatchers(supported); |
| 473 | + featureFlags.setSupportsReplDedupByLidAndEid(supported); |
| 474 | + featureFlags.setSupportsGetPartitionedMetadataWithoutAutoCreation(supported); |
| 475 | + return Commands.serializeWithSize(cmd); |
| 476 | + } |
| 477 | + }; |
| 478 | + }); |
| 479 | + |
| 480 | + // Verify: the broker will create a connection, which disabled "supportsReplDedupByLidAndEid". |
| 481 | + Producer<byte[]> producer = injectedClient.newProducer().topic(topic).create(); |
| 482 | + ServerCnx serverCnx = (ServerCnx) pulsar.getBrokerService().getTopic(topic, false).get().get() |
| 483 | + .getProducers().values().iterator().next().getCnx(); |
| 484 | + FeatureFlags featureFlags = serverCnx.getFeatures(); |
| 485 | + assertEquals(featureFlags.isSupportsAuthRefresh(), supported); |
| 486 | + assertEquals(featureFlags.isSupportsBrokerEntryMetadata(), supported); |
| 487 | + assertEquals(featureFlags.isSupportsPartialProducer(), supported); |
| 488 | + assertEquals(featureFlags.isSupportsTopicWatchers(), supported); |
| 489 | + assertEquals(featureFlags.isSupportsReplDedupByLidAndEid(), supported); |
| 490 | + assertEquals(featureFlags.isSupportsGetPartitionedMetadataWithoutAutoCreation(), supported); |
| 491 | + |
| 492 | + // cleanup. |
| 493 | + producer.close(); |
| 494 | + injectedClient.close(); |
| 495 | + admin.topics().delete(topic); |
| 496 | + } |
| 497 | + |
432 | 498 | private PulsarClient getClientActiveConsumerChangeNotSupported(ClientConfigurationData conf) |
433 | 499 | throws Exception { |
434 | 500 | ThreadFactory threadFactory = new DefaultThreadFactory("pulsar-client-io", Thread.currentThread().isDaemon()); |
|
0 commit comments