-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ServiceBus SDK: Rbac support #6393
Conversation
bainian12345
commented
May 22, 2019
- Removed dependency to ADAL other than testing purposes
- Added connection string support for RBAC authentication
- Modified client and AadTokenProvider APIs to allow more flexible ways to provide authentication
/// <param name="receiveMode">Mode of receive of messages. Defaults to <see cref="ReceiveMode"/>.PeekLock.</param> | ||
/// <param name="retryPolicy">Retry policy for queue operations. Defaults to <see cref="RetryPolicy.Default"/></param> | ||
/// <remarks>Creates a new connection to the queue, which is opened during the first send/receive operation.</remarks> | ||
public static QueueClient CreateWithAzureActiveDirectory( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CreateWithAzureActiveDirectory [](start = 34, length = 30)
- Do we need this API? We already have the overload where you can pass your own ITokenProvider. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also accept connectionStringBuilder
. So lets not duplicate the APIs
In reply to: 286696363 [](ancestors = 286696363)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious as to the purpose of not just documenting that the consumer should create and use an CreateAzureActiveDirectoryTokenProvider
or CreateAzureActiveDirectoryTokenProvider
and pass them to the ITokenProvider
overload. Is there a benefit to consumers that I'm overlooking?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to block on this, but I'm still curious as to the answer. I feel that I'm missing some important context...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's removed and will no longer part of this change. It was an effort to keep consistency with the EventHubs SDK but it seems like there are good reasons to avoid these redundant APIs.
In reply to: 292678097 [](ancestors = 292678097)
/// <param name="receiveMode">Mode of receive of messages. Defaults to <see cref="ReceiveMode"/>.PeekLock.</param> | ||
/// <param name="retryPolicy">Retry policy for queue operations. Defaults to <see cref="RetryPolicy.Default"/></param> | ||
/// <remarks>Creates a new connection to the queue, which is opened during the first send/receive operation.</remarks> | ||
public static QueueClient CreateWithAzureActiveDirectory( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static [](start = 15, length = 6)
Even if this API is needed, this should not be static. This SDK has slightly different API syntax compared to the older one. Here you should be able to do a new QueueClient()
, and not QueueClient.CreateWith*
#Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do constructor, the signature will collide with the one below. Eventhubs is also using Create() methods
In reply to: 286696743 [](ancestors = 286696743)
/// <param name="receiveMode">Mode of receive of messages. Defaults to <see cref="ReceiveMode"/>.PeekLock.</param> | ||
/// <param name="retryPolicy">Retry policy for queue operations. Defaults to <see cref="RetryPolicy.Default"/></param> | ||
/// <remarks>Creates a new connection to the queue, which is opened during the first send/receive operation.</remarks> | ||
public static QueueClient CreateWithManagedIdentity( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CreateWithManagedIdentity [](start = 34, length = 25)
Same as above #Closed
@@ -10,7 +10,7 @@ namespace Microsoft.Azure.ServiceBus.Primitives | |||
/// <summary> | |||
/// Represents the Azure Active Directory token provider for Azure Managed Service Identity integration. | |||
/// </summary> | |||
public class ManagedServiceIdentityTokenProvider : TokenProvider | |||
public class ManagedIdentityTokenProvider : TokenProvider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ManagedIdentityTokenProvider [](start = 17, length = 28)
Do we need this rename? If we rename the public method then it becomes a breaking change.
If there's enough justification for the rename, lets update the major version in the csproj. #Closed
/// <summary> | ||
/// Enables Azure Active Directory Managed Identity authentication when set to 'Managed Identity' | ||
/// </summary> | ||
public string Authentication { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authentication [](start = 22, length = 14)
Curious as to why this is a string? As compared to other options of - Enum or bool #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest the enum approach, personally. Asking consumers to pass a magic string seems like it would offer a challenge to discovering usable values via intellisense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case that you're set on a string, maybe consider adding a pseudo-enumeration to allow discovery and help prevent typos, then? Something like:
public static class AuthenticationType
{
public static const ManagedIdentity = "Managed Identity";
}
That also gives you the advantage of being able to throw doc comments on the type and member to guide the user experience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it expected to extend methods of authentication in the near future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is another area that I've not seen a response and have concerns about user experience. I don't want to block on it, as it is consistent with the direction that the Event Hubs client went, but I would love to see some thoughts after usability testing.
} | ||
|
||
void validate() | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Instead of calling during ToString(), you could just do validation within the setter of each of the property..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that you have validation within the setter, you don't need this method anymore.
In reply to: 286699955 [](ancestors = 286699955)
@@ -218,6 +218,10 @@ void InitializeConnection(ServiceBusConnectionStringBuilder builder) | |||
{ | |||
this.TokenProvider = new SharedAccessSignatureTokenProvider(builder.SasKeyName, builder.SasKey); | |||
} | |||
else if (!string.Equals(builder.Authentication, "Managed Identity", StringComparison.OrdinalIgnoreCase)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Managed Identity" [](start = 60, length = 18)
nit: convert to a const string
#Closed
@@ -218,6 +218,10 @@ void InitializeConnection(ServiceBusConnectionStringBuilder builder) | |||
{ | |||
this.TokenProvider = new SharedAccessSignatureTokenProvider(builder.SasKeyName, builder.SasKey); | |||
} | |||
else if (!string.Equals(builder.Authentication, "Managed Identity", StringComparison.OrdinalIgnoreCase)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(!string.Equals [](start = 20, length = 15)
Is it supposed to be *!*string.Equals?? #Closed
/// <param name="transportType">Transport type.</param> | ||
/// <param name="retryPolicy">Retry policy for topic operations. Defaults to <see cref="RetryPolicy.Default"/></param> | ||
/// <remarks>Creates a new connection to the topic, which is opened during the first send/receive operation.</remarks> | ||
public static TopicClient CreateWithAzureActiveDirectory( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CreateWithAzureActiveDirectory [](start = 34, length = 30)
Same as QueueClient. We dont need this API #Closed
/// <param name="receiveMode">Mode of receive of messages. Defaults to <see cref="ReceiveMode"/>.PeekLock.</param> | ||
/// <param name="retryPolicy">Retry policy for subscription operations. Defaults to <see cref="RetryPolicy.Default"/></param> | ||
/// <remarks>Creates a new connection to the subscription, which is opened during the first send/receive operation.</remarks> | ||
public static SubscriptionClient CreateWithAzureActiveDirectory( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CreateWithAzureActiveDirectory [](start = 41, length = 30)
Same as QueueClient. We don't need this API #Closed
sdk/servicebus/Microsoft.Azure.ServiceBus/src/Primitives/TokenProvider.cs
Show resolved
Hide resolved
public void InvalidAadConnectionStringTest() | ||
{ | ||
String connecitionString = "Endpoint=sb://test.servicebus.windows.net/;authentication=Managed Identity;SHAREDACCESSKEYNAME=val"; | ||
Assert.Throws<ArgumentException>(() => new ServiceBusConnectionStringBuilder(connecitionString)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
connecitionString [](start = 89, length = 17)
nit: typo #Closed
sdk/servicebus/Microsoft.Azure.ServiceBus/tests/TokenProviderTests.cs
Outdated
Show resolved
Hide resolved
@bainian12345 - Please add @jsquire as a reviewer. #Closed |
Thanks, Neeraj. I flagged myself based on your comment. I'll try to loop back on this before the end of the week with feedback. |
@@ -10,7 +10,7 @@ namespace Microsoft.Azure.ServiceBus.Primitives | |||
/// <summary> | |||
/// Represents the Azure Active Directory token provider for Azure Managed Service Identity integration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're moving forward with the rename, you'll probably want to consider updating this comment as well.
sdk/servicebus/Microsoft.Azure.ServiceBus/src/Primitives/AzureActiveDirectoryTokenProvider.cs
Show resolved
Hide resolved
/// <param name="receiveMode">Mode of receive of messages. Defaults to <see cref="ReceiveMode"/>.PeekLock.</param> | ||
/// <param name="retryPolicy">Retry policy for queue operations. Defaults to <see cref="RetryPolicy.Default"/></param> | ||
/// <remarks>Creates a new connection to the queue, which is opened during the first send/receive operation.</remarks> | ||
public static QueueClient CreateWithAzureActiveDirectory( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious as to the purpose of not just documenting that the consumer should create and use an CreateAzureActiveDirectoryTokenProvider
or CreateAzureActiveDirectoryTokenProvider
and pass them to the ITokenProvider
overload. Is there a benefit to consumers that I'm overlooking?
/// <summary> | ||
/// Enables Azure Active Directory Managed Identity authentication when set to 'Managed Identity' | ||
/// </summary> | ||
public string Authentication { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest the enum approach, personally. Asking consumers to pass a magic string seems like it would offer a challenge to discovering usable values via intellisense.
sdk/servicebus/Microsoft.Azure.ServiceBus/tests/TokenProviderTests.cs
Outdated
Show resolved
Hide resolved
We also need to integrate the management layer with MSI and AAD (rbac support). Is that going to be part of this PR? |
@@ -2,7 +2,7 @@ | |||
<PropertyGroup> | |||
<AssemblyTitle>Azure ServiceBus SDK</AssemblyTitle> | |||
<Description>This is the next generation Azure Service Bus .NET Standard client library that focuses on queues & topics. For more information about Service Bus, see https://azure.microsoft.com/en-us/services/service-bus/</Description> | |||
<VersionPrefix>3.4.0</VersionPrefix> | |||
<VersionPrefix>3.5.0</VersionPrefix> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3.5.0 [](start = 19, length = 5)
Major version needs to be changed here, and not minor version. But now to think of it, this should not be your responsibility. The person doing the release should take care of updating the version whenever he/she releases. Maybe you can revert this change.
Sounds good @jsquire?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with both of Neeraj's points. These changes are definitely worth a major bump due to some being breaking changes. Better to only version during release, lest it keep getting bumped inadvertently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My preference would be to update the changelog.md as well as the version at the time when the decision to ship a new major version is made -- or we should figure out an approach to track the required version changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The question that occurs to me with that approach how a contributor would know when they need to increment the version and when that has already been done prior? I fear that we may have a gap with respect to "we're planning to release a new version and these changes are a part of it" versus "I'd like to include these changes for whenever a new major version is planned" versus "I'd like to include these priority changes and they should trigger a minor release and be done soon."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, in the past (old repo) there were milestones and one of them was the next major. A PR/issue that would be a breaking change would be assigned to that milestone. When it comes to collaborators, especially external, during the PR work/review it becomes clear wherever a change is a breaking one or not and what version should it target (major, minor, or a patch).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And, for consideration, it will be extremely helpful to see issues associated with the PRs that would be aggregated for each release, in the notes section. Similar to what was done here: https://github.com/Azure/azure-service-bus-dotnet/releases
await this.PeekLockTestCase(queueClient.InnerSender, queueClient.InnerReceiver, 10); | ||
} | ||
#pragma warning restore xUnit1013 | ||
static readonly Uri ServiceBusAudience = new Uri("https://servicebus.azure.net"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ServiceBusAudience [](start = 28, length = 18)
This is probably not used anywhere?
[Fact] | ||
[LiveTest] | ||
[DisplayTestMethodName] | ||
public async Task QueueWithAadTokenProviderTest() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QueueWithAadTokenProviderTest [](start = 26, length = 29)
Why did you remove these tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are more like end-to-end integration tests that also rely on many other services, not sure if it's best practice to have it here.
In reply to: 289559465 [](ancestors = 289559465)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bainian12345 does sound like a good candidate for a separate project within the solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in agreement with Sean's suggestion. There seem to be several "please don't run these as part of the automation" cases; a separate project or at least isolating them in a dedicated class would help to keep them from being confused with other tests.
[Fact] | ||
public void InvalidAadConnectionStringTest() | ||
{ | ||
String connectionString = "Endpoint=sb://test.servicebus.windows.net/;authentication=Managed Identity;SHAREDACCESSKEYNAME=val"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String connectionString = "Endpoint=sb://test.servicebus.windows.net/;authentication=Managed Identity;SHAREDACCESSKEYNAME=val"; | |
var connectionString = "Endpoint=sb://test.servicebus.windows.net/;authentication=Managed Identity;SHAREDACCESSKEYNAME=val"; |
connection string support for ManagementClient has been added. In reply to: 497867339 [](ancestors = 497867339) |
{ | ||
return new SharedAccessSignatureTokenProvider(builder.SasKeyName, builder.SasKey); | ||
} | ||
else if (!string.IsNullOrEmpty(builder.Authentication)) | ||
{ | ||
if (builder.Authentication.Equals(ServiceBusConnectionStringBuilder.AuthenticationType.ManagedIdentity, StringComparison.OrdinalIgnoreCase)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to consider simplifying to something like:
else if (String.Equals(builder.Authentication, ServiceBusConnectionStringBuilder.AuthenticationType.ManagedIdentity, StringComparison.OrdinalIgnoreCase))
/// <returns>The <see cref="TokenProvider" /> for returning Json web token.</returns> | ||
public static TokenProvider CreateAadTokenProvider(AuthenticationContext authContext, ClientAssertionCertificate clientAssertionCertificate) | ||
/// <param name="authCallback">The authentication delegate to provide access token.</param> | ||
/// <param name="authority">Address of the authority to issue token.</param> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Respectfully, I'm not sure that these comments offer much context or clarity for users who are unfamiliar. You may want to consider revising them to be more explicit or, if not, just removing them.
@@ -218,6 +218,13 @@ void InitializeConnection(ServiceBusConnectionStringBuilder builder) | |||
{ | |||
this.TokenProvider = new SharedAccessSignatureTokenProvider(builder.SasKeyName, builder.SasKey); | |||
} | |||
else if (!string.IsNullOrEmpty(builder.Authentication)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to consider simplifying to something like:
else if (String.Equals(builder.Authentication, ServiceBusConnectionStringBuilder.AuthenticationType.ManagedIdentity, StringComparison.OrdinalIgnoreCase))
|
||
const string EntityPathConfigName = "EntityPath"; | ||
const string TransportTypeConfigName = "TransportType"; | ||
|
||
const string OperationTimeoutConfigName = "OperationTimeout"; | ||
|
||
string entityPath, sasKeyName, sasKey, sasToken, endpoint; | ||
string authType; | ||
|
||
public static class AuthenticationType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that this is really discoverable tucked in here as a nested class. How would we expect callers to know to look inside the connection string builder to find the authentication type constants?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels a bit redundant to make it its separate class, especially with just one value right now. What do you think about just using a public const like "AuthenticationManagedIdentity"?
In reply to: 292684143 [](ancestors = 292684143)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the perspective of a consumer of the API that does not know about this particular magic string nor the implementation, can you describe the scenario for how you would expect them to discover this value? I'm not clear on how a consumer would know to explore the nested class or the ConnectionStringBuilder
members to discover it.
The reason that I suggest a dedicated type is that if I look in intellisense and see a class called AuthenticationType
or similar and explore the members, I'm more likely to be able to discover it. Frankly, that is the reason that I'm pushing for a true enum here. The type name of the enum in the message signature clearly tells callers where to look for the valid set of values with no intuitive leap.
In code terms:
public void DoTheThing(string magicValueThatYouMustKnow) { ... }
versus
public void DoTheThing(MagicValue magicValue) { ... }
In the latter case, I can clearly understand what you're asking of me. In the former, I have to figure it out. Even when the associated doc comment calls it out, it is easy to miss and not nearly as guided an experience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, I'm not too concerned about the discovery of this value to external users of this API. It's very unlikely that the user would need to manually do anything with this value, since the connection string is just a generated value that they need to copy+paste from elsewhere and feed as an input to this API. I think having this value being discoverable/convenient to other developers is probably more important.
In reply to: 293031840 [](ancestors = 293031840)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anything that is public is users concern. Otherwise, it should be internal.
Also, "users" are developers as well 🙂
@@ -260,6 +302,11 @@ public string GetNamespaceConnectionString() | |||
connectionStringBuilder.Append($"{OperationTimeoutConfigName}{KeyValueSeparator}{this.OperationTimeout}{KeyValuePairDelimiter}"); | |||
} | |||
|
|||
if (this.Authentication != null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern of building negates a lot of the advantage of using a StringBuilder
. Unless there's a compiler optimization that I'm not aware of, you're essentially allocating another string builder to do the format for the bling string and feeding it's output into your string builder.
You may want to consider just doing AppendFormat
or a series of Append
directly to your builder.
@jsquire did you see #6393 (comment)? The change is really forcing abbreviations rather than have clean names. vs |
I did, and I'm of the same opinion. I'm hopeful that there will be a follow-up set of changes that address some of the feedback around discoverability and naming, which has also been discussed offline. That said, I'm trying to be sensitive to a deliverable date for internal testing of the RBAC feature set by the service teams, so I didn't want to block this PR. Were this intended for public release, I would have taken a different tact. I've opened #6548 to track this. |
/// <param name="authCallback">The user defined authentication delegate to provide access token.</param> | ||
/// <param name="authority">URL of the Azure Active Directory instance to issue token.</param> | ||
/// <param name="state">Custom parameters that may be passed into the authentication delegate.</param> | ||
/// <returns>The <see cref="Microsoft.ServiceBus.TokenProvider" /> for returning Json web token.</returns> | ||
public static TokenProvider CreateAadTokenProvider( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest we consider avoiding the abbreviation here and go with something like CreateAzureActiveDirectoryTokenProvider
for clarity. This class and method are public
and, therefore, discoverable/usable by consumers directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at #6393 (comment) wouldn't this change be handled in a separate (follow up) PR, @jsquire?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but I've referred back to this one in the issue that I opened to track, since there are several comments that were not addressed due to time constraints. I wanted to take one last pass and keep thoughts consolidated so that they're all in one place for future consideration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Would expect to see these comments in the new PR with a reference to this PR as a starting point. Otherwise it looks like a call to action on the PR that has been approved 🙂
@@ -191,5 +191,15 @@ public async Task NonAmqpUriSchemesShouldWorkAsExpected() | |||
await receiver.CloseAsync(); | |||
}); | |||
} | |||
|
|||
[Fact] | |||
public void InvalidAadConnectionStringTest() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest we consider avoiding the abbreviation here and go with something like InvalidAzureActiveDirectoryConnectionStringFailsValidation
for clarity. The more explicit the name, the more helpful it is to troubleshoot from the build dashboard for those without deep familiarity with the code.
[Fact] | ||
public void InvalidAadConnectionStringTest() | ||
{ | ||
var connectionString = "Endpoint=sb://test.servicebus.windows.net/;authentication=Managed Identity;SHAREDACCESSKEYNAME=val"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we please move these to [InlineData]
and try to keep the test scope focused? These are really different cases for the same behavior, not a related set of assertions to validate a single operation.
} | ||
}); | ||
} | ||
|
||
[Fact] | ||
public async Task AadAuthCallback() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest we consider avoiding the abbreviation here and try to find a name that more clearly expresses the semantics of what scenario the test is attempting to validate.
{ | ||
if (!string.IsNullOrWhiteSpace(this.SasKeyName)) | ||
{ | ||
throw Fx.Exception.Argument("Authentication, SharedAccessKeyName", Resources.ArgumentInvalidCombination.FormatForUser("Authentication, SharedAccessKeyName")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd suggest using nameof
rather than hardcoding.