diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index 2ddc685..0000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## Actual Behavior
-1.
-2.
-
-## Expected Behavior
-1.
-2.
-
-## Versions
-- OS platform and version:
-- .NET Version:
-- NuGet package version or commit ID:
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..238610d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,22 @@
+---
+name: Bug report
+about: Report a bug to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+
+## Actual Behavior
+1.
+2.
+
+## Expected Behavior
+1.
+2.
+
+## Versions
+- OS platform and version:
+- .NET Version:
+- NuGet package version or commit ID:
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..0ca2c19
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,24 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+
+A clear and concise description of what the problem is. E.g. “I’m always frustrated when [...]”
+
+**Describe the solution you’d like**
+
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you’ve considered**
+
+A clear and concise description of any alternative solutions or features you’ve considered.
+
+**Additional context**
+
+Add any other context or screenshots about the feature request here.
diff --git a/src/Microsoft.Azure.ServiceBus/Amqp/AmqpConnectionHelper.cs b/src/Microsoft.Azure.ServiceBus/Amqp/AmqpConnectionHelper.cs
index 1cb8ba5..91eeb44 100644
--- a/src/Microsoft.Azure.ServiceBus/Amqp/AmqpConnectionHelper.cs
+++ b/src/Microsoft.Azure.ServiceBus/Amqp/AmqpConnectionHelper.cs
@@ -4,6 +4,7 @@
namespace Microsoft.Azure.ServiceBus.Amqp
{
using System;
+ using System.Net;
using Microsoft.Azure.Amqp;
using Microsoft.Azure.Amqp.Sasl;
using Microsoft.Azure.Amqp.Transport;
@@ -101,7 +102,8 @@ namespace Microsoft.Azure.ServiceBus.Amqp
public static TransportSettings CreateWebSocketTransportSettings(
string networkHost,
string hostName,
- int port)
+ int port,
+ IWebProxy proxy)
{
var uriBuilder = new UriBuilder(
WebSocketConstants.WebSocketSecureScheme,
@@ -112,7 +114,8 @@ namespace Microsoft.Azure.ServiceBus.Amqp
{
Uri = uriBuilder.Uri,
ReceiveBufferSize = AmqpConstants.TransportBufferSize,
- SendBufferSize = AmqpConstants.TransportBufferSize
+ SendBufferSize = AmqpConstants.TransportBufferSize,
+ Proxy = proxy
};
TransportSettings tpSettings = webSocketTransportSettings;
diff --git a/src/Microsoft.Azure.ServiceBus/Core/MessageSender.cs b/src/Microsoft.Azure.ServiceBus/Core/MessageSender.cs
index 72613d6..64dcf7a 100644
--- a/src/Microsoft.Azure.ServiceBus/Core/MessageSender.cs
+++ b/src/Microsoft.Azure.ServiceBus/Core/MessageSender.cs
@@ -237,6 +237,11 @@ namespace Microsoft.Azure.ServiceBus.Core
this.ThrowIfClosed();
var count = MessageSender.ValidateMessages(messageList);
+ if (count <= 0)
+ {
+ return;
+ }
+
MessagingEventSource.Log.MessageSendStart(this.ClientId, count);
bool isDiagnosticSourceEnabled = ServiceBusDiagnosticSource.IsEnabled();
diff --git a/src/Microsoft.Azure.ServiceBus/Management/ManagementClient.cs b/src/Microsoft.Azure.ServiceBus/Management/ManagementClient.cs
index 617611b..ac566fa 100644
--- a/src/Microsoft.Azure.ServiceBus/Management/ManagementClient.cs
+++ b/src/Microsoft.Azure.ServiceBus/Management/ManagementClient.cs
@@ -18,7 +18,6 @@ namespace Microsoft.Azure.ServiceBus.Management
private HttpClient httpClient;
private readonly string endpointFQDN;
private readonly ITokenProvider tokenProvider;
- private readonly TimeSpan operationTimeout;
private readonly int port;
private readonly string clientId;
@@ -48,14 +47,13 @@ namespace Microsoft.Azure.ServiceBus.Management
/// Token provider which will generate security tokens for authorization.
public ManagementClient(ServiceBusConnectionStringBuilder connectionStringBuilder, ITokenProvider tokenProvider = default)
{
- this.httpClient = new HttpClient();
+ this.httpClient = new HttpClient { Timeout = connectionStringBuilder.OperationTimeout };
this.endpointFQDN = connectionStringBuilder.Endpoint;
this.tokenProvider = tokenProvider ?? CreateTokenProvider(connectionStringBuilder);
- this.operationTimeout = Constants.DefaultOperationTimeout;
this.port = GetPort(connectionStringBuilder.Endpoint);
this.clientId = nameof(ManagementClient) + Guid.NewGuid().ToString("N").Substring(0, 6);
- MessagingEventSource.Log.ManagementClientCreated(this.clientId, this.operationTimeout.TotalSeconds, this.tokenProvider.ToString());
+ MessagingEventSource.Log.ManagementClientCreated(this.clientId, this.httpClient.Timeout.TotalSeconds, this.tokenProvider.ToString());
}
public static HttpRequestMessage CloneRequest(HttpRequestMessage req)
diff --git a/src/Microsoft.Azure.ServiceBus/Management/NamespaceInfoExtensions.cs b/src/Microsoft.Azure.ServiceBus/Management/NamespaceInfoExtensions.cs
index 0b108ba..391be09 100644
--- a/src/Microsoft.Azure.ServiceBus/Management/NamespaceInfoExtensions.cs
+++ b/src/Microsoft.Azure.ServiceBus/Management/NamespaceInfoExtensions.cs
@@ -57,11 +57,19 @@ namespace Microsoft.Azure.ServiceBus.Management
case "Alias":
nsInfo.Alias = element.Value;
break;
+ case "MessagingUnits":
+ int.TryParse(element.Value, out var units);
+ nsInfo.MessagingUnits = units;
+ break;
case "NamespaceType":
if (Enum.TryParse(element.Value, out var nsType))
{
nsInfo.NamespaceType = nsType;
}
+ else if (element.Value == "Messaging") // TODO: workaround till next major as it's a breaking change
+ {
+ nsInfo.NamespaceType = NamespaceType.ServiceBus;
+ }
else
{
nsInfo.NamespaceType = NamespaceType.Others;
diff --git a/src/Microsoft.Azure.ServiceBus/Management/NamespaceType.cs b/src/Microsoft.Azure.ServiceBus/Management/NamespaceType.cs
index 4e61d68..9a0b466 100644
--- a/src/Microsoft.Azure.ServiceBus/Management/NamespaceType.cs
+++ b/src/Microsoft.Azure.ServiceBus/Management/NamespaceType.cs
@@ -15,7 +15,7 @@ namespace Microsoft.Azure.ServiceBus.Management
///
/// Supported only for backward compatibility.
- /// Namespace can contain mixture of messaging entities and notification hubs.
+ /// Namespace can contain mixture of messaging entities and notification hubs.
///
Mixed = 2,
diff --git a/src/Microsoft.Azure.ServiceBus/Message.cs b/src/Microsoft.Azure.ServiceBus/Message.cs
index fb20401..b8698ba 100644
--- a/src/Microsoft.Azure.ServiceBus/Message.cs
+++ b/src/Microsoft.Azure.ServiceBus/Message.cs
@@ -268,7 +268,7 @@ namespace Microsoft.Azure.ServiceBus
///
/// Gets the total size of the message body in bytes.
///
- public long Size => Body.Length;
+ public long Size => this.Body != null ? this.Body.Length : 0;
///
/// Gets the "user properties" bag, which can be used for custom message metadata.
diff --git a/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj b/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj
index 3988d4b..5b31c53 100644
--- a/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj
+++ b/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj
@@ -23,14 +23,14 @@
false
false
true
- CS1591;CS1573
+ CS1591;CS1573;NU5125
-
+
-
+
diff --git a/src/Microsoft.Azure.ServiceBus/ServiceBusConnection.cs b/src/Microsoft.Azure.ServiceBus/ServiceBusConnection.cs
index 0cb58ce..766bb35 100644
--- a/src/Microsoft.Azure.ServiceBus/ServiceBusConnection.cs
+++ b/src/Microsoft.Azure.ServiceBus/ServiceBusConnection.cs
@@ -4,6 +4,7 @@
namespace Microsoft.Azure.ServiceBus
{
using System;
+ using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.Amqp;
using Microsoft.Azure.Amqp.Framing;
@@ -37,7 +38,7 @@ namespace Microsoft.Azure.ServiceBus
/// Namespace connection string
/// It is the responsibility of the user to close the connection after use through
public ServiceBusConnection(string namespaceConnectionString)
- : this(namespaceConnectionString, Constants.DefaultOperationTimeout, RetryPolicy.Default)
+ : this(namespaceConnectionString, RetryPolicy.Default)
{
}
@@ -45,11 +46,10 @@ namespace Microsoft.Azure.ServiceBus
/// Creates a new connection to service bus.
///
/// Namespace connection string.
- /// Duration after which individual operations will timeout.
/// Retry policy for operations. Defaults to
/// It is the responsibility of the user to close the connection after use through
- public ServiceBusConnection(string namespaceConnectionString, TimeSpan operationTimeout, RetryPolicy retryPolicy = null)
- : this(operationTimeout, retryPolicy)
+ public ServiceBusConnection(string namespaceConnectionString, RetryPolicy retryPolicy = null)
+ : this(retryPolicy)
{
if (string.IsNullOrWhiteSpace(namespaceConnectionString))
{
@@ -65,6 +65,33 @@ namespace Microsoft.Azure.ServiceBus
this.InitializeConnection(serviceBusConnectionStringBuilder);
}
+ ///
+ /// Creates a new connection to service bus.
+ ///
+ /// Namespace connection string.
+ /// Duration after which individual operations will timeout.
+ /// Retry policy for operations. Defaults to
+ /// It is the responsibility of the user to close the connection after use through
+ [Obsolete("This constructor is obsolete. Use ServiceBusConnection(string namespaceConnectionString, RetryPolicy retryPolicy) constructor instead, providing operationTimeout in the connection string.")]
+ public ServiceBusConnection(string namespaceConnectionString, TimeSpan operationTimeout, RetryPolicy retryPolicy = null)
+ : this(retryPolicy)
+ {
+ if (string.IsNullOrWhiteSpace(namespaceConnectionString))
+ {
+ throw Fx.Exception.ArgumentNullOrWhiteSpace(nameof(namespaceConnectionString));
+ }
+
+ var serviceBusConnectionStringBuilder = new ServiceBusConnectionStringBuilder(namespaceConnectionString);
+ if (!string.IsNullOrWhiteSpace(serviceBusConnectionStringBuilder.EntityPath))
+ {
+ throw Fx.Exception.Argument(nameof(namespaceConnectionString), "NamespaceConnectionString should not contain EntityPath.");
+ }
+
+ this.InitializeConnection(serviceBusConnectionStringBuilder);
+ // operationTimeout argument explicitly provided by caller should take precedence over OperationTimeout found in the connection string.
+ this.OperationTimeout = operationTimeout;
+ }
+
///
/// Creates a new connection to service bus.
///
@@ -72,7 +99,7 @@ namespace Microsoft.Azure.ServiceBus
/// Transport type.
/// Retry policy for operations. Defaults to
public ServiceBusConnection(string endpoint, TransportType transportType, RetryPolicy retryPolicy = null)
- : this(Constants.DefaultOperationTimeout, retryPolicy)
+ : this(retryPolicy)
{
if (string.IsNullOrWhiteSpace(endpoint))
{
@@ -88,9 +115,8 @@ namespace Microsoft.Azure.ServiceBus
this.InitializeConnection(serviceBusConnectionStringBuilder);
}
- internal ServiceBusConnection(TimeSpan operationTimeout, RetryPolicy retryPolicy = null)
+ internal ServiceBusConnection(RetryPolicy retryPolicy = null)
{
- this.OperationTimeout = operationTimeout;
this.RetryPolicy = retryPolicy ?? RetryPolicy.Default;
this.syncLock = new object();
}
@@ -193,6 +219,7 @@ namespace Microsoft.Azure.ServiceBus
this.TokenProvider = new SharedAccessSignatureTokenProvider(builder.SasKeyName, builder.SasKey);
}
+ this.OperationTimeout = builder.OperationTimeout;
this.TransportType = builder.TransportType;
this.ConnectionManager = new FaultTolerantAmqpObject(this.CreateConnectionAsync, CloseConnection);
this.TransactionController = new FaultTolerantAmqpObject(this.CreateControllerAsync, CloseController);
@@ -283,7 +310,8 @@ namespace Microsoft.Azure.ServiceBus
return AmqpConnectionHelper.CreateWebSocketTransportSettings(
networkHost: networkHost,
hostName: hostName,
- port: port);
+ port: port,
+ proxy: WebRequest.DefaultWebProxy);
}
return AmqpConnectionHelper.CreateTcpTransportSettings(
diff --git a/src/Microsoft.Azure.ServiceBus/ServiceBusConnectionStringBuilder.cs b/src/Microsoft.Azure.ServiceBus/ServiceBusConnectionStringBuilder.cs
index 676bfc6..2574efe 100644
--- a/src/Microsoft.Azure.ServiceBus/ServiceBusConnectionStringBuilder.cs
+++ b/src/Microsoft.Azure.ServiceBus/ServiceBusConnectionStringBuilder.cs
@@ -5,6 +5,7 @@ namespace Microsoft.Azure.ServiceBus
{
using System;
using System.Collections.Generic;
+ using System.Globalization;
using System.Text;
using Primitives;
@@ -24,6 +25,8 @@ namespace Microsoft.Azure.ServiceBus
const string EntityPathConfigName = "EntityPath";
const string TransportTypeConfigName = "TransportType";
+ const string OperationTimeoutConfigName = "OperationTimeout";
+
string entityPath, sasKeyName, sasKey, sasToken, endpoint;
///
@@ -212,6 +215,12 @@ namespace Microsoft.Azure.ServiceBus
///
public TransportType TransportType { get; set; }
+ ///
+ /// Duration after which individual operations will timeout.
+ ///
+ /// Defaults to 1 minute.
+ public TimeSpan OperationTimeout { get; set; } = Constants.DefaultOperationTimeout;
+
internal Dictionary ConnectionStringProperties = new Dictionary(StringComparer.CurrentCultureIgnoreCase);
///
@@ -243,7 +252,12 @@ namespace Microsoft.Azure.ServiceBus
if (this.TransportType != TransportType.Amqp)
{
- connectionStringBuilder.Append($"{TransportTypeConfigName}{KeyValueSeparator}{this.TransportType}");
+ connectionStringBuilder.Append($"{TransportTypeConfigName}{KeyValueSeparator}{this.TransportType}{KeyValuePairDelimiter}");
+ }
+
+ if (this.OperationTimeout != Constants.DefaultOperationTimeout)
+ {
+ connectionStringBuilder.Append($"{OperationTimeoutConfigName}{KeyValueSeparator}{this.OperationTimeout}{KeyValuePairDelimiter}");
}
return connectionStringBuilder.ToString().Trim(';');
@@ -319,6 +333,31 @@ namespace Microsoft.Azure.ServiceBus
this.TransportType = transportType;
}
}
+ else if (key.Equals(OperationTimeoutConfigName, StringComparison.OrdinalIgnoreCase))
+ {
+ if (int.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out var timeoutInSeconds))
+ {
+ this.OperationTimeout = TimeSpan.FromSeconds(timeoutInSeconds);
+ }
+ else if (TimeSpan.TryParse(value, NumberFormatInfo.InvariantInfo, out var operationTimeout))
+ {
+ this.OperationTimeout = operationTimeout;
+ }
+ else
+ {
+ throw Fx.Exception.Argument(nameof(connectionString), $"The {OperationTimeoutConfigName} ({value}) format is invalid. It must be an integer representing a number of seconds.");
+ }
+
+ if (this.OperationTimeout.TotalMilliseconds <= 0)
+ {
+ throw Fx.Exception.Argument(nameof(connectionString), $"The {OperationTimeoutConfigName} ({value}) must be greater than zero.");
+ }
+
+ if (this.OperationTimeout.TotalHours >= 1)
+ {
+ throw Fx.Exception.Argument(nameof(connectionString), $"The {OperationTimeoutConfigName} ({value}) must be smaller than one hour.");
+ }
+ }
else
{
ConnectionStringProperties[key] = value;
diff --git a/test/Microsoft.Azure.ServiceBus.UnitTests/API/ApiApprovals.ApproveAzureServiceBus.approved.txt b/test/Microsoft.Azure.ServiceBus.UnitTests/API/ApiApprovals.ApproveAzureServiceBus.approved.txt
index 19f35d0..1e1bae4 100644
--- a/test/Microsoft.Azure.ServiceBus.UnitTests/API/ApiApprovals.ApproveAzureServiceBus.approved.txt
+++ b/test/Microsoft.Azure.ServiceBus.UnitTests/API/ApiApprovals.ApproveAzureServiceBus.approved.txt
@@ -309,6 +309,10 @@ namespace Microsoft.Azure.ServiceBus
{
public ServiceBusConnection(Microsoft.Azure.ServiceBus.ServiceBusConnectionStringBuilder connectionStringBuilder) { }
public ServiceBusConnection(string namespaceConnectionString) { }
+ public ServiceBusConnection(string namespaceConnectionString, Microsoft.Azure.ServiceBus.RetryPolicy retryPolicy = null) { }
+ [System.ObsoleteAttribute("This constructor is obsolete. Use ServiceBusConnection(string namespaceConnection" +
+ "String, RetryPolicy retryPolicy) constructor instead, providing operationTimeout" +
+ " in the connection string.")]
public ServiceBusConnection(string namespaceConnectionString, System.TimeSpan operationTimeout, Microsoft.Azure.ServiceBus.RetryPolicy retryPolicy = null) { }
public ServiceBusConnection(string endpoint, Microsoft.Azure.ServiceBus.TransportType transportType, Microsoft.Azure.ServiceBus.RetryPolicy retryPolicy = null) { }
public System.Uri Endpoint { get; set; }
@@ -329,6 +333,7 @@ namespace Microsoft.Azure.ServiceBus
public ServiceBusConnectionStringBuilder(string endpoint, string entityPath, string sharedAccessSignature, Microsoft.Azure.ServiceBus.TransportType transportType) { }
public string Endpoint { get; set; }
public string EntityPath { get; set; }
+ public System.TimeSpan OperationTimeout { get; set; }
public string SasKey { get; set; }
public string SasKeyName { get; set; }
public string SasToken { get; set; }
diff --git a/test/Microsoft.Azure.ServiceBus.UnitTests/Management/ManagementClientTests.cs b/test/Microsoft.Azure.ServiceBus.UnitTests/Management/ManagementClientTests.cs
index 1241073..0c57436 100644
--- a/test/Microsoft.Azure.ServiceBus.UnitTests/Management/ManagementClientTests.cs
+++ b/test/Microsoft.Azure.ServiceBus.UnitTests/Management/ManagementClientTests.cs
@@ -639,7 +639,8 @@ namespace Microsoft.Azure.ServiceBus.UnitTests.Management
{
var nsInfo = await client.GetNamespaceInfoAsync();
Assert.NotNull(nsInfo);
- Assert.Equal(MessagingSku.Standard, nsInfo.MessagingSku); // Most CI systems generally use standard, hence this check just to ensure the API is working.
+ Assert.Equal(MessagingSku.Standard, nsInfo.MessagingSku); // Most CI systems generally use standard, hence this check just to ensure the API is working.
+ Assert.Equal(NamespaceType.ServiceBus, nsInfo.NamespaceType); // Common namespace type used for testing is messaging.
}
public void Dispose()
diff --git a/test/Microsoft.Azure.ServiceBus.UnitTests/Microsoft.Azure.ServiceBus.UnitTests.csproj b/test/Microsoft.Azure.ServiceBus.UnitTests/Microsoft.Azure.ServiceBus.UnitTests.csproj
index 2bcb93c..d2b6540 100644
--- a/test/Microsoft.Azure.ServiceBus.UnitTests/Microsoft.Azure.ServiceBus.UnitTests.csproj
+++ b/test/Microsoft.Azure.ServiceBus.UnitTests/Microsoft.Azure.ServiceBus.UnitTests.csproj
@@ -36,14 +36,14 @@
-
+
-
-
+
+
@@ -56,7 +56,7 @@
-
+
diff --git a/test/Microsoft.Azure.ServiceBus.UnitTests/SenderReceiverTests.cs b/test/Microsoft.Azure.ServiceBus.UnitTests/SenderReceiverTests.cs
index 97f90db..4ce85af 100644
--- a/test/Microsoft.Azure.ServiceBus.UnitTests/SenderReceiverTests.cs
+++ b/test/Microsoft.Azure.ServiceBus.UnitTests/SenderReceiverTests.cs
@@ -376,7 +376,7 @@ namespace Microsoft.Azure.ServiceBus.UnitTests
var recivedMessage = await receiver.ReceiveAsync().ConfigureAwait(false);
Assert.True(Encoding.UTF8.GetString(recivedMessage.Body) == Encoding.UTF8.GetString(messageBody));
-
+
var connection = sender.ServiceBusConnection;
Assert.Throws(() => new MessageSender(connection, TestConstants.PartitionedQueueName));
}
@@ -413,7 +413,7 @@ namespace Microsoft.Azure.ServiceBus.UnitTests
messageBody = Encoding.UTF8.GetBytes("Message 2");
message = new Message(messageBody);
- await sender.SendAsync(message);
+ await sender.SendAsync(message);
recivedMessage = await receiver.ReceiveAsync().ConfigureAwait(false);
Assert.True(Encoding.UTF8.GetString(recivedMessage.Body) == Encoding.UTF8.GetString(messageBody));
@@ -459,5 +459,27 @@ namespace Microsoft.Azure.ServiceBus.UnitTests
await receiver.CloseAsync().ConfigureAwait(false);
}
}
+
+ [Theory]
+ [InlineData(TestConstants.NonPartitionedQueueName)]
+ [DisplayTestMethodName]
+ async Task MessageSenderShouldNotThrowWhenSendingEmptyCollection(string queueName)
+ {
+ var sender = new MessageSender(TestUtility.NamespaceConnectionString, queueName);
+ var receiver = new MessageReceiver(TestUtility.NamespaceConnectionString, queueName, ReceiveMode.ReceiveAndDelete);
+
+ try
+ {
+ await sender.SendAsync(new List());
+ var message = await receiver.ReceiveAsync(TimeSpan.FromSeconds(3));
+ Assert.True(message == null, "Expected not to find any messages, but a message was received.");
+ }
+ finally
+ {
+ await sender.CloseAsync();
+ await receiver.CloseAsync();
+ }
+ }
+
}
}
\ No newline at end of file
diff --git a/test/Microsoft.Azure.ServiceBus.UnitTests/ServiceBusConnectionStringBuilderTests.cs b/test/Microsoft.Azure.ServiceBus.UnitTests/ServiceBusConnectionStringBuilderTests.cs
index a1d3509..4c1c0cd 100644
--- a/test/Microsoft.Azure.ServiceBus.UnitTests/ServiceBusConnectionStringBuilderTests.cs
+++ b/test/Microsoft.Azure.ServiceBus.UnitTests/ServiceBusConnectionStringBuilderTests.cs
@@ -75,6 +75,13 @@ namespace Microsoft.Azure.ServiceBus.UnitTests
csBuilder.EntityPath = "myQ";
Assert.Equal("Endpoint=amqps://contoso.servicebus.windows.net;EntityPath=myQ", csBuilder.ToString());
+
+ csBuilder.EntityPath = "";
+ csBuilder.TransportType = TransportType.AmqpWebSockets;
+ Assert.Equal("Endpoint=amqps://contoso.servicebus.windows.net;TransportType=AmqpWebSockets", csBuilder.ToString());
+
+ csBuilder.OperationTimeout = TimeSpan.FromSeconds(42);
+ Assert.Equal("Endpoint=amqps://contoso.servicebus.windows.net;TransportType=AmqpWebSockets;OperationTimeout=00:00:42", csBuilder.ToString());
}
[Fact]
@@ -126,6 +133,36 @@ namespace Microsoft.Azure.ServiceBus.UnitTests
Assert.Equal(TransportType.Amqp, csBuilder.TransportType);
}
+ [Fact]
+ void ConnectionStringBuilderShouldParseOperationTimeoutAsInteger()
+ {
+ var csBuilder = new ServiceBusConnectionStringBuilder("Endpoint=sb://contoso.servicebus.windows.net;SharedAccessKeyName=keyname;SharedAccessKey=key;OperationTimeout=120");
+ Assert.Equal(TimeSpan.FromMinutes(2), csBuilder.OperationTimeout);
+ }
+
+ [Fact]
+ void ConnectionStringBuilderShouldParseOperationTimeoutAsTimeSpan()
+ {
+ var csBuilder = new ServiceBusConnectionStringBuilder("Endpoint=sb://contoso.servicebus.windows.net;SharedAccessKeyName=keyname;SharedAccessKey=key;OperationTimeout=00:12:34");
+ Assert.Equal(TimeSpan.FromMinutes(12).Add(TimeSpan.FromSeconds(34)), csBuilder.OperationTimeout);
+ }
+
+ [Fact]
+ void ConnectionStringBuilderOperationTimeoutShouldDefaultToOneMinute()
+ {
+ var csBuilder = new ServiceBusConnectionStringBuilder("Endpoint=sb://contoso.servicebus.windows.net;SharedAccessKeyName=keyname;SharedAccessKey=key");
+ Assert.Equal(Constants.DefaultOperationTimeout, csBuilder.OperationTimeout);
+ }
+
+ [Fact]
+ void ConnectionStringBuilderShouldThrowForInvalidOperationTimeout()
+ {
+ var exception = Assert.Throws(() => new ServiceBusConnectionStringBuilder("Endpoint=sb://contoso.servicebus.windows.net;SharedAccessKeyName=keyname;SharedAccessKey=key;OperationTimeout=x"));
+ Assert.Equal("connectionString", exception.ParamName);
+ Assert.Contains("OperationTimeout", exception.Message);
+ Assert.Contains("(x)", exception.Message);
+ }
+
[Fact]
void ConnectionStringBuilderShouldParseToken()
{