diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/SessionOptions.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/SessionOptions.java index bdb8c8e4..48019843 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/SessionOptions.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/SessionOptions.java @@ -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. @@ -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. + *
  • {@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 NOT to set this value. * * *

    Thread Safety

    @@ -215,6 +219,8 @@ public int highWaterMark() { private final HostHealthMonitor hostHealthMonitor; + private final String userAgentPrefix; + private SessionOptions() { brokerUri = DEFAULT_URI; startTimeout = DEFAULT_START_TIMEOUT; @@ -226,6 +232,7 @@ private SessionOptions() { configureQueueTimeout = QUEUE_OPERATION_TIMEOUT; closeQueueTimeout = QUEUE_OPERATION_TIMEOUT; hostHealthMonitor = null; + userAgentPrefix = ""; } private SessionOptions(Builder builder) { @@ -239,6 +246,7 @@ private SessionOptions(Builder builder) { configureQueueTimeout = builder.configureQueueTimeout; closeQueueTimeout = builder.closeQueueTimeout; hostHealthMonitor = builder.hostHealthMonitor; + userAgentPrefix = builder.userAgentPrefix; } /** @@ -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; @@ -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. * @@ -417,6 +438,7 @@ private Builder(SessionOptions options) { configureQueueTimeout = options.configureQueueTimeout; closeQueueTimeout = options.closeQueueTimeout; hostHealthMonitor = options.hostHealthMonitor; + userAgentPrefix = options.userAgentPrefix; } /** @@ -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; + } } } diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/TcpBrokerConnection.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/TcpBrokerConnection.java index 47c4b9cc..ca7a5696 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/TcpBrokerConnection.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/TcpBrokerConnection.java @@ -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. @@ -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(); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/ClientIdentity.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/ClientIdentity.java index 47f87c8d..8f1d6445 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/ClientIdentity.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/ClientIdentity.java @@ -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. @@ -27,6 +27,7 @@ public class ClientIdentity { private String clusterName; private Integer clusterNodeId; private ClientLanguage sdkLanguage; + private String userAgent; public ClientIdentity() { init(); @@ -48,6 +49,7 @@ private void init() { clusterName = ""; clusterNodeId = -1; sdkLanguage = ClientLanguage.E_UNKNOWN; + userAgent = ""; } public Integer protocolVersion() { @@ -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(); } diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/ControlMessageChoice.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/ControlMessageChoice.java index d6123730..b93095c7 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/ControlMessageChoice.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/ControlMessageChoice.java @@ -187,7 +187,7 @@ public final DisconnectResponse disconnectResponse() { return disconnectResponse; } - public void init() { + public final void init() { configureQueueStream = null; configureQueueStreamResponse = null; configureStream = null; diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/NegotiationMessageChoice.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/NegotiationMessageChoice.java index 5dd7b58a..62a553b2 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/NegotiationMessageChoice.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/msg/NegotiationMessageChoice.java @@ -58,7 +58,7 @@ public final BrokerResponse brokerResponse() { return brokerResponse; } - public void init() { + public final void init() { clientIdentity = null; brokerResponse = null; } diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/net/ConnectionOptions.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/net/ConnectionOptions.java index bc585cc4..f95631a3 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/net/ConnectionOptions.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/net/ConnectionOptions.java @@ -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. @@ -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) { @@ -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; } @@ -99,4 +112,8 @@ public Duration startRetryInterval() { public WriteBufferWaterMark writeBufferWaterMark() { return writeWaterMark; } + + public String userAgentPrefix() { + return userAgentPrefix; + } } diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckHeader.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckHeader.java index 11e07ede..d8ac63b4 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckHeader.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckHeader.java @@ -24,7 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class AckHeader implements Streamable { +public final class AckHeader implements Streamable { // This class represents header for an 'ACK' event. An 'ACK' event is the // event sent by the broker to a client in response to a post message on // queue. Such event is optional, depending on flags used at queue open. diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckMessageImpl.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckMessageImpl.java index c86bca4f..9d04c494 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckMessageImpl.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckMessageImpl.java @@ -105,23 +105,23 @@ public AckMessageImpl( setQueueId(queueId); } - public void setStatus(ResultCodes.AckResult status) { + public final void setStatus(ResultCodes.AckResult status) { int value = ResultCodeUtils.intFromAckResult(status); statusAndCorrelationId = (statusAndCorrelationId & CORRID_MASK) | (value << STATUS_START_IDX); } - public void setCorrelationId(CorrelationIdImpl value) { + public final void setCorrelationId(CorrelationIdImpl value) { int id = value.toInt(); statusAndCorrelationId = (statusAndCorrelationId & STATUS_MASK) | (id & CORRID_MASK); correlationId = value; } - public void setQueueId(int value) { + public final void setQueueId(int value) { queueId = value; } - public void setMessageGUID(final MessageGUID value) { + public final void setMessageGUID(final MessageGUID value) { value.toBinary(messageGUID); } diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckMessageIterator.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckMessageIterator.java index 096dcf00..45debf8a 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckMessageIterator.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/AckMessageIterator.java @@ -22,7 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class AckMessageIterator extends MessageIterator implements Iterator { +public final class AckMessageIterator extends MessageIterator implements Iterator { static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/BinaryMessageProperty.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/BinaryMessageProperty.java index 26338ff5..9c7a9813 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/BinaryMessageProperty.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/BinaryMessageProperty.java @@ -15,7 +15,7 @@ */ package com.bloomberg.bmq.impl.infr.proto; -public class BinaryMessageProperty extends MessageProperty { +public final class BinaryMessageProperty extends MessageProperty { public BinaryMessageProperty() { super(PropertyType.BINARY, MessagePropertyHeader.MAX_PROPERTY_VALUE_LENGTH); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/BoolMessageProperty.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/BoolMessageProperty.java index 1b670e2e..8af2925e 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/BoolMessageProperty.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/BoolMessageProperty.java @@ -15,7 +15,7 @@ */ package com.bloomberg.bmq.impl.infr.proto; -public class BoolMessageProperty extends MessageProperty { +public final class BoolMessageProperty extends MessageProperty { public BoolMessageProperty() { super(PropertyType.BOOL, Byte.SIZE); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ByteMessageProperty.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ByteMessageProperty.java index 76ad84ef..de9e1cb2 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ByteMessageProperty.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ByteMessageProperty.java @@ -15,7 +15,7 @@ */ package com.bloomberg.bmq.impl.infr.proto; -public class ByteMessageProperty extends MessageProperty { +public final class ByteMessageProperty extends MessageProperty { public ByteMessageProperty() { super(PropertyType.BYTE, Byte.SIZE); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ConfirmHeader.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ConfirmHeader.java index addbcfd4..146abf7d 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ConfirmHeader.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ConfirmHeader.java @@ -21,7 +21,7 @@ import com.bloomberg.bmq.impl.infr.util.BitUtil; import java.io.IOException; -public class ConfirmHeader implements Streamable { +public final class ConfirmHeader implements Streamable { // This class represents header for a 'CONFIRM' event. A 'CONFIRM' event // is the event sent by a client to the broker to signify it's done // processing a specific message and the broker can dispose of it. diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ConfirmMessageIterator.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ConfirmMessageIterator.java index 666402a4..27a25425 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ConfirmMessageIterator.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ConfirmMessageIterator.java @@ -21,7 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ConfirmMessageIterator extends MessageIterator { +public final class ConfirmMessageIterator extends MessageIterator { static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/EventHeader.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/EventHeader.java index e89e4e5c..8f175cb9 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/EventHeader.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/EventHeader.java @@ -252,7 +252,7 @@ public void setControlEventEncodingType(EncodingType type) { byte typeAsByte = (byte) (type.toInt()); // Set those bits to represent 'type' - typeSpecificUpdate |= (typeAsByte << CONTROL_EVENT_ENCODING_START_IDX); + typeSpecificUpdate |= (byte) (typeAsByte << CONTROL_EVENT_ENCODING_START_IDX); setTypeSpecific(typeSpecificUpdate); } diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/Int32MessageProperty.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/Int32MessageProperty.java index bf87098c..97cfcc99 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/Int32MessageProperty.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/Int32MessageProperty.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -public class Int32MessageProperty extends MessageProperty { +public final class Int32MessageProperty extends MessageProperty { public Int32MessageProperty() { super(PropertyType.INT32, Integer.SIZE); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/Int64MessageProperty.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/Int64MessageProperty.java index 5fd10c7f..7228f3ff 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/Int64MessageProperty.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/Int64MessageProperty.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -public class Int64MessageProperty extends MessageProperty { +public final class Int64MessageProperty extends MessageProperty { public Int64MessageProperty() { super(PropertyType.INT64, Long.SIZE); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/MessagePropertiesImpl.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/MessagePropertiesImpl.java index bc5f6347..86da37b4 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/MessagePropertiesImpl.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/MessagePropertiesImpl.java @@ -216,7 +216,7 @@ public int streamInOld(T input) throws IOExc } // Read padding bytes - final long numPaddingBytes = input.readByte(); + final int numPaddingBytes = input.readByte(); // Skip padding bytes if (input.skip(numPaddingBytes - 1) != numPaddingBytes - 1) { diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/MessagePropertyHeader.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/MessagePropertyHeader.java index 40d800c2..1b43f396 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/MessagePropertyHeader.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/MessagePropertyHeader.java @@ -21,7 +21,7 @@ import java.io.DataOutput; import java.io.IOException; -public class MessagePropertyHeader { +public final class MessagePropertyHeader { // This class represents the header for a message property in a PUT or // PUSH message. diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/OptionHeader.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/OptionHeader.java index 5266b50a..0ed40788 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/OptionHeader.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/OptionHeader.java @@ -25,7 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class OptionHeader implements Streamable { +public final class OptionHeader implements Streamable { // This class represents the header for an option. In a typical // implementation usage, every Option class will start by an // 'OptionHeader' member. diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushHeader.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushHeader.java index f6c66cb7..cde23502 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushHeader.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushHeader.java @@ -24,7 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PushHeader { +public final class PushHeader { static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); // This struct represents the header for a 'PUSH' event. A 'PUSH' event is diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushMessageImpl.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushMessageImpl.java index 26c4dc4d..ce0e71c7 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushMessageImpl.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushMessageImpl.java @@ -45,7 +45,7 @@ public PushMessageImpl() { reset(); } - public void reset() { + public final void reset() { header = new PushHeader(); appData = new ApplicationData(); options = new Options(); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushMessageIterator.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushMessageIterator.java index 181e6124..85e3b911 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushMessageIterator.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PushMessageIterator.java @@ -20,7 +20,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PushMessageIterator extends MessageIterator implements Iterator { +public final class PushMessageIterator extends MessageIterator + implements Iterator { static Logger logger = LoggerFactory.getLogger(PushMessageIterator.class); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PutHeader.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PutHeader.java index 9d73b902..0a63a9fe 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PutHeader.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PutHeader.java @@ -22,7 +22,7 @@ import com.bloomberg.bmq.impl.infr.util.BitUtil; import java.io.IOException; -public class PutHeader { +public final class PutHeader { // This class represents the header for a 'PUT' event. A 'PUT' event is // the event sent by a client to the broker to post message on queue(s). diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PutMessageIterator.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PutMessageIterator.java index 7194c8c3..889fa167 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PutMessageIterator.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/PutMessageIterator.java @@ -21,7 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PutMessageIterator extends MessageIterator implements Iterator { +public final class PutMessageIterator extends MessageIterator implements Iterator { static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ShortMessageProperty.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ShortMessageProperty.java index 3a4798c0..3dae80c4 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ShortMessageProperty.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/ShortMessageProperty.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -public class ShortMessageProperty extends MessageProperty { +public final class ShortMessageProperty extends MessageProperty { public ShortMessageProperty() { super(PropertyType.SHORT, Short.SIZE); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/StringMessageProperty.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/StringMessageProperty.java index cb3bade8..0e10331c 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/StringMessageProperty.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/proto/StringMessageProperty.java @@ -20,7 +20,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class StringMessageProperty extends MessageProperty { +public final class StringMessageProperty extends MessageProperty { static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); diff --git a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/util/SystemUtil.java b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/util/SystemUtil.java index d735c86f..8d4feee7 100644 --- a/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/util/SystemUtil.java +++ b/bmq-sdk/src/main/java/com/bloomberg/bmq/impl/infr/util/SystemUtil.java @@ -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. @@ -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()) @@ -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; diff --git a/bmq-sdk/src/test/java/com/bloomberg/bmq/impl/infr/codec/JsonDecoderUtilTest.java b/bmq-sdk/src/test/java/com/bloomberg/bmq/impl/infr/codec/JsonDecoderUtilTest.java index ba217461..dc1dc60e 100644 --- a/bmq-sdk/src/test/java/com/bloomberg/bmq/impl/infr/codec/JsonDecoderUtilTest.java +++ b/bmq-sdk/src/test/java/com/bloomberg/bmq/impl/infr/codec/JsonDecoderUtilTest.java @@ -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. diff --git a/bmq-sdk/src/test/java/com/bloomberg/bmq/impl/infr/proto/SchemaEventImplBuilderTest.java b/bmq-sdk/src/test/java/com/bloomberg/bmq/impl/infr/proto/SchemaEventImplBuilderTest.java index 44f879d3..1289ae78 100644 --- a/bmq-sdk/src/test/java/com/bloomberg/bmq/impl/infr/proto/SchemaEventImplBuilderTest.java +++ b/bmq-sdk/src/test/java/com/bloomberg/bmq/impl/infr/proto/SchemaEventImplBuilderTest.java @@ -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. diff --git a/bmq-sdk/src/test/java/com/bloomberg/bmq/it/PlainConsumerIT.java b/bmq-sdk/src/test/java/com/bloomberg/bmq/it/PlainConsumerIT.java index 820d0644..636aa439 100644 --- a/bmq-sdk/src/test/java/com/bloomberg/bmq/it/PlainConsumerIT.java +++ b/bmq-sdk/src/test/java/com/bloomberg/bmq/it/PlainConsumerIT.java @@ -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. @@ -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(); diff --git a/bmq-sdk/src/test/java/com/bloomberg/bmq/it/PlainProducerIT.java b/bmq-sdk/src/test/java/com/bloomberg/bmq/it/PlainProducerIT.java index 09024f50..b0e5bdf4 100644 --- a/bmq-sdk/src/test/java/com/bloomberg/bmq/it/PlainProducerIT.java +++ b/bmq-sdk/src/test/java/com/bloomberg/bmq/it/PlainProducerIT.java @@ -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. @@ -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(); diff --git a/bmq-sdk/src/test/java/com/bloomberg/bmq/util/TestHelpers.java b/bmq-sdk/src/test/java/com/bloomberg/bmq/util/TestHelpers.java index 2a74eeee..a8ddb518 100644 --- a/bmq-sdk/src/test/java/com/bloomberg/bmq/util/TestHelpers.java +++ b/bmq-sdk/src/test/java/com/bloomberg/bmq/util/TestHelpers.java @@ -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); } } } diff --git a/bmq-sdk/src/test/resources/data/msg_control_nego_client_a326573a-2c1e-42a2-afdc-da184456c118.bin b/bmq-sdk/src/test/resources/data/msg_control_nego_client_a326573a-2c1e-42a2-afdc-da184456c118.bin index 212cc5f5..d8255607 100644 Binary files a/bmq-sdk/src/test/resources/data/msg_control_nego_client_a326573a-2c1e-42a2-afdc-da184456c118.bin and b/bmq-sdk/src/test/resources/data/msg_control_nego_client_a326573a-2c1e-42a2-afdc-da184456c118.bin differ