Skip to content

Commit

Permalink
Merge pull request #7 from TitanShark/feature/add-base-readme
Browse files Browse the repository at this point in the history
#1 | ADDED: Essential Infos for README.md.
  • Loading branch information
lanluu authored Dec 13, 2020
2 parents 4e66c66 + ed7760a commit aa8a46d
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
73 changes: 72 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,73 @@
# TitanShark.Thresher
Provides core functionalities and abstractions.
Provides extendable **Interception Mechanism** for `HttpClient`.

## TitanShark.Thresher.Core
**Nuget Package:** https://www.nuget.org/packages/TitanShark.Thresher.Core/

**Minimum DotNet's Version required:**
- .Net Framework 4.6.2
- .Net Standard 2.0
- .Net 5.0 (yayy! IoI)

### Core concepts:
`InterceptableHttpClientHandler` is your new friend :-), as it provides you the possibilities for customizing behaviors of `HttpClientHandler` via your own Interceptors (`IInterceptor`).

Interceptors will be executed by an `InterceptorRunner`. For your choice, `SequentialInterceptorsRunner` and `ParallelInterceptorsRunner` were built-in.

### Use case 1: Mocking Request (in Unit-Test)
If you need to mock the Response in your Unit-Test, you should write your own `Transmitter`, like in the below example:

``` CSharp
const string responseContentText = "Hello World!";
var transmitter = new Transmitter
(
(callId, request, cancellationToken) =>
{
_output.WriteLine($"Request to '{request.RequestUri}' was sent out.");

return Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.Created)
{
Content = new StringContent(responseContentText)
});
}
);
var handler = new InterceptableHttpClientHandler(transmitter: transmitter);
var sut = new HttpClient(handler);
```

[More details](TitanShark.Thresher.Core.Tests/TransmitterTests.cs)

### Use case 2: Recording and replaying your Request/Reponse

For tracing, backup or anylazing, you might need to capture all Requests sent out and corresponding Responses received. Then `Recorder` and `Replayer` are your weapons.

Generally, `Recorder` is just a special `Interceptor` which saves passed-thru Request and Response as `Record` into the target `Persistence`. In the other direction, `Replayer` filters `Record` in `Persistence` to form a `Snapshot` for replaying.

``` CSharp
// recording
var persistence = new InMemoryRecordsPersistence();
var recorder = new Recorder(persistence);
var handler = new InterceptableHttpClientHandler(
transmitter: transmitter,
interceptorsRunner: new SequentialInterceptorsRunner(recorder));
var client = new HttpClient(handler);

// code for sending Requests
//...
// replaying Requests with given Response's Status Codes
var snapshot = await persistence.Snapshot(
CancellationToken.None,
started, ended,
new[] { HttpStatusCode.BadRequest, HttpStatusCode.NotFound });
var replayer = new Replayer(new SequentialReplayingStrategy(), client, snapshot);
replayer.Start();
```

[More details](TitanShark.Thresher.Core.Tests/ReplayerTests.cs)

You are not limited to `InMemoryRecordsPersistence`; just write a new `Persistence` for your own need. All you have to do is adding a new implementation of `IRecordsPersistence`.

By default, `SystemJsonRecordSerializer` (powered by `System.Text.Json` - a built-in, lightweight JSON-Lib of .Net Framework) is employed for serializing/deserializing `Record`. You can however plug your own Serialization Mechanism (implementing `IRecordSerializer`) into your `Persistence`'s Instance. An example for using `Newtonsoft.Json` is given [here](TitanShark.Thresher.Core.Tests/InterceptorTests.cs).

### All other cool features (e.g. Embedded MongoDB as Persistence, OpenAPI Compatibility, etc.) are coming soon! ;-)
6 changes: 6 additions & 0 deletions TitanShark.Thresher.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
.github\workflows\publish.yml = .github\workflows\publish.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".docs", ".docs", "{B7F92137-6B5B-41A1-BF75-E0D5D3B10E2B}"
ProjectSection(SolutionItems) = preProject
LICENSE = LICENSE
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down

0 comments on commit aa8a46d

Please sign in to comment.