Skip to content

Commit

Permalink
Pass RequestContext to GetSecret overload
Browse files Browse the repository at this point in the history
  • Loading branch information
heaths committed Mar 20, 2023
1 parent f450955 commit f1cf157
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ public SecretClient(System.Uri vaultUri, Azure.Core.TokenCredential credential,
public virtual Azure.AsyncPageable<Azure.Security.KeyVault.Secrets.SecretProperties> GetPropertiesOfSecretsAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Pageable<Azure.Security.KeyVault.Secrets.SecretProperties> GetPropertiesOfSecretVersions(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.AsyncPageable<Azure.Security.KeyVault.Secrets.SecretProperties> GetPropertiesOfSecretVersionsAsync(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.NullableResponse<Azure.Security.KeyVault.Secrets.KeyVaultSecret> GetSecret(string name, string version, Azure.RequestContext context) { throw null; }
public virtual Azure.Response<Azure.Security.KeyVault.Secrets.KeyVaultSecret> GetSecret(string name, string version = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.NullableResponse<Azure.Security.KeyVault.Secrets.KeyVaultSecret>> GetSecretAsync(string name, string version, Azure.RequestContext context) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Security.KeyVault.Secrets.KeyVaultSecret>> GetSecretAsync(string name, string version = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.NullableResponse<Azure.Security.KeyVault.Secrets.KeyVaultSecret> GetSecretIfExists(string name, string version = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.NullableResponse<Azure.Security.KeyVault.Secrets.KeyVaultSecret>> GetSecretIfExistsAsync(string name, string version = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response PurgeDeletedSecret(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response> PurgeDeletedSecretAsync(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Security.KeyVault.Secrets.SecretProperties> RestoreSecretBackup(byte[] backup, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
Expand Down
31 changes: 16 additions & 15 deletions sdk/keyvault/Azure.Security.KeyVault.Secrets/src/SecretClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,23 +148,25 @@ public virtual Response<KeyVaultSecret> GetSecret(string name, string version =
/// </remarks>
/// <param name="name">The name of the secret.</param>
/// <param name="version">The version of the secret.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
/// <param name="context">A <see cref="RequestContext"/> controlling the request lifetime, error handling, and per-call pipeline policies.</param>
/// <returns>A response containing the <see cref="KeyVaultSecret"/> or <c>null</c> if not found.</returns>
/// <exception cref="ArgumentException"><paramref name="name"/> is an empty string.</exception>
/// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
public virtual async Task<NullableResponse<KeyVaultSecret>> GetSecretIfExistsAsync(string name, string version = null, CancellationToken cancellationToken = default)
#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
public virtual async Task<NullableResponse<KeyVaultSecret>> GetSecretAsync(string name, string version, RequestContext context)
#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
{
Argument.AssertNotNullOrEmpty(name, nameof(name));

using DiagnosticScope scope = _pipeline.CreateScope($"{nameof(SecretClient)}.{nameof(GetSecretIfExists)}");
using DiagnosticScope scope = _pipeline.CreateScope($"{nameof(SecretClient)}.{nameof(GetSecret)}");
scope.AddAttribute("secret", name);
scope.AddAttribute("version", version);
scope.Start();

try
{
return await _pipeline.SendRequestAsync(RequestMethod.Get, ResponseClassifier200404, () => new KeyVaultSecret(), cancellationToken, SecretsPath, name, "/", version).ConfigureAwait(false);
return await _pipeline.SendRequestAsync(RequestMethod.Get, context, () => new KeyVaultSecret(), SecretsPath, name, "/", version).ConfigureAwait(false);
}
catch (Exception e)
{
Expand All @@ -182,23 +184,25 @@ public virtual async Task<NullableResponse<KeyVaultSecret>> GetSecretIfExistsAsy
/// </remarks>
/// <param name="name">The name of the secret.</param>
/// <param name="version">The version of the secret.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
/// <param name="context">A <see cref="RequestContext"/> controlling the request lifetime, error handling, and per-call pipeline policies.</param>
/// <returns>A response containing the <see cref="KeyVaultSecret"/> or <c>null</c> if not found.</returns>
/// <exception cref="ArgumentException"><paramref name="name"/> is an empty string.</exception>
/// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
public virtual NullableResponse<KeyVaultSecret> GetSecretIfExists(string name, string version = null, CancellationToken cancellationToken = default)
#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
public virtual NullableResponse<KeyVaultSecret> GetSecret(string name, string version, RequestContext context)
#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
{
Argument.AssertNotNullOrEmpty(name, nameof(name));

using DiagnosticScope scope = _pipeline.CreateScope($"{nameof(SecretClient)}.{nameof(GetSecretIfExists)}");
using DiagnosticScope scope = _pipeline.CreateScope($"{nameof(SecretClient)}.{nameof(GetSecret)}");
scope.AddAttribute("secret", name);
scope.AddAttribute("version", version);
scope.Start();

try
{
return _pipeline.SendRequest(RequestMethod.Get, ResponseClassifier200404, () => new KeyVaultSecret(), cancellationToken, SecretsPath, name, "/", version);
return _pipeline.SendRequest(RequestMethod.Get, context, () => new KeyVaultSecret(), SecretsPath, name, "/", version);
}
catch (Exception e)
{
Expand All @@ -208,7 +212,7 @@ public virtual NullableResponse<KeyVaultSecret> GetSecretIfExists(string name, s
}

/// <summary>
/// Lists the properties of all enabled and disabled versions of the specified secret. You can use the returned <see cref="SecretProperties.Name"/> and <see cref="SecretProperties.Version"/> in subsequent calls to <see cref="GetSecretAsync"/>.
/// Lists the properties of all enabled and disabled versions of the specified secret. You can use the returned <see cref="SecretProperties.Name"/> and <see cref="SecretProperties.Version"/> in subsequent calls to <c>GetSecretAsync</c>.
/// </summary>
/// <remarks>
/// <para>
Expand All @@ -235,7 +239,7 @@ public virtual AsyncPageable<SecretProperties> GetPropertiesOfSecretVersionsAsyn
}

/// <summary>
/// Lists the properties of all enabled and disabled versions of the specified secret. You can use the returned <see cref="SecretProperties.Name"/> and <see cref="SecretProperties.Version"/> in subsequent calls to <see cref="GetSecret"/>.
/// Lists the properties of all enabled and disabled versions of the specified secret. You can use the returned <see cref="SecretProperties.Name"/> and <see cref="SecretProperties.Version"/> in subsequent calls to <c>GetSecretc</c>.
/// </summary>
/// <remarks>
/// <para>
Expand All @@ -262,7 +266,7 @@ public virtual Pageable<SecretProperties> GetPropertiesOfSecretVersions(string n
}

/// <summary>
/// Lists the properties of all enabled and disabled secrets in the specified vault. You can use the returned <see cref="SecretProperties.Name"/> in subsequent calls to <see cref="GetSecretAsync"/>.
/// Lists the properties of all enabled and disabled secrets in the specified vault. You can use the returned <see cref="SecretProperties.Name"/> in subsequent calls to <c>GetSecretAsync</c>.
/// </summary>
/// <remarks>
/// The Get Secrets operation is applicable to the entire vault. However, only
Expand All @@ -280,7 +284,7 @@ public virtual AsyncPageable<SecretProperties> GetPropertiesOfSecretsAsync(Cance
}

/// <summary>
/// Lists the properties of all enabled and disabled secrets in the specified vault. You can use the returned <see cref="SecretProperties.Name"/> in subsequent calls to <see cref="GetSecret"/>.
/// Lists the properties of all enabled and disabled secrets in the specified vault. You can use the returned <see cref="SecretProperties.Name"/> in subsequent calls to <c>GetSecret</c>.
/// </summary>
/// <remarks>
/// The Get Secrets operation is applicable to the entire vault. However, only
Expand Down Expand Up @@ -896,8 +900,5 @@ public virtual Response<SecretProperties> RestoreSecretBackup(byte[] backup, Can
throw;
}
}

private static ResponseClassifier s_responseClassifier200404;
private static ResponseClassifier ResponseClassifier200404 => s_responseClassifier200404 ??= new StatusCodeClassifier(stackalloc ushort[] { 200, 404 });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -484,10 +484,13 @@ public async Task AuthenticateCrossTenant()
[RecordedTest]
public async Task GetNonExistentSecretNoThrow()
{
RequestContext context = new();
context.AddClassifier(404, false);

ClientDiagnosticListener trace = new ClientDiagnosticListener(name => name.StartsWith("Azure."), IsAsync);
try
{
NullableResponse<KeyVaultSecret> response = await Client.GetSecretIfExistsAsync("ShouldNotExist");
NullableResponse<KeyVaultSecret> response = await Client.GetSecretAsync("ShouldNotExist", null, context);

Assert.AreEqual(404, response.GetRawResponse().Status);
Assert.IsFalse(response.HasValue);
Expand All @@ -499,7 +502,7 @@ public async Task GetNonExistentSecretNoThrow()
trace.Dispose();
}

var scope = trace.AssertScope($"{nameof(SecretClient)}.{nameof(SecretClient.GetSecretIfExists)}");
var scope = trace.AssertScope($"{nameof(SecretClient)}.{nameof(SecretClient.GetSecret)}");
Assert.IsFalse(scope.IsFailed);
}
}
Expand Down
28 changes: 14 additions & 14 deletions sdk/keyvault/Azure.Security.KeyVault.Shared/src/KeyVaultPipeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ public Uri CreateFirstPageUri(string path, params ValueTuple<string, string>[] q
return firstPage.ToUri();
}

public HttpMessage CreateMessage(RequestMethod method, ResponseClassifier classifier, Uri uri, bool appendApiVersion)
public HttpMessage CreateMessage(RequestMethod method, Uri uri, bool appendApiVersion)
{
// No need to allocate a RequestContext now, but if/when we do accept a RequestContext as a public parameter,
// consider passing that with a default classifier instead of a separate classifier parameter.
HttpMessage message = _pipeline.CreateMessage(null, classifier);
HttpMessage message = _pipeline.CreateMessage();
Request request = message.Request;

request.Headers.Add(HttpHeader.Common.JsonContentType);
Expand All @@ -75,10 +75,10 @@ public HttpMessage CreateMessage(RequestMethod method, ResponseClassifier classi
return message;
}

public HttpMessage CreateMessage(RequestMethod method, ResponseClassifier classifier, params string[] path)
public HttpMessage CreateMessage(RequestMethod method, RequestContext context, params string[] path)
{
// See comment in CreateMessage overload above for future design consideration.
HttpMessage message = _pipeline.CreateMessage(null, classifier);
HttpMessage message = _pipeline.CreateMessage(context);
Request request = message.Request;

request.Headers.Add(HttpHeader.Common.JsonContentType);
Expand Down Expand Up @@ -136,7 +136,7 @@ public async Task<Page<T>> GetPageAsync<T>(Uri firstPageUri, string nextLink, Fu
firstPageUri = new Uri(nextLink);
}

using HttpMessage message = CreateMessage(RequestMethod.Get, null, firstPageUri, false);
using HttpMessage message = CreateMessage(RequestMethod.Get, firstPageUri, false);
await SendRequestAsync(message, cancellationToken).ConfigureAwait(false);
Response response = message.Response;

Expand Down Expand Up @@ -168,7 +168,7 @@ public Page<T> GetPage<T>(Uri firstPageUri, string nextLink, Func<T> itemFactory
firstPageUri = new Uri(nextLink);
}

using HttpMessage message = CreateMessage(RequestMethod.Get, null, firstPageUri, false);
using HttpMessage message = CreateMessage(RequestMethod.Get, firstPageUri, false);
SendRequest(message, cancellationToken);
Response response = message.Response;

Expand Down Expand Up @@ -219,19 +219,19 @@ public async Task<Response<TResult>> SendRequestAsync<TResult>(RequestMethod met
return CreateResponse(message.Response, resultFactory());
}

public async Task<NullableResponse<TResult>> SendRequestAsync<TResult>(RequestMethod method, ResponseClassifier classifier, Func<TResult> resultFactory, CancellationToken cancellationToken, params string[] path)
public async Task<NullableResponse<TResult>> SendRequestAsync<TResult>(RequestMethod method, RequestContext context, Func<TResult> resultFactory, params string[] path)
where TResult : IJsonDeserializable
{
using HttpMessage message = CreateMessage(method, classifier, path);
await SendRequestAsync(message, cancellationToken).ConfigureAwait(false);
using HttpMessage message = CreateMessage(method, context, path);
await SendRequestAsync(message, context?.CancellationToken ?? default).ConfigureAwait(false);

return CreateResponse(message, resultFactory);
}

public async Task<Response<TResult>> SendRequestAsync<TResult>(RequestMethod method, Func<TResult> resultFactory, Uri uri, CancellationToken cancellationToken)
where TResult : IJsonDeserializable
{
using HttpMessage message = CreateMessage(method, null, uri, true);
using HttpMessage message = CreateMessage(method, uri, true);
await SendRequestAsync(message, cancellationToken).ConfigureAwait(false);

return CreateResponse(message.Response, resultFactory());
Expand All @@ -246,19 +246,19 @@ public Response<TResult> SendRequest<TResult>(RequestMethod method, Func<TResult
return CreateResponse(message.Response, resultFactory());
}

public NullableResponse<TResult> SendRequest<TResult>(RequestMethod method, ResponseClassifier classifier, Func<TResult> resultFactory, CancellationToken cancellationToken, params string[] path)
public NullableResponse<TResult> SendRequest<TResult>(RequestMethod method, RequestContext context, Func<TResult> resultFactory,params string[] path)
where TResult : IJsonDeserializable
{
using HttpMessage message = CreateMessage(method, classifier, path);
SendRequest(message, cancellationToken);
using HttpMessage message = CreateMessage(method, context, path);
SendRequest(message, context?.CancellationToken ?? default);

return CreateResponse(message, resultFactory);
}

public Response<TResult> SendRequest<TResult>(RequestMethod method, Func<TResult> resultFactory, Uri uri, CancellationToken cancellationToken)
where TResult : IJsonDeserializable
{
using HttpMessage message = CreateMessage(method, null, uri, true);
using HttpMessage message = CreateMessage(method, uri, true);
SendRequest(message, cancellationToken);

return CreateResponse(message.Response, resultFactory());
Expand Down

0 comments on commit f1cf157

Please sign in to comment.