Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:

- name: Upload broker logs as artifacts
if: failure()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: broker_logs_${{ matrix.java }}
path: /tmp/bmq-broker/broker_logs.tar.gz
Expand Down
48 changes: 47 additions & 1 deletion bmq-sdk/src/main/java/com/bloomberg/bmq/SessionOptions.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Bloomberg Finance L.P.
* Copyright 2022-2025 Bloomberg Finance L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -62,6 +62,10 @@
* HostHealthMonitor} interface responsible for notifying the session when the health of the
* host machine has changed. A {@code hostHealthMonitor} must be specified in oder for queues
* opened through the session to suspend on unhealthy hosts.
* <li>{@code userAgentPrefix}: String to include in the user agent for broker telemetry. This
* string must only contain printable characters and must be less than 128 characters long.
* This is provided for libraries that are wrapping this SDK. Applications directly using the
* SDK are encouraged <strong>NOT</strong> to set this value.
* </ul>
*
* <H2>Thread Safety</H2>
Expand Down Expand Up @@ -215,6 +219,8 @@ public int highWaterMark() {

private final HostHealthMonitor hostHealthMonitor;

private final String userAgentPrefix;

private SessionOptions() {
brokerUri = DEFAULT_URI;
startTimeout = DEFAULT_START_TIMEOUT;
Expand All @@ -226,6 +232,7 @@ private SessionOptions() {
configureQueueTimeout = QUEUE_OPERATION_TIMEOUT;
closeQueueTimeout = QUEUE_OPERATION_TIMEOUT;
hostHealthMonitor = null;
userAgentPrefix = "";
}

private SessionOptions(Builder builder) {
Expand All @@ -239,6 +246,7 @@ private SessionOptions(Builder builder) {
configureQueueTimeout = builder.configureQueueTimeout;
closeQueueTimeout = builder.closeQueueTimeout;
hostHealthMonitor = builder.hostHealthMonitor;
userAgentPrefix = builder.userAgentPrefix;
}

/**
Expand Down Expand Up @@ -383,6 +391,16 @@ public HostHealthMonitor hostHealthMonitor() {
return hostHealthMonitor;
}

/**
* Returns the string that will be prefixed to the user agent used by {@link
* com.bloomberg.bmq.Session} to identify itself to the broker.
*
* @return String user agent string prefix
*/
public String userAgentPrefix() {
return userAgentPrefix;
}

/** Helper class to create a {@code SesssionOptions} object with custom settings. */
public static class Builder {
private URI brokerUri;
Expand All @@ -397,6 +415,9 @@ public static class Builder {
private Duration closeQueueTimeout;

private HostHealthMonitor hostHealthMonitor;

private String userAgentPrefix;

/**
* Creates a {@code SesssionOptions} object based on this {@code Builder} properties.
*
Expand All @@ -417,6 +438,7 @@ private Builder(SessionOptions options) {
configureQueueTimeout = options.configureQueueTimeout;
closeQueueTimeout = options.closeQueueTimeout;
hostHealthMonitor = options.hostHealthMonitor;
userAgentPrefix = options.userAgentPrefix;
}

/**
Expand Down Expand Up @@ -558,5 +580,29 @@ public Builder setHostHealthMonitor(HostHealthMonitor value) {
hostHealthMonitor = Argument.expectNonNull(value, "host health monitor");
return this;
}

/**
* Sets the user agent prefix. This string is prefixed to a user agent constructed by the
* SDK. This is intended ONLY for other libraries that wrap this SDK to identify themselves
* for broker telemetry. Applications that are directly using this SDK are encouraged not to
* set this.
*
* @param value String user agent prefix
* @return Builder this object
* @throws NullPointerException if the specified value is null
* @throws IllegalArgumentException in case the specified value contains non-ASCII
* characters, contains non-printable characters (i.e., control characters), or is
* longer than 127 characters.
*/
public Builder setUserAgentPrefix(String value) {
Argument.expectNonNull(value, "user agent prefix");
Argument.expectCondition(
value.codePoints().allMatch(c -> c < 128 && !Character.isISOControl(c)),
"user agent prefix must be printable ASCII");
Argument.expectCondition(
value.length() < 128, "user agent prefix must be shorter than 128 characters");
userAgentPrefix = value;
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Bloomberg Finance L.P.
* Copyright 2022-2025 Bloomberg Finance L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -373,9 +373,20 @@ private NegotiationMessageChoice createNegoMsg() {
clientIdentity.setClusterName("");
clientIdentity.setClusterNodeId(-1);
clientIdentity.setSdkLanguage(ClientLanguage.E_JAVA);
clientIdentity.setUserAgent(constructUserAgent());
return negoMsgChoice;
}

private String constructUserAgent() {
String prefix = "";
if (connectionOptions.userAgentPrefix().length() > 0) {
prefix = connectionOptions.userAgentPrefix() + " ";
}
String javaVersion = "java" + SystemUtil.getJavaVersionString();
String sdkVersion = VersionUtil.getJarVersion();
return prefix + "com.bloomberg.bmq(" + javaVersion + "):" + sdkVersion;
}

private WriteStatus negotiate() throws IOException {
if (negotiationMsg == null) {
negotiationMsg = createNegoMsg();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Bloomberg Finance L.P.
* Copyright 2022-2025 Bloomberg Finance L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,6 +27,7 @@ public class ClientIdentity {
private String clusterName;
private Integer clusterNodeId;
private ClientLanguage sdkLanguage;
private String userAgent;

public ClientIdentity() {
init();
Expand All @@ -48,6 +49,7 @@ private void init() {
clusterName = "";
clusterNodeId = -1;
sdkLanguage = ClientLanguage.E_UNKNOWN;
userAgent = "";
}

public Integer protocolVersion() {
Expand Down Expand Up @@ -138,6 +140,14 @@ public void setSdkLanguage(ClientLanguage value) {
sdkLanguage = value;
}

public String userAgent() {
return userAgent;
}

public void setUserAgent(String value) {
userAgent = value;
}

public Object createNewInstance() {
return new ClientIdentity();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Bloomberg Finance L.P.
* Copyright 2022-2025 Bloomberg Finance L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -39,12 +39,14 @@ public final class ConnectionOptions {
private int startNumRetries = DEFAULT_START_NUM_RETRIES;
private Duration startRetryInterval = DEFAULT_START_RETRY_INTERVAL;
private WriteBufferWaterMark writeWaterMark = new WriteBufferWaterMark();
private String userAgentPrefix = "";

public ConnectionOptions() {}

public ConnectionOptions(SessionOptions sesOpts) {
brokerUri = sesOpts.brokerUri();
writeWaterMark = sesOpts.writeBufferWaterMark();
userAgentPrefix = sesOpts.userAgentPrefix();
}

public ConnectionOptions setBrokerUri(URI value) {
Expand Down Expand Up @@ -80,6 +82,17 @@ public ConnectionOptions setWriteBufferWaterMark(WriteBufferWaterMark value) {
return this;
}

public ConnectionOptions setUserAgentPrefix(String value) {
Argument.expectNonNull(value, "user agent prefix");
Argument.expectCondition(
value.codePoints().allMatch(c -> c < 128 && !Character.isISOControl(c)),
"user agent prefix must be printable ASCII");
Argument.expectCondition(
value.length() < 128, "user agent prefix must be shorter than 128 characters");
userAgentPrefix = value;
return this;
}

public URI brokerUri() {
return brokerUri;
}
Expand All @@ -99,4 +112,8 @@ public Duration startRetryInterval() {
public WriteBufferWaterMark writeBufferWaterMark() {
return writeWaterMark;
}

public String userAgentPrefix() {
return userAgentPrefix;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Bloomberg Finance L.P.
* Copyright 2022-2025 Bloomberg Finance L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -48,7 +48,7 @@ public static JavaVersion getJavaVersion() {
JavaVersion result = JavaVersion.JAVA_UNSUPPORTED;

try {
String version = System.getProperty("java.version");
String version = getJavaVersionString();

result =
Arrays.stream(JavaVersion.values())
Expand All @@ -63,6 +63,10 @@ public static JavaVersion getJavaVersion() {
return result;
}

public static String getJavaVersionString() {
return System.getProperty("java.version");
}

public static int getProcessId() {
int pid = 0;
String vmname = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Bloomberg Finance L.P.
* Copyright 2022-2025 Bloomberg Finance L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Bloomberg Finance L.P.
* Copyright 2022-2025 Bloomberg Finance L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Bloomberg Finance L.P.
* Copyright 2022-2025 Bloomberg Finance L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -115,6 +115,7 @@ public static ByteBuffer[] getLastMessage(int port, Uri uri)
clientIdentity.setClusterName("");
clientIdentity.setClusterNodeId(-1);
clientIdentity.setSdkLanguage(ClientLanguage.E_JAVA);
clientIdentity.setUserAgent("com.bloomberg.bmq.it.PlainConsumerIT");

SchemaEventBuilder schemaBuilder = new SchemaEventBuilder();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Bloomberg Finance L.P.
* Copyright 2022-2025 Bloomberg Finance L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -117,6 +117,7 @@ public static void sendMessage(
clientIdentity.setClusterName("");
clientIdentity.setClusterNodeId(-1);
clientIdentity.setSdkLanguage(ClientLanguage.E_JAVA);
clientIdentity.setUserAgent("com.bloomberg.bmq.it.PlainProducerIT");

SchemaEventBuilder schemaBuilder = new SchemaEventBuilder();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ public static void compareWithFileContent(
v1 = in1.read();
v2 = in2.read();
assertTrue(v1 >= 0);
assertEquals(v1, v2);
assertEquals(
v1,
v2,
"Found mismatch at byte " + i + ": " + (char) v1 + ", " + (char) v2);
}
}
}
Expand Down
Binary file not shown.
Loading