diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClientConstants.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClientConstants.java index b49ac3bb93ca..cfce200c7362 100644 --- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClientConstants.java +++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClientConstants.java @@ -5,10 +5,6 @@ public final class ClientConstants { public static final String NOT_APPLICABLE = "n/a"; - public static final String PRODUCT_NAME = "azsdk-java-eventhubs"; - // {x-version-update-start;com.azure:azure-messaging-eventhubs;current} - public static final String CURRENT_JAVA_CLIENT_VERSION = "5.0.0-beta.7"; - // {x-version-update-end} public static final String PLATFORM_INFO = getOSInformation(); public static final String FRAMEWORK_INFO = getFrameworkInfo(); @@ -17,8 +13,8 @@ public final class ClientConstants { * $/core/azure-core/src/main/java/com/azure/core/http/policy/UserAgentPolicy.java * TODO (conniey): Extract logic from UserAgentPolicy into something we can use here. */ - public static final String USER_AGENT = String.format("%s/%s %s;%s", - PRODUCT_NAME, CURRENT_JAVA_CLIENT_VERSION, System.getProperty("java.version"), PLATFORM_INFO); + public static final String USER_AGENT_TEMPLATE = + "%s/%s " + System.getProperty("java.version") + ";" + PLATFORM_INFO; /** * The default maximum allowable size, in bytes, for a batch to be sent. diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java index 6a6393482a9d..9e895e62ebe8 100644 --- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java +++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java @@ -72,10 +72,13 @@ public class ReactorConnection implements AmqpConnection { * @param reactorProvider Provides proton-j Reactor instances. * @param handlerProvider Provides {@link BaseHandler} to listen to proton-j reactor events. * @param tokenManagerProvider Provides the appropriate token manager to authorize with CBS node. + * @param messageSerializer Serializer to translate objects to and from proton-j {@link Message messages}. + * @param product The name of the product this connection is created for. + * @param clientVersion The version of the client library creating the connection. */ public ReactorConnection(String connectionId, ConnectionOptions connectionOptions, ReactorProvider reactorProvider, ReactorHandlerProvider handlerProvider, TokenManagerProvider tokenManagerProvider, - MessageSerializer messageSerializer) { + MessageSerializer messageSerializer, String product, String clientVersion) { this.connectionOptions = connectionOptions; this.reactorProvider = reactorProvider; @@ -86,7 +89,7 @@ public ReactorConnection(String connectionId, ConnectionOptions connectionOption this.messageSerializer = messageSerializer; this.handler = handlerProvider.createConnectionHandler(connectionId, connectionOptions.getFullyQualifiedNamespace(), connectionOptions.getTransportType(), - connectionOptions.getProxyOptions()); + connectionOptions.getProxyOptions(), product, clientVersion); this.retryPolicy = RetryUtil.getRetryPolicy(connectionOptions.getRetry()); this.connectionMono = Mono.fromCallable(this::getOrCreateConnection) diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorHandlerProvider.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorHandlerProvider.java index 1ebce066d2dd..408d3f40de94 100644 --- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorHandlerProvider.java +++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorHandlerProvider.java @@ -40,22 +40,26 @@ public ReactorHandlerProvider(ReactorProvider provider) { * @param connectionId Identifier associated with this connection. * @param hostname Host for the connection handler. * @param transportType Transport type used for the connection. + * @param proxyOptions The options to use for proxy. + * @param product The name of the product this connection handler is created for. + * @param clientVersion The version of the client library creating the connection handler. * @return A new {@link ConnectionHandler}. */ public ConnectionHandler createConnectionHandler(String connectionId, String hostname, - AmqpTransportType transportType, ProxyOptions proxyOptions) { + AmqpTransportType transportType, ProxyOptions proxyOptions, String product, String clientVersion) { switch (transportType) { case AMQP: - return new ConnectionHandler(connectionId, hostname); + return new ConnectionHandler(connectionId, hostname, product, clientVersion); case AMQP_WEB_SOCKETS: if (proxyOptions != null && proxyOptions.isProxyAddressConfigured()) { - return new WebSocketsProxyConnectionHandler(connectionId, hostname, proxyOptions); + return new WebSocketsProxyConnectionHandler(connectionId, hostname, proxyOptions, product, + clientVersion); } else if (WebSocketsProxyConnectionHandler.shouldUseProxy(hostname)) { logger.info("System default proxy configured for hostname '{}'. Using proxy.", hostname); return new WebSocketsProxyConnectionHandler(connectionId, hostname, - ProxyOptions.SYSTEM_DEFAULTS); + ProxyOptions.SYSTEM_DEFAULTS, product, clientVersion); } else { - return new WebSocketsConnectionHandler(connectionId, hostname); + return new WebSocketsConnectionHandler(connectionId, hostname, product, clientVersion); } default: throw logger.logExceptionAsWarning(new IllegalArgumentException(String.format(Locale.US, diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/ConnectionHandler.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/ConnectionHandler.java index 1a24abcecc0f..4ee59700008f 100644 --- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/ConnectionHandler.java +++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/ConnectionHandler.java @@ -36,41 +36,31 @@ public class ConnectionHandler extends Handler { static final int MAX_FRAME_SIZE = 65536; private final Map connectionProperties; - protected final ClientLogger logger; + private final ClientLogger logger = new ClientLogger(ConnectionHandler.class); /** * Creates a handler that handles proton-j's connection events. * * @param connectionId Identifier for this connection. * @param hostname Hostname of the AMQP message broker to create a connection to. + * @param product The name of the product this connection handler is created for. + * @param clientVersion The version of the client library creating the connection handler. */ - public ConnectionHandler(final String connectionId, final String hostname) { - this(connectionId, hostname, new ClientLogger(ConnectionHandler.class)); - } - - /** - * Creates a handler that handles proton-j's connection events. - * - * @param connectionId Identifier for this connection. - * @param hostname Hostname to use for socket creation. If there is a proxy configured, this could be a proxy's - * IP address. - * @param logger The service logger to use. - */ - protected ConnectionHandler(final String connectionId, final String hostname, final ClientLogger logger) { + public ConnectionHandler(final String connectionId, final String hostname, String product, String clientVersion) { super(connectionId, hostname); add(new Handshaker()); - this.logger = logger; this.connectionProperties = new HashMap<>(); - this.connectionProperties.put(PRODUCT.toString(), ClientConstants.PRODUCT_NAME); - this.connectionProperties.put(VERSION.toString(), ClientConstants.CURRENT_JAVA_CLIENT_VERSION); + this.connectionProperties.put(PRODUCT.toString(), product); + this.connectionProperties.put(VERSION.toString(), clientVersion); this.connectionProperties.put(PLATFORM.toString(), ClientConstants.PLATFORM_INFO); this.connectionProperties.put(FRAMEWORK.toString(), ClientConstants.FRAMEWORK_INFO); + String userAgent = String.format(ClientConstants.USER_AGENT_TEMPLATE, product, clientVersion); - final String userAgent = ClientConstants.USER_AGENT.length() <= MAX_USER_AGENT_LENGTH - ? ClientConstants.USER_AGENT - : ClientConstants.USER_AGENT.substring(0, MAX_USER_AGENT_LENGTH); + userAgent = userAgent.length() <= MAX_USER_AGENT_LENGTH + ? userAgent + : userAgent.substring(0, MAX_USER_AGENT_LENGTH); this.connectionProperties.put(USER_AGENT.toString(), userAgent); } diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/WebSocketsConnectionHandler.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/WebSocketsConnectionHandler.java index a2bbef6b297a..965d37862891 100644 --- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/WebSocketsConnectionHandler.java +++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/WebSocketsConnectionHandler.java @@ -20,15 +20,19 @@ public class WebSocketsConnectionHandler extends ConnectionHandler { private static final String SOCKET_PATH = "/$servicebus/websocket"; private static final String PROTOCOL = "AMQPWSB10"; + private final ClientLogger logger = new ClientLogger(WebSocketsConnectionHandler.class); /** * Creates a handler that handles proton-j's connection events using web sockets. * * @param connectionId Identifier for this connection. * @param hostname Hostname to use for socket creation. + * @param product The name of the product this connection handler is created for. + * @param clientVersion The version of the client library creating the connection handler. */ - public WebSocketsConnectionHandler(final String connectionId, final String hostname) { - super(connectionId, hostname, new ClientLogger(WebSocketsConnectionHandler.class)); + public WebSocketsConnectionHandler(final String connectionId, final String hostname, final String product, + final String clientVersion) { + super(connectionId, hostname, product, clientVersion); } @Override diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/WebSocketsProxyConnectionHandler.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/WebSocketsProxyConnectionHandler.java index 40f37c390138..f649e4413e1e 100644 --- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/WebSocketsProxyConnectionHandler.java +++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/handler/WebSocketsProxyConnectionHandler.java @@ -48,11 +48,14 @@ public class WebSocketsProxyConnectionHandler extends WebSocketsConnectionHandle * @param connectionId Identifier for this connection. * @param amqpHostname Hostname of the AMQP message broker. The hostname of the proxy is exposed in {@link * #getHostname()}. + * @param proxyOptions The options to use for proxy. + * @param product The name of the product this connection handler is created for. + * @param clientVersion The version of the client library creating the connection handler. * @throws NullPointerException if {@code amqpHostname} or {@code proxyConfiguration} is null. */ public WebSocketsProxyConnectionHandler(String connectionId, String amqpHostname, - ProxyOptions proxyOptions) { - super(connectionId, amqpHostname); + ProxyOptions proxyOptions, String product, String clientVersion) { + super(connectionId, amqpHostname, product, clientVersion); this.amqpHostname = Objects.requireNonNull(amqpHostname, "'amqpHostname' cannot be null."); this.proxyOptions = Objects.requireNonNull(proxyOptions, "'proxyConfiguration' cannot be null."); this.remoteHost = amqpHostname + ":" + HTTPS_PORT; diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/MockReactorHandlerProvider.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/MockReactorHandlerProvider.java index 5bf0eb3e6b48..a496c3603b30 100644 --- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/MockReactorHandlerProvider.java +++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/MockReactorHandlerProvider.java @@ -33,8 +33,9 @@ public SessionHandler createSessionHandler(String connectionId, String hostname, } @Override - public ConnectionHandler createConnectionHandler(String connectionId, String hostname, AmqpTransportType transportType, - ProxyOptions configuration) { + public ConnectionHandler createConnectionHandler(String connectionId, String hostname, + AmqpTransportType transportType, ProxyOptions configuration, String product, String clientVersion) { + return connectionHandler; } diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java index 318ea204fbe1..c7920087df3d 100644 --- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java +++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java @@ -53,6 +53,8 @@ public class ReactorConnectionTest { private static final ConnectionStringProperties CREDENTIAL_INFO = new ConnectionStringProperties("Endpoint=sb://test-event-hub.servicebus.windows.net/;SharedAccessKeyName=dummySharedKeyName;SharedAccessKey=dummySharedKeyValue;EntityPath=eventhub1;"); private static final String HOSTNAME = CREDENTIAL_INFO.getEndpoint().getHost(); private static final Scheduler SCHEDULER = Schedulers.elastic(); + private static final String PRODUCT = "test"; + private static final String CLIENT_VERSION = "1.0.0-test"; private ReactorConnection connection; private SessionHandler sessionHandler; @@ -83,7 +85,7 @@ public void setup() throws IOException { when(reactor.selectable()).thenReturn(selectable); - connectionHandler = new ConnectionHandler(CONNECTION_ID, HOSTNAME); + connectionHandler = new ConnectionHandler(CONNECTION_ID, HOSTNAME, PRODUCT, CLIENT_VERSION); final ReactorDispatcher reactorDispatcher = new ReactorDispatcher(reactor); when(reactorProvider.getReactor()).thenReturn(reactor); @@ -99,7 +101,7 @@ public void setup() throws IOException { CREDENTIAL_INFO.getEntityPath(), tokenProvider, CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP, retryOptions, ProxyOptions.SYSTEM_DEFAULTS, SCHEDULER); connection = new ReactorConnection(CONNECTION_ID, connectionOptions, reactorProvider, reactorHandlerProvider, - tokenManager, messageSerializer); + tokenManager, messageSerializer, PRODUCT, CLIENT_VERSION); } @AfterEach @@ -274,7 +276,7 @@ public void createCBSNode() { @Test public void createCBSNodeTimeoutException() { // Arrange - final ConnectionHandler handler = new ConnectionHandler(CONNECTION_ID, HOSTNAME); + final ConnectionHandler handler = new ConnectionHandler(CONNECTION_ID, HOSTNAME, PRODUCT, CLIENT_VERSION); final ReactorHandlerProvider provider = new MockReactorHandlerProvider(reactorProvider, handler, sessionHandler, null, null); @@ -290,7 +292,7 @@ public void createCBSNodeTimeoutException() { // Act and Assert try (ReactorConnection connectionBad = new ReactorConnection(CONNECTION_ID, parameters, reactorProvider, - provider, tokenManager, messageSerializer)) { + provider, tokenManager, messageSerializer, PRODUCT, CLIENT_VERSION)) { StepVerifier.create(connectionBad.getClaimsBasedSecurityNode()) .verifyError(TimeoutException.class); } diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorHandlerProviderTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorHandlerProviderTest.java index 71ec9f417833..d02798a0e3e6 100644 --- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorHandlerProviderTest.java +++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorHandlerProviderTest.java @@ -42,6 +42,8 @@ public class ReactorHandlerProviderTest { private static final Proxy PROXY = new Proxy(Proxy.Type.HTTP, PROXY_ADDRESS); private static final String USERNAME = "test-user"; private static final String PASSWORD = "test-password"; + private static final String PRODUCT = "test"; + private static final String CLIENT_VERSION = "1.0.0-test"; @Mock private Reactor reactor; @@ -84,7 +86,8 @@ public void teardown() { @Test public void getsConnectionHandlerAMQP() { // Act - final ConnectionHandler handler = provider.createConnectionHandler(CONNECTION_ID, HOSTNAME, AmqpTransportType.AMQP, null); + final ConnectionHandler handler = provider.createConnectionHandler(CONNECTION_ID, HOSTNAME, + AmqpTransportType.AMQP, null, PRODUCT, CLIENT_VERSION); // Assert Assertions.assertNotNull(handler); @@ -99,7 +102,7 @@ public void getsConnectionHandlerAMQP() { public void getsConnectionHandlerWebSockets(ProxyOptions configuration) { // Act final ConnectionHandler handler = provider.createConnectionHandler(CONNECTION_ID, HOSTNAME, - AmqpTransportType.AMQP_WEB_SOCKETS, configuration); + AmqpTransportType.AMQP_WEB_SOCKETS, configuration, PRODUCT, CLIENT_VERSION); // Assert Assertions.assertNotNull(handler); @@ -120,7 +123,7 @@ public void getsConnectionHandlerProxy() { // Act final ConnectionHandler handler = provider.createConnectionHandler(CONNECTION_ID, hostname, - AmqpTransportType.AMQP_WEB_SOCKETS, configuration); + AmqpTransportType.AMQP_WEB_SOCKETS, configuration, PRODUCT, CLIENT_VERSION); // Assert Assertions.assertNotNull(handler); @@ -144,7 +147,7 @@ public void noProxySelected(ProxyOptions configuration) { // Act final ConnectionHandler handler = provider.createConnectionHandler(CONNECTION_ID, hostname, - AmqpTransportType.AMQP_WEB_SOCKETS, configuration); + AmqpTransportType.AMQP_WEB_SOCKETS, configuration, PRODUCT, CLIENT_VERSION); // Act and Assert Assertions.assertEquals(PROXY_ADDRESS.getHostName(), handler.getHostname()); diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/ConnectionHandlerTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/ConnectionHandlerTest.java index 8313917799ef..a23b94a85488 100644 --- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/ConnectionHandlerTest.java +++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/ConnectionHandlerTest.java @@ -26,9 +26,7 @@ import static com.azure.core.amqp.implementation.handler.ConnectionHandler.FRAMEWORK; import static com.azure.core.amqp.implementation.handler.ConnectionHandler.MAX_FRAME_SIZE; import static com.azure.core.amqp.implementation.handler.ConnectionHandler.PLATFORM; -import static com.azure.core.amqp.implementation.handler.ConnectionHandler.PRODUCT; import static com.azure.core.amqp.implementation.handler.ConnectionHandler.USER_AGENT; -import static com.azure.core.amqp.implementation.handler.ConnectionHandler.VERSION; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -39,6 +37,8 @@ public class ConnectionHandlerTest { private static final String CONNECTION_ID = "some-random-id"; private static final String HOSTNAME = "hostname-random"; private ConnectionHandler handler; + private static final String PRODUCT = "test"; + private static final String CLIENT_VERSION = "1.0.0-test"; @Captor private ArgumentCaptor> argumentCaptor; @@ -46,7 +46,7 @@ public class ConnectionHandlerTest { @BeforeEach public void setup() { MockitoAnnotations.initMocks(this); - handler = new ConnectionHandler(CONNECTION_ID, HOSTNAME); + handler = new ConnectionHandler(CONNECTION_ID, HOSTNAME, PRODUCT, CLIENT_VERSION); } @AfterEach @@ -59,8 +59,6 @@ public void teardown() { public void createHandler() { // Arrange final Map expected = new HashMap<>(); - expected.put(PRODUCT.toString(), ClientConstants.PRODUCT_NAME); - expected.put(VERSION.toString(), ClientConstants.CURRENT_JAVA_CLIENT_VERSION); expected.put(PLATFORM.toString(), ClientConstants.PLATFORM_INFO); expected.put(FRAMEWORK.toString(), ClientConstants.FRAMEWORK_INFO); diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/WebSocketsConnectionHandlerTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/WebSocketsConnectionHandlerTest.java index 519b5cb57a19..e53151d18a1b 100644 --- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/WebSocketsConnectionHandlerTest.java +++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/WebSocketsConnectionHandlerTest.java @@ -24,8 +24,6 @@ import static com.azure.core.amqp.implementation.handler.ConnectionHandler.FRAMEWORK; import static com.azure.core.amqp.implementation.handler.ConnectionHandler.PLATFORM; -import static com.azure.core.amqp.implementation.handler.ConnectionHandler.PRODUCT; -import static com.azure.core.amqp.implementation.handler.ConnectionHandler.VERSION; import static com.azure.core.amqp.implementation.handler.WebSocketsConnectionHandler.HTTPS_PORT; import static com.azure.core.amqp.implementation.handler.WebSocketsConnectionHandler.MAX_FRAME_SIZE; import static org.mockito.ArgumentMatchers.any; @@ -39,13 +37,16 @@ public class WebSocketsConnectionHandlerTest { private static final String HOSTNAME = "hostname-random"; private WebSocketsConnectionHandler handler; + private static final String PRODUCT = "test"; + private static final String CLIENT_VERSION = "1.0.0-test"; + @Captor ArgumentCaptor> argumentCaptor; @BeforeEach public void setup() { MockitoAnnotations.initMocks(this); - handler = new WebSocketsConnectionHandler(CONNECTION_ID, HOSTNAME); + handler = new WebSocketsConnectionHandler(CONNECTION_ID, HOSTNAME, PRODUCT, CLIENT_VERSION); } @AfterEach @@ -58,8 +59,6 @@ public void teardown() { public void createHandler() { // Arrange final Map expected = new HashMap<>(); - expected.put(PRODUCT.toString(), ClientConstants.PRODUCT_NAME); - expected.put(VERSION.toString(), ClientConstants.CURRENT_JAVA_CLIENT_VERSION); expected.put(PLATFORM.toString(), ClientConstants.PLATFORM_INFO); expected.put(FRAMEWORK.toString(), ClientConstants.FRAMEWORK_INFO); diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/WebSocketsProxyConnectionHandlerTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/WebSocketsProxyConnectionHandlerTest.java index 6544f9a3aa73..23a4fd102b85 100644 --- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/WebSocketsProxyConnectionHandlerTest.java +++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/handler/WebSocketsProxyConnectionHandlerTest.java @@ -34,6 +34,8 @@ public class WebSocketsProxyConnectionHandlerTest { private static final String PASSWORD = "test-password"; private static final ProxyOptions PROXY_CONFIGURATION = new ProxyOptions(ProxyAuthenticationType.DIGEST, PROXY, USERNAME, PASSWORD); + private static final String PRODUCT = "test"; + private static final String CLIENT_VERSION = "1.0.0-test"; private ProxySelector originalProxySelector; private ProxySelector proxySelector; @@ -56,12 +58,14 @@ public void teardown() { @Test public void nullProxyConfiguration() { - assertThrows(NullPointerException.class, () -> new WebSocketsProxyConnectionHandler(CONNECTION_ID, HOSTNAME, null)); + assertThrows(NullPointerException.class, () -> new WebSocketsProxyConnectionHandler(CONNECTION_ID, HOSTNAME, + null, PRODUCT, CLIENT_VERSION)); } @Test public void nullHostname() { - assertThrows(NullPointerException.class, () -> new WebSocketsProxyConnectionHandler(CONNECTION_ID, null, PROXY_CONFIGURATION)); + assertThrows(NullPointerException.class, () -> new WebSocketsProxyConnectionHandler(CONNECTION_ID, null, + PROXY_CONFIGURATION, PRODUCT, CLIENT_VERSION)); } /** @@ -74,7 +78,7 @@ public void noProxySelected() { .thenReturn(Collections.singletonList(PROXY)); final WebSocketsProxyConnectionHandler handler = new WebSocketsProxyConnectionHandler(CONNECTION_ID, HOSTNAME, - PROXY_CONFIGURATION); + PROXY_CONFIGURATION, PRODUCT, CLIENT_VERSION); // Act and Assert Assertions.assertEquals(PROXY_ADDRESS.getHostName(), handler.getHostname()); @@ -91,7 +95,7 @@ public void systemProxyConfigurationSelected() { .thenReturn(Collections.singletonList(PROXY)); final WebSocketsProxyConnectionHandler handler = new WebSocketsProxyConnectionHandler(CONNECTION_ID, HOSTNAME, - ProxyOptions.SYSTEM_DEFAULTS); + ProxyOptions.SYSTEM_DEFAULTS, PRODUCT, CLIENT_VERSION); // Act and Assert Assertions.assertEquals(PROXY_ADDRESS.getHostName(), handler.getHostname()); @@ -114,7 +118,8 @@ public void proxyConfigurationSelected() { when(proxySelector.select(any())).thenReturn(Collections.singletonList(PROXY)); - final WebSocketsProxyConnectionHandler handler = new WebSocketsProxyConnectionHandler(CONNECTION_ID, host, configuration); + final WebSocketsProxyConnectionHandler handler = new WebSocketsProxyConnectionHandler(CONNECTION_ID, host, + configuration, PRODUCT, CLIENT_VERSION); // Act and Assert Assertions.assertEquals(address.getHostName(), handler.getHostname()); diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubClientBuilder.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubClientBuilder.java index ac1d1366f5e2..6d87554add01 100644 --- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubClientBuilder.java +++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubClientBuilder.java @@ -28,6 +28,7 @@ import com.azure.messaging.eventhubs.implementation.EventHubAmqpConnection; import com.azure.messaging.eventhubs.implementation.EventHubReactorAmqpConnection; import com.azure.messaging.eventhubs.implementation.EventHubSharedKeyCredential; +import java.util.Map; import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; import reactor.core.scheduler.Schedulers; @@ -104,6 +105,10 @@ public class EventHubClientBuilder { // Default number of events to fetch when creating the consumer. static final int DEFAULT_PREFETCH_COUNT = 500; + private static final String EVENTHUBS_PROPERTIES_FILE = "azure-messaging-eventhubs.properties"; + private static final String NAME_KEY = "name"; + private static final String VERSION_KEY = "version"; + private static final String UNKNOWN = "UNKNOWN"; private final ClientLogger logger = new ClientLogger(EventHubClientBuilder.class); @@ -511,11 +516,14 @@ private EventHubConnection buildConnection(MessageSerializer messageSerializer) final ReactorProvider provider = new ReactorProvider(); final ReactorHandlerProvider handlerProvider = new ReactorHandlerProvider(provider); + Map properties = CoreUtils.getProperties(EVENTHUBS_PROPERTIES_FILE); + String product = properties.getOrDefault(NAME_KEY, UNKNOWN); + String clientVersion = properties.getOrDefault(VERSION_KEY, UNKNOWN); + final Mono connectionMono = Mono.fromCallable(() -> { final String connectionId = StringUtil.getRandomString("MF"); - return new EventHubReactorAmqpConnection(connectionId, connectionOptions, provider, handlerProvider, - tokenManagerProvider, messageSerializer); + tokenManagerProvider, messageSerializer, product, clientVersion); }); return new EventHubConnection(connectionMono, connectionOptions); diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubReactorAmqpConnection.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubReactorAmqpConnection.java index 10cafdd474a6..f02043178245 100644 --- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubReactorAmqpConnection.java +++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubReactorAmqpConnection.java @@ -42,10 +42,12 @@ public class EventHubReactorAmqpConnection extends ReactorConnection implements * @param messageSerializer Serializes and deserializes proton-j messages. */ public EventHubReactorAmqpConnection(String connectionId, ConnectionOptions connectionOptions, - ReactorProvider reactorProvider, ReactorHandlerProvider handlerProvider, - TokenManagerProvider tokenManagerProvider, MessageSerializer messageSerializer) { + ReactorProvider reactorProvider, ReactorHandlerProvider handlerProvider, + TokenManagerProvider tokenManagerProvider, MessageSerializer messageSerializer, + String product, String clientVersion) { + super(connectionId, connectionOptions, reactorProvider, handlerProvider, tokenManagerProvider, - messageSerializer); + messageSerializer, product, clientVersion); this.reactorProvider = reactorProvider; this.handlerProvider = handlerProvider; this.tokenManagerProvider = tokenManagerProvider; diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/resources/azure-messaging-eventhubs.properties b/sdk/eventhubs/azure-messaging-eventhubs/src/main/resources/azure-messaging-eventhubs.properties new file mode 100644 index 000000000000..ca812989b4f2 --- /dev/null +++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/resources/azure-messaging-eventhubs.properties @@ -0,0 +1,2 @@ +name=${project.artifactId} +version=${project.version} diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/CBSChannelTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/CBSChannelTest.java index 3a6b4bb3aa93..51458dbec9ae 100644 --- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/CBSChannelTest.java +++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/CBSChannelTest.java @@ -23,7 +23,9 @@ import com.azure.core.util.CoreUtils; import com.azure.core.util.logging.ClientLogger; import com.azure.messaging.eventhubs.IntegrationTestBase; +import java.util.Map; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -45,11 +47,20 @@ public class CBSChannelTest extends IntegrationTestBase { private AzureTokenManagerProvider azureTokenManagerProvider; @Mock private MessageSerializer messageSerializer; + private static String product; + private static String clientVersion; public CBSChannelTest() { super(new ClientLogger(CBSChannelTest.class)); } + @BeforeAll + public static void init() { + Map properties = CoreUtils.getProperties("azure-messaging-eventhubs.properties"); + product = properties.get("name"); + clientVersion = properties.get("version"); + } + @Override protected void beforeTest() { MockitoAnnotations.initMocks(this); @@ -69,7 +80,7 @@ protected void beforeTest() { ReactorProvider reactorProvider = new ReactorProvider(); ReactorHandlerProvider handlerProvider = new ReactorHandlerProvider(reactorProvider); connection = new TestReactorConnection(CONNECTION_ID, connectionOptions, reactorProvider, handlerProvider, - azureTokenManagerProvider, messageSerializer); + azureTokenManagerProvider, messageSerializer, product, clientVersion); final Mono requestResponseChannel = connection.getCBSChannel(); @@ -126,11 +137,13 @@ public void unsuccessfulAuthorize() { } private static final class TestReactorConnection extends ReactorConnection { + private TestReactorConnection(String connectionId, ConnectionOptions connectionOptions, - ReactorProvider reactorProvider, ReactorHandlerProvider handlerProvider, - TokenManagerProvider tokenManagerProvider, MessageSerializer messageSerializer) { + ReactorProvider reactorProvider, ReactorHandlerProvider handlerProvider, + TokenManagerProvider tokenManagerProvider, MessageSerializer messageSerializer, + String product, String clientVersion) { super(connectionId, connectionOptions, reactorProvider, handlerProvider, tokenManagerProvider, - messageSerializer); + messageSerializer, product, clientVersion); } private Mono getCBSChannel() { diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/EventHubReactorConnectionTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/EventHubReactorConnectionTest.java index 485612210e05..bc483e58368a 100644 --- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/EventHubReactorConnectionTest.java +++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/EventHubReactorConnectionTest.java @@ -15,11 +15,14 @@ import com.azure.core.amqp.implementation.TokenManagerProvider; import com.azure.core.amqp.implementation.handler.ConnectionHandler; import com.azure.core.credential.TokenCredential; +import com.azure.core.util.CoreUtils; +import java.util.Map; import org.apache.qpid.proton.engine.Connection; import org.apache.qpid.proton.reactor.Reactor; import org.apache.qpid.proton.reactor.Selectable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; @@ -55,10 +58,20 @@ public class EventHubReactorConnectionTest { @Mock private ReactorHandlerProvider handlerProvider; private ConnectionOptions connectionOptions; + private static String product; + private static String clientVersion; + + @BeforeAll + public static void init() throws Exception { + Map properties = CoreUtils.getProperties("azure-messaging-eventhubs.properties"); + product = properties.get("name"); + clientVersion = properties.get("version"); + } @BeforeEach public void setup() throws IOException { - final ConnectionHandler connectionHandler = new ConnectionHandler(CONNECTION_ID, HOSTNAME); + final ConnectionHandler connectionHandler = new ConnectionHandler(CONNECTION_ID, HOSTNAME, product, + clientVersion); MockitoAnnotations.initMocks(this); @@ -78,15 +91,17 @@ tokenCredential, CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType when(reactorProvider.createReactor(connectionHandler.getConnectionId(), connectionHandler.getMaxFrameSize())) .thenReturn(reactor); - when(handlerProvider.createConnectionHandler(CONNECTION_ID, HOSTNAME, AmqpTransportType.AMQP, proxy)) + when(handlerProvider.createConnectionHandler(CONNECTION_ID, HOSTNAME, AmqpTransportType.AMQP, proxy, product, + clientVersion)) .thenReturn(connectionHandler); } @Test public void getsManagementChannel() { // Arrange - final EventHubReactorAmqpConnection connection = new EventHubReactorAmqpConnection(CONNECTION_ID, connectionOptions, - reactorProvider, handlerProvider, tokenManagerProvider, messageSerializer); + final EventHubReactorAmqpConnection connection = new EventHubReactorAmqpConnection(CONNECTION_ID, + connectionOptions, reactorProvider, handlerProvider, tokenManagerProvider, messageSerializer, product, + clientVersion); // Act & Assert StepVerifier.create(connection.getManagementNode()) diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/ReactorConnectionIntegrationTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/ReactorConnectionIntegrationTest.java index 9e38bdc0a5d1..8bf2c6c384ca 100644 --- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/ReactorConnectionIntegrationTest.java +++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/ReactorConnectionIntegrationTest.java @@ -15,9 +15,12 @@ import com.azure.core.amqp.implementation.ReactorHandlerProvider; import com.azure.core.amqp.implementation.ReactorProvider; import com.azure.core.credential.TokenCredential; +import com.azure.core.util.CoreUtils; import com.azure.core.util.logging.ClientLogger; import com.azure.messaging.eventhubs.IntegrationTestBase; +import java.util.Map; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -35,11 +38,20 @@ public class ReactorConnectionIntegrationTest extends IntegrationTestBase { @Mock private MessageSerializer serializer; + private static String product; + private static String clientVersion; public ReactorConnectionIntegrationTest() { super(new ClientLogger(ReactorConnectionIntegrationTest.class)); } + @BeforeAll + public static void init() { + Map properties = CoreUtils.getProperties("azure-messaging-eventhubs.properties"); + product = properties.get("name"); + clientVersion = properties.get("version"); + } + @Override protected void beforeTest() { MockitoAnnotations.initMocks(this); @@ -58,7 +70,7 @@ protected void beforeTest() { ReactorProvider reactorProvider = new ReactorProvider(); ReactorHandlerProvider handlerProvider = new ReactorHandlerProvider(reactorProvider); connection = new ReactorConnection("test-connection-id", options, reactorProvider, - handlerProvider, tokenManagerProvider, serializer); + handlerProvider, tokenManagerProvider, serializer, product, clientVersion); } @Override