pmilet.Playback 1.1.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package pmilet.Playback --version 1.1.1                
NuGet\Install-Package pmilet.Playback -Version 1.1.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="pmilet.Playback" Version="1.1.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add pmilet.Playback --version 1.1.1                
#r "nuget: pmilet.Playback, 1.1.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install pmilet.Playback as a Cake Addin
#addin nuget:?package=pmilet.Playback&version=1.1.1

// Install pmilet.Playback as a Cake Tool
#tool nuget:?package=pmilet.Playback&version=1.1.1                

Asp.Net Core Playback

An Asp.Net Core middleware library for recording and replaying http requests.

Purpose

Record http requests in your production environment and replay them locally in your localhost by refering to the recorded playback id. The playback ids are easy to use as regression or load tests.

How to record and playback Api requests?

Once your Asp.NetCore Api is configured for playback ( see quick start section below or refer to sample in github repo ) you can start recording your api requests by setting the X-Playback-Mode request header value to Record.

curl -X GET --header 'Accept: text/plain' --header 'X-Playback-Mode: Record' 'http://apigatewaysample.azurewebsites.net/api/Hello/hello'

then a x-playback-id response header will be returned.

Response Headers
{
  "date": "Wed, 25 Oct 2017 21:05:46 GMT",
  "content-encoding": "gzip",
  "server": "Kestrel",
  "x-powered-by": "ASP.NET",
  "vary": "Accept-Encoding",
  "content-type": "text/plain; charset=utf-8",
  "transfer-encoding": "chunked",
  "x-playback-id": "_ApiGateway+Sample_v1.0_Hello%252Fhello_GET_757602046"
}

To replay set the X-Playback-Mode header to Playback and the X-Playback-Id header with the value received from the recording response.

curl -X GET --header 'Accept: text/plain' --header 'X-Playback-Id: _ApiGateway+Sample_v1.0_Hello%252Fhello_GET_757602046' --header 'X-Playback-Mode: Playback' 'http://apigatewaysample.azurewebsites.net/api/Hello/bye'

When setting the x-playback-mode to None the playback functionality is bypassed.

PlaybackId format

The playback id is composed of differents parts each one carrying important context information. The playback id parts are separated by an underscore :

PlaybackContextInfo_ApiName_PlaybackVersion_RequestPath_RequestMethod_RequestContextHash  

  • The PlayContextInfo comes from the X-Playback-RequestContext header.
  • The ApiName is the web api Name.
  • The PlaybackVersion comes from the X-Playback-Version header.
  • The RequestPath is the request path url encoded
  • The RequestMethod is the request http verb
  • The RequestContextHash is a hash of the request payload in order to univoquely indentify each different request.

For example this playbackid DemoUser_ApiGateway+Sample_v1.0_Hello%252Fhello_GET_757602046 can be descompsed as:

  • PlayContextInfo = DemoUser
  • AssemblyName = ApiGateway+Sample
  • PlaybackVersion = v1.0
  • RequestPath = Hello%252Fhello
  • RequestMethod = GET
  • RequestContextHash = 757602046

How to Quick Start

In your Startup class:

Configure Playback middleware.

using pmilet.Playback;

...

public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }
        
...        

public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            ...
            
            services.AddPlayback(Configuration);
            
            ...
            
            //don't forget to return the service provider
            return services.BuildServiceProvider();

         }
 
 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            ...
            
            app.UsePlayback();
          
            ...
        }
      
 ...
            

In your appsetings.json file:

Add playback storage section

{
  "PlaybackBlobStorage": {
    "ConnectionString": "UseDevelopmentStorage=true",
    "ContainerName": "playback"
  },

In your controllers:

if using swagger, decorate your controller for swagger to generate playback headers in swagger UI  

using pmilet.Playback;

  ...

  [HttpGet]
  [SwaggerOperationFilter(typeof(PlaybackSwaggerFilter))]
  public async Task<string> Get()
  
  ...
  

How to record responses received from outgoing requests

For recording responses from outgoing requests you should use the PlaybackContext class that can be injected in your api proxies.

this code excerpt show how you can save a response received from an outgoing api call

       var response = await httpClient.GetAsync(url);
       var result = await response.Content.ReadAsStringAsync();
       if (_playbackContext.IsRecord)
            {
                await _playbackContext.RecordResult<MyServiceResponse>(result);
            }
            else if ( _playbackContext.IsPlayback )
            {
                return await _playbackContext.PlaybackResult<MyServiceResponse>();
            }
     

How to fake api responses

For faking api call responses implement a class that inherits from IFakeFactory like in the following example:

public class MyPlaybackFakeFactory : FakeFactoryBase
    {
        public override void GenerateFakeResponse(HttpContext context)
        {
            switch (context.Request.Path.Value.ToLower())
            {
                case "/api/hello":
                    if (context.Request.Method == "POST")
                        GenerateFakeResponse<HelloRequest, string>(context, HelloPost);
                    else if (context.Request.Method == "GET")
                        GenerateFakeResponse<string, string>(context, HelloGet);
                    break;
                default:
                    throw new NotImplementedException("fake method not found");
            }
        }

Then don't forget to register your fake factory duting initialization:

public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().AddControllersAsServices();
            
            services.AddPlayback(Configuration, fakeFactory: new MyPlaybackFakeFactory());
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp1.1 is compatible.  netcoreapp2.0 is compatible.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net452 is compatible.  net46 was computed.  net461 is compatible.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.2.2 1,647 4/1/2019
1.2.1 1,215 2/19/2018
1.2.0 1,056 2/19/2018
1.1.2 1,146 1/23/2018
1.1.1 1,219 1/23/2018
1.1.0 1,072 1/23/2018
1.0.10 2,023 10/27/2017
1.0.9 1,488 10/25/2017
1.0.8 1,143 10/25/2017
1.0.7 1,296 10/22/2017
1.0.6 1,073 10/21/2017
1.0.5 989 10/21/2017
1.0.4 1,010 10/21/2017
1.0.3 990 10/18/2017
1.0.2 987 10/18/2017
1.0.1 986 10/18/2017
1.0.0 862 10/15/2017

new file storage service