This repository has been archived by the owner on Jul 9, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add uri replacement handler * Bump minor version * Add changelog entry.
- Loading branch information
1 parent
3ddf8e0
commit 01e734e
Showing
5 changed files
with
201 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
Microsoft.Kiota.Http.HttpClientLibrary.Tests/Middleware/UriReplacementHandlerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Microsoft.Kiota.Http.HttpClientLibrary.Middleware; | ||
using Microsoft.Kiota.Http.HttpClientLibrary.Middleware.Options; | ||
using Moq; | ||
using Xunit; | ||
|
||
namespace Microsoft.Kiota.Http.HttpClientLibrary.Tests.Middleware; | ||
|
||
public class UriReplacementOptionTests { | ||
[Fact] | ||
public void Does_Nothing_When_Url_Replacement_Is_Disabled() | ||
{ | ||
var uri = new Uri("http://localhost/test"); | ||
var disabled = new UriReplacementHandlerOption(false, new Dictionary<string, string>()); | ||
|
||
Assert.False(disabled.IsEnabled()); | ||
Assert.Equal(uri, disabled.Replace(uri)); | ||
|
||
disabled = new UriReplacementHandlerOption(false, new Dictionary<string, string>{ | ||
{"test", ""} | ||
}); | ||
|
||
Assert.Equal(uri, disabled.Replace(uri)); | ||
} | ||
|
||
[Fact] | ||
public void Returns_Null_When_Url_Provided_Is_Null() | ||
{ | ||
var disabled = new UriReplacementHandlerOption(false, new Dictionary<string, string>()); | ||
|
||
Assert.False(disabled.IsEnabled()); | ||
Assert.Null(disabled.Replace(null)); | ||
} | ||
|
||
[Fact] | ||
public void Replaces_Key_In_Path_With_Value() | ||
{ | ||
var uri = new Uri("http://localhost/test"); | ||
var option = new UriReplacementHandlerOption(true, new Dictionary<string, string>{{"test", ""}}); | ||
|
||
Assert.True(option.IsEnabled()); | ||
Assert.Equal("http://localhost/", option.Replace(uri)!.ToString()); | ||
} | ||
} | ||
|
||
public class UriReplacementHandlerTests | ||
{ | ||
[Fact] | ||
public async Task Calls_Uri_ReplacementAsync() | ||
{ | ||
var mockReplacement = new Mock<IUriReplacementHandlerOption>(); | ||
mockReplacement.Setup(static x => x.IsEnabled()).Returns(true); | ||
mockReplacement.Setup(static x => x.Replace(It.IsAny<Uri>())).Returns(new Uri("http://changed")); | ||
|
||
var handler = new UriReplacementHandler<IUriReplacementHandlerOption>(mockReplacement.Object) | ||
{ | ||
InnerHandler = new FakeSuccessHandler() | ||
}; | ||
var msg = new HttpRequestMessage(HttpMethod.Get, "http://localhost"); | ||
var client = new HttpClient(handler); | ||
await client.SendAsync(msg); | ||
|
||
mockReplacement.Verify(static x=> x.Replace(It.IsAny<Uri>()), Times.Once()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Microsoft.Kiota.Abstractions; | ||
|
||
namespace Microsoft.Kiota.Http.HttpClientLibrary.Middleware.Options; | ||
|
||
/// <summary> | ||
/// Interface for making URI replacements. | ||
/// </summary> | ||
public interface IUriReplacementHandlerOption : IRequestOption | ||
{ | ||
/// <summary> | ||
/// Check if URI replacement is enabled for the option. | ||
/// </summary> | ||
/// <returns>true if replacement is enabled or false otherwise.</returns> | ||
bool IsEnabled(); | ||
|
||
/// <summary> | ||
/// Accepts a URI and returns a new URI with all replacements applied. | ||
/// </summary> | ||
/// <param name="original">The URI to apply replacements to</param> | ||
/// <returns>A new URI with all replacements applied.</returns> | ||
Uri? Replace(Uri? original); | ||
} | ||
|
||
/// <summary> | ||
/// Url replacement options. | ||
/// </summary> | ||
public class UriReplacementHandlerOption : IUriReplacementHandlerOption | ||
{ | ||
private readonly bool isEnabled; | ||
|
||
private readonly IEnumerable<KeyValuePair<string, string>> replacementPairs; | ||
|
||
/// <summary> | ||
/// Creates a new instance of UriReplacementOption. | ||
/// </summary> | ||
/// <param name="isEnabled">Whether replacement is enabled.</param> | ||
/// <param name="replacementPairs">Replacements with the key being a string to match against and the value being the replacement.</param> | ||
public UriReplacementHandlerOption(bool isEnabled, IEnumerable<KeyValuePair<string, string>> replacementPairs) | ||
{ | ||
this.isEnabled = isEnabled; | ||
this.replacementPairs = replacementPairs; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public bool IsEnabled() | ||
{ | ||
return isEnabled; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public Uri? Replace(Uri? original) | ||
{ | ||
if(original is null) return null; | ||
|
||
if(!isEnabled) | ||
{ | ||
return original; | ||
} | ||
|
||
var newUrl = new UriBuilder(original); | ||
foreach(var pair in replacementPairs) | ||
{ | ||
newUrl.Path = newUrl.Path.Replace(pair.Key, pair.Value); | ||
} | ||
|
||
return newUrl.Uri; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using System.Diagnostics; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Microsoft.Kiota.Abstractions; | ||
using Microsoft.Kiota.Http.HttpClientLibrary.Extensions; | ||
using Microsoft.Kiota.Http.HttpClientLibrary.Middleware.Options; | ||
|
||
namespace Microsoft.Kiota.Http.HttpClientLibrary.Middleware; | ||
|
||
/// <summary> | ||
/// Replaces a portion of the URL. | ||
/// </summary> | ||
/// <typeparam name="TUriReplacementHandlerOption">A type with the rules used to perform a URI replacement.</typeparam> | ||
public class UriReplacementHandler<TUriReplacementHandlerOption> : DelegatingHandler where TUriReplacementHandlerOption : IUriReplacementHandlerOption | ||
{ | ||
private readonly TUriReplacementHandlerOption uriReplacement; | ||
|
||
/// <summary> | ||
/// Creates a new UriReplacementHandler. | ||
/// </summary> | ||
/// <param name="uriReplacement">An object with the URI replacement rules.</param> | ||
public UriReplacementHandler(TUriReplacementHandlerOption uriReplacement) | ||
{ | ||
this.uriReplacement = uriReplacement; | ||
} | ||
|
||
/// <inheritdoc/> | ||
protected override async Task<HttpResponseMessage> SendAsync( | ||
HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) | ||
{ | ||
ActivitySource? activitySource; | ||
Activity? activity; | ||
if(request.GetRequestOption<ObservabilityOptions>() is ObservabilityOptions obsOptions) | ||
{ | ||
activitySource = new ActivitySource(obsOptions.TracerInstrumentationName); | ||
activity = activitySource.StartActivity($"{nameof(UriReplacementHandler<TUriReplacementHandlerOption>)}_{nameof(SendAsync)}"); | ||
activity?.SetTag("com.microsoft.kiota.handler.uri_replacement.enable", uriReplacement.IsEnabled()); | ||
} | ||
else | ||
{ | ||
activity = null; | ||
activitySource = null; | ||
} | ||
|
||
try | ||
{ | ||
request.RequestUri = uriReplacement.Replace(request.RequestUri); | ||
return await base.SendAsync(request, cancellationToken); | ||
} | ||
finally | ||
{ | ||
activity?.Dispose(); | ||
activitySource?.Dispose(); | ||
} | ||
} | ||
} |