Skip to content

Commit

Permalink
Move version and product name from amqp to event hubs library (#7092)
Browse files Browse the repository at this point in the history
* Move version and product name from amqp to event hubs library

* Update AMQP library pass user agent info from client library

* Fix checkstyle
  • Loading branch information
srnagar authored Jan 3, 2020
1 parent 918103c commit ef05815
Show file tree
Hide file tree
Showing 18 changed files with 136 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,41 +36,31 @@ public class ConnectionHandler extends Handler {
static final int MAX_FRAME_SIZE = 65536;

private final Map<String, Object> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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);

Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -39,14 +37,16 @@ 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<Map<Symbol, Object>> argumentCaptor;

@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
handler = new ConnectionHandler(CONNECTION_ID, HOSTNAME);
handler = new ConnectionHandler(CONNECTION_ID, HOSTNAME, PRODUCT, CLIENT_VERSION);
}

@AfterEach
Expand All @@ -59,8 +59,6 @@ public void teardown() {
public void createHandler() {
// Arrange
final Map<String, String> 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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<Map<Symbol, Object>> argumentCaptor;

@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
handler = new WebSocketsConnectionHandler(CONNECTION_ID, HOSTNAME);
handler = new WebSocketsConnectionHandler(CONNECTION_ID, HOSTNAME, PRODUCT, CLIENT_VERSION);
}

@AfterEach
Expand All @@ -58,8 +59,6 @@ public void teardown() {
public void createHandler() {
// Arrange
final Map<String, String> 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);

Expand Down
Loading

0 comments on commit ef05815

Please sign in to comment.