mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-11 22:30:41 +01:00
Add option to ProxySettings to append guid to mapping file (#838)
* Add option to ProxySettings to append guid to mapping file * . * . * .
This commit is contained in:
@@ -106,6 +106,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.xUnit", "src\W
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NET6.WithCertificate", "examples\WireMock.Net.Console.NET6.WithCertificate\WireMock.Net.Console.NET6.WithCertificate.csproj", "{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueExample", "examples\WireMockAzureQueueExample\WireMockAzureQueueExample.csproj", "{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueProxy", "examples\WireMockAzureQueueProxy\WireMockAzureQueueProxy.csproj", "{ADB557D8-D66B-4387-912B-3F73E290B478}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -252,6 +256,14 @@ Global
|
||||
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ADB557D8-D66B-4387-912B-3F73E290B478}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ADB557D8-D66B-4387-912B-3F73E290B478}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -294,6 +306,8 @@ Global
|
||||
{670C7562-C154-442E-A249-7D26849BCD13} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{ADB557D8-D66B-4387-912B-3F73E290B478} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
||||
|
||||
264
examples/WireMockAzureQueueExample/.gitignore
vendored
Normal file
264
examples/WireMockAzureQueueExample/.gitignore
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# Azure Functions localsettings file
|
||||
local.settings.json
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
13
examples/WireMockAzureQueueExample/Function1.cs
Normal file
13
examples/WireMockAzureQueueExample/Function1.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WireMockAzureQueueExample;
|
||||
|
||||
public class Function1
|
||||
{
|
||||
[FunctionName("Function1")]
|
||||
public void Run([QueueTrigger("myqueue-items", Connection = "ConnectionStringToWireMock")]string myQueueItem, ILogger log)
|
||||
{
|
||||
log.LogWarning($"C# Queue trigger function processed: {myQueueItem}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"profiles": {
|
||||
"WireMockAzureQueueExample": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "--port 7290",
|
||||
"launchBrowser": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"appInsights1": {
|
||||
"type": "appInsights"
|
||||
},
|
||||
"secrets1": {
|
||||
"type": "secrets"
|
||||
},
|
||||
"storage1": {
|
||||
"type": "storage",
|
||||
"connectionId": "AzureWebJobsStorage"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"appInsights1": {
|
||||
"type": "appInsights.sdk"
|
||||
},
|
||||
"secrets1": {
|
||||
"type": "secrets.user"
|
||||
},
|
||||
"storage1": {
|
||||
"secretStore": null,
|
||||
"resourceId": null,
|
||||
"type": "storage.emulator",
|
||||
"connectionId": "AzureWebJobsStorage"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
|
||||
<UserSecretsId>bb7d8355-68c4-4f81-8c2d-6cdd80cd7602</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Storage.Blobs" Version="12.3.0" />
|
||||
<PackageReference Include="Azure.Storage.Files.Shares" Version="12.1.0" />
|
||||
<PackageReference Include="Azure.Storage.Queues" Version="12.2.0" />
|
||||
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="4.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="host.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="local.settings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
11
examples/WireMockAzureQueueExample/host.json
Normal file
11
examples/WireMockAzureQueueExample/host.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "2.0",
|
||||
"logging": {
|
||||
"applicationInsights": {
|
||||
"samplingSettings": {
|
||||
"isEnabled": true,
|
||||
"excludedTypes": "Request"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
examples/WireMockAzureQueueProxy/Program.cs
Normal file
40
examples/WireMockAzureQueueProxy/Program.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMockAzureQueueProxy;
|
||||
|
||||
static class Program
|
||||
{
|
||||
static void Main(params string[] args)
|
||||
{
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
Logger = new WireMockConsoleLogger(),
|
||||
Urls = new[] { "http://localhost:20001/" },
|
||||
StartAdminInterface = false,
|
||||
ReadStaticMappings = true,
|
||||
WatchStaticMappings = true,
|
||||
WatchStaticMappingsInSubdirectories = true,
|
||||
//ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||
//{
|
||||
// Url = "http://127.0.0.1:10001",
|
||||
// SaveMapping = true,
|
||||
// SaveMappingToFile = true,
|
||||
// AppendGuidToSavedMappingFile = true
|
||||
//}
|
||||
});
|
||||
|
||||
System.Console.WriteLine("Press any key to stop the server");
|
||||
System.Console.ReadKey();
|
||||
server.Stop();
|
||||
|
||||
System.Console.WriteLine("Displaying all requests");
|
||||
var allRequests = server.LogEntries;
|
||||
System.Console.WriteLine(JsonConvert.SerializeObject(allRequests, Formatting.Indented));
|
||||
|
||||
System.Console.WriteLine("Press any key to quit");
|
||||
System.Console.ReadKey();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="__admin\mappings\*.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"Guid": "b4a2ff02-fb7f-4496-8c04-9aafc4f5f8f7",
|
||||
"Title": "Proxy Mapping for DELETE /devstoreaccount1/myqueue-items/messages/41b2aadc-d6ea-4c3c-ae20-2ae72eb08d88",
|
||||
"Description": "Proxy Mapping for DELETE /devstoreaccount1/myqueue-items/messages/41b2aadc-d6ea-4c3c-ae20-2ae72eb08d88",
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/devstoreaccount1/myqueue-items/messages/41b2aadc-d6ea-4c3c-ae20-2ae72eb08d88",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"DELETE"
|
||||
],
|
||||
"Params": [
|
||||
{
|
||||
"Name": "popreceipt",
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "*",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 204,
|
||||
"Headers": {
|
||||
"Server": "Azurite-Queue/3.19.0",
|
||||
"x-ms-client-request-id": "{{request.headers.x-ms-client-request-id}}",
|
||||
"x-ms-request-id": "{{Random Type=\"Guid\"}}",
|
||||
"x-ms-version": "2021-10-04",
|
||||
"Date": "{{DateTime.Now \"ddd, dd MMM yyy HH’:’mm’:’ss ‘GMT’\"}}",
|
||||
"Connection": "keep-alive",
|
||||
"Keep-Alive": "timeout=5"
|
||||
},
|
||||
"UseTransformer": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"Scenario": "AzureQueue Get Messages",
|
||||
"WhenStateIs": "No more messages",
|
||||
"SetStateTo": "No more messages",
|
||||
"Guid": "4c871968-29ee-472b-a548-170444d4cc3e",
|
||||
"Title": "Proxy Mapping for GET NO MSG /devstoreaccount1/myqueue-items/messages",
|
||||
"Description": "Proxy Mapping for GET NO MSG /devstoreaccount1/myqueue-items/messages",
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/devstoreaccount1/myqueue-items/messages",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"GET"
|
||||
],
|
||||
"Params": [
|
||||
{
|
||||
"Name": "numofmessages",
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "ExactMatcher",
|
||||
"Pattern": "16",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "visibilitytimeout",
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "ExactMatcher",
|
||||
"Pattern": "600",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 200,
|
||||
"Body": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><QueueMessagesList/>",
|
||||
"Headers": {
|
||||
"Content-Type": "application/xml",
|
||||
"Server": "Azurite-Queue/3.19.0",
|
||||
"x-ms-client-request-id": "{{request.headers.x-ms-client-request-id}}",
|
||||
"x-ms-request-id": "{{Random Type=\"Guid\"}}",
|
||||
"x-ms-version": "2021-10-04",
|
||||
"Date": "{{DateTime.Now \"ddd, dd MMM yyy HH’:’mm’:’ss ‘GMT’\"}}",
|
||||
"Connection": "keep-alive",
|
||||
"Keep-Alive": "timeout=5",
|
||||
"Transfer-Encoding": "chunked"
|
||||
},
|
||||
"UseTransformer": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"Scenario": "AzureQueue Get Messages",
|
||||
"SetStateTo": "No more messages",
|
||||
"Guid": "da9c6799-fbf8-41b6-8933-0df50f821ebb",
|
||||
"Title": "Proxy Mapping for GET /devstoreaccount1/myqueue-items/messages",
|
||||
"Description": "Proxy Mapping for GET /devstoreaccount1/myqueue-items/messages",
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/devstoreaccount1/myqueue-items/messages",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"GET"
|
||||
],
|
||||
"Params": [
|
||||
{
|
||||
"Name": "numofmessages",
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "*",
|
||||
"IgnoreCase": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "visibilitytimeout",
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "*",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 200,
|
||||
"Body": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><QueueMessagesList><QueueMessage><MessageId>41b2aadc-d6ea-4c3c-ae20-2ae72eb08d88</MessageId><InsertionTime>Sat, 29 Oct 2022 07:11:40 GMT</InsertionTime><ExpirationTime>Sat, 31 Dec 2022 07:11:40 GMT</ExpirationTime><PopReceipt>MjlPY3QyMDIyMDc6MTE6NDAyMjU2</PopReceipt><TimeNextVisible>Sat, 29 Oct 2022 07:21:40 GMT</TimeNextVisible><DequeueCount>1</DequeueCount><MessageText>c3RlZg==</MessageText></QueueMessage></QueueMessagesList>",
|
||||
"Headers": {
|
||||
"Content-Type": "application/xml",
|
||||
"Server": "Azurite-Queue/3.19.0",
|
||||
"x-ms-client-request-id": "{{request.headers.x-ms-client-request-id}}",
|
||||
"x-ms-request-id": "{{Random Type=\"Guid\"}}",
|
||||
"x-ms-version": "2021-10-04",
|
||||
"Date": "{{DateTime.Now \"ddd, dd MMM yyy HH’:’mm’:’ss ‘GMT’\"}}",
|
||||
"Connection": "keep-alive",
|
||||
"Keep-Alive": "timeout=5",
|
||||
"Transfer-Encoding": "chunked"
|
||||
},
|
||||
"UseTransformer": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Guid": "17c7a389-98e1-4383-975d-54c82d1e3860",
|
||||
"Title": "Proxy Mapping for HEAD /devstoreaccount1/myqueue-items",
|
||||
"Description": "Proxy Mapping for HEAD /devstoreaccount1/myqueue-items",
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/devstoreaccount1/myqueue-items",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"HEAD"
|
||||
],
|
||||
"Params": [
|
||||
{
|
||||
"Name": "comp",
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "ExactMatcher",
|
||||
"Pattern": "metadata",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 200,
|
||||
"Body": "",
|
||||
"Headers": {
|
||||
"Server": "Azurite-Queue/3.19.0",
|
||||
"x-ms-client-request-id": "{{request.headers.x-ms-client-request-id}}",
|
||||
"x-ms-approximate-messages-count": "0",
|
||||
"x-ms-request-id": "{{Random Type=\"Guid\"}}",
|
||||
"x-ms-version": "2021-10-04",
|
||||
"Date": "{{DateTime.Now \"ddd, dd MMM yyy HH’:’mm’:’ss ‘GMT’\"}}",
|
||||
"Connection": "keep-alive",
|
||||
"Keep-Alive": "timeout=5"
|
||||
},
|
||||
"UseTransformer": true
|
||||
}
|
||||
}
|
||||
@@ -1,67 +1,71 @@
|
||||
namespace WireMock.Admin.Settings
|
||||
namespace WireMock.Admin.Settings;
|
||||
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class ProxyAndRecordSettingsModel
|
||||
{
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class ProxyAndRecordSettingsModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The clientCertificate thumbprint or subject name fragment to use.
|
||||
/// Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
||||
/// </summary>
|
||||
public string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||
/// <summary>
|
||||
/// The clientCertificate thumbprint or subject name fragment to use.
|
||||
/// Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
||||
/// </summary>
|
||||
public string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the WebProxySettings.
|
||||
/// </summary>
|
||||
public WebProxySettingsModel WebProxySettings { get; set; }
|
||||
/// <summary>
|
||||
/// Defines the WebProxySettings.
|
||||
/// </summary>
|
||||
public WebProxySettingsModel WebProxySettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Proxy requests should follow redirection (30x).
|
||||
/// </summary>
|
||||
public bool? AllowAutoRedirect { get; set; }
|
||||
/// <summary>
|
||||
/// Proxy requests should follow redirection (30x).
|
||||
/// </summary>
|
||||
public bool? AllowAutoRedirect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The URL to proxy.
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
/// <summary>
|
||||
/// The URL to proxy.
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Save the mapping for each request/response to the internal Mappings.
|
||||
/// </summary>
|
||||
public bool SaveMapping { get; set; }
|
||||
/// <summary>
|
||||
/// Save the mapping for each request/response to the internal Mappings.
|
||||
/// </summary>
|
||||
public bool SaveMapping { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Save the mapping for each request/response also to a file. (Note that SaveMapping must also be set to true.)
|
||||
/// </summary>
|
||||
public bool SaveMappingToFile { get; set; }
|
||||
/// <summary>
|
||||
/// Save the mapping for each request/response also to a file. (Note that SaveMapping must also be set to true.)
|
||||
/// </summary>
|
||||
public bool SaveMappingToFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Only save request/response to the internal Mappings if the status code is included in this pattern. (Note that SaveMapping must also be set to true.)
|
||||
/// The pattern can contain a single value like "200", but also ranges like "2xx", "100,300,600" or "100-299,6xx" are supported.
|
||||
/// </summary>
|
||||
public string SaveMappingForStatusCodePattern { get; set; } = "*";
|
||||
/// <summary>
|
||||
/// Only save request/response to the internal Mappings if the status code is included in this pattern. (Note that SaveMapping must also be set to true.)
|
||||
/// The pattern can contain a single value like "200", but also ranges like "2xx", "100,300,600" or "100-299,6xx" are supported.
|
||||
/// </summary>
|
||||
public string SaveMappingForStatusCodePattern { get; set; } = "*";
|
||||
|
||||
/// <summary>
|
||||
/// Defines a list from headers which will be excluded from the saved mappings.
|
||||
/// </summary>
|
||||
public string[] ExcludedHeaders { get; set; }
|
||||
/// <summary>
|
||||
/// Defines a list from headers which will be excluded from the saved mappings.
|
||||
/// </summary>
|
||||
public string[] ExcludedHeaders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines a list of cookies which will be excluded from the saved mappings.
|
||||
/// </summary>
|
||||
public string[] ExcludedCookies { get; set; }
|
||||
/// <summary>
|
||||
/// Defines a list of cookies which will be excluded from the saved mappings.
|
||||
/// </summary>
|
||||
public string[] ExcludedCookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prefer the Proxy Mapping over the saved Mapping (in case SaveMapping is set to <c>true</c>).
|
||||
/// </summary>
|
||||
// public bool PreferProxyMapping { get; set; }
|
||||
/// <summary>
|
||||
/// Prefer the Proxy Mapping over the saved Mapping (in case SaveMapping is set to <c>true</c>).
|
||||
/// </summary>
|
||||
// public bool PreferProxyMapping { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When SaveMapping is set to <c>true</c>, this setting can be used to control the behavior of the generated request matchers for the new mapping.
|
||||
/// - <c>false</c>, the default matchers will be used.
|
||||
/// - <c>true</c>, the defined mappings in the request wil be used for the new mapping.
|
||||
///
|
||||
/// Default value is false.
|
||||
/// </summary>
|
||||
public bool UseDefinedRequestMatchers { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// When SaveMapping is set to <c>true</c>, this setting can be used to control the behavior of the generated request matchers for the new mapping.
|
||||
/// - <c>false</c>, the default matchers will be used.
|
||||
/// - <c>true</c>, the defined mappings in the request wil be used for the new mapping.
|
||||
///
|
||||
/// Default value is false.
|
||||
/// </summary>
|
||||
public bool UseDefinedRequestMatchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Append an unique GUID to the filename from the saved mapping file.
|
||||
/// </summary>
|
||||
public bool AppendGuidToSavedMappingFile { get; set; }
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Util;
|
||||
@@ -35,15 +36,18 @@ internal static class HttpResponseMessageHelper
|
||||
contentEncodingHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
if (httpResponseMessage.StatusCode != HttpStatusCode.NoContent) // A body is not allowed for 204.
|
||||
{
|
||||
Stream = stream,
|
||||
ContentType = contentTypeHeader?.FirstOrDefault(),
|
||||
DeserializeJson = deserializeJson,
|
||||
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
|
||||
DecompressGZipAndDeflate = decompressGzipAndDeflate
|
||||
};
|
||||
responseMessage.BodyData = await BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false);
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = stream,
|
||||
ContentType = contentTypeHeader?.FirstOrDefault(),
|
||||
DeserializeJson = deserializeJson,
|
||||
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
|
||||
DecompressGZipAndDeflate = decompressGzipAndDeflate
|
||||
};
|
||||
responseMessage.BodyData = await BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var header in headers)
|
||||
|
||||
@@ -99,7 +99,14 @@ namespace WireMock.Owin.Mappers
|
||||
|
||||
if (bytes != null)
|
||||
{
|
||||
await response.Body.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await response.Body.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_options.Logger.Warn("Error writing response body. Exception : {0}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,11 +13,8 @@ internal class MappingToFileSaver
|
||||
|
||||
public MappingToFileSaver(WireMockServerSettings settings, MappingConverter mappingConverter)
|
||||
{
|
||||
Guard.NotNull(settings);
|
||||
Guard.NotNull(mappingConverter);
|
||||
|
||||
_settings = settings;
|
||||
_mappingConverter = mappingConverter;
|
||||
_settings = Guard.NotNull(settings);
|
||||
_mappingConverter = Guard.NotNull(mappingConverter);
|
||||
}
|
||||
|
||||
public void SaveMappingToFile(IMapping mapping, string? folder = null)
|
||||
@@ -30,17 +27,31 @@ internal class MappingToFileSaver
|
||||
}
|
||||
|
||||
var model = _mappingConverter.ToMappingModel(mapping);
|
||||
string filename = (!string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToString()) + ".json";
|
||||
|
||||
string path = Path.Combine(folder, filename);
|
||||
var filename = BuildSanitizedFileName(mapping);
|
||||
var path = Path.Combine(folder, filename);
|
||||
|
||||
_settings.Logger.Info("Saving Mapping file {0}", filename);
|
||||
_settings.Logger.Info("Saving Mapping file {0}", path);
|
||||
|
||||
_settings.FileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(model, JsonSerializationConstants.JsonSerializerSettingsDefault));
|
||||
}
|
||||
|
||||
private static string SanitizeFileName(string name, char replaceChar = '_')
|
||||
private string BuildSanitizedFileName(IMapping mapping, char replaceChar = '_')
|
||||
{
|
||||
return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, replaceChar));
|
||||
string name;
|
||||
if (!string.IsNullOrEmpty(mapping.Title))
|
||||
{
|
||||
name = mapping.Title!;
|
||||
if (_settings.ProxyAndRecordSettings?.AppendGuidToSavedMappingFile == true)
|
||||
{
|
||||
name += $"{replaceChar}{mapping.Guid}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = mapping.Guid.ToString();
|
||||
}
|
||||
|
||||
return $"{Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, replaceChar))}.json";
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -18,11 +16,9 @@ using WireMock.Http;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Proxy;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Serialization;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
@@ -208,62 +204,6 @@ public partial class WireMockServer
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Proxy and Record
|
||||
private HttpClient? _httpClientForProxy;
|
||||
|
||||
private void InitProxyAndRecord(WireMockServerSettings settings)
|
||||
{
|
||||
if (settings.ProxyAndRecordSettings == null)
|
||||
{
|
||||
_httpClientForProxy = null;
|
||||
DeleteMapping(ProxyMappingGuid);
|
||||
return;
|
||||
}
|
||||
|
||||
_httpClientForProxy = HttpClientBuilder.Build(settings.ProxyAndRecordSettings);
|
||||
|
||||
var proxyRespondProvider = Given(Request.Create().WithPath("/*").UsingAnyMethod()).WithGuid(ProxyMappingGuid).WithTitle("Default Proxy Mapping on /*");
|
||||
if (settings.StartAdminInterface == true)
|
||||
{
|
||||
proxyRespondProvider.AtPriority(WireMockConstants.ProxyPriority);
|
||||
}
|
||||
|
||||
proxyRespondProvider.RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
|
||||
}
|
||||
|
||||
private async Task<IResponseMessage> ProxyAndRecordAsync(IRequestMessage requestMessage, WireMockServerSettings settings)
|
||||
{
|
||||
var requestUri = new Uri(requestMessage.Url);
|
||||
var proxyUri = new Uri(settings.ProxyAndRecordSettings!.Url);
|
||||
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
|
||||
|
||||
var proxyHelper = new ProxyHelper(settings);
|
||||
|
||||
var (responseMessage, mapping) = await proxyHelper.SendAsync(
|
||||
null,
|
||||
_settings.ProxyAndRecordSettings!,
|
||||
_httpClientForProxy!,
|
||||
requestMessage,
|
||||
proxyUriWithRequestPathAndQuery.AbsoluteUri
|
||||
).ConfigureAwait(false);
|
||||
|
||||
if (mapping != null)
|
||||
{
|
||||
if (settings.ProxyAndRecordSettings.SaveMapping)
|
||||
{
|
||||
_options.Mappings.TryAdd(mapping.Guid, mapping);
|
||||
}
|
||||
|
||||
if (settings.ProxyAndRecordSettings.SaveMappingToFile)
|
||||
{
|
||||
_mappingToFileSaver.SaveMappingToFile(mapping);
|
||||
}
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Settings
|
||||
private IResponseMessage SettingsGet(IRequestMessage requestMessage)
|
||||
{
|
||||
|
||||
68
src/WireMock.Net/Server/WireMockServer.Proxy.cs
Normal file
68
src/WireMock.Net/Server/WireMockServer.Proxy.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Constants;
|
||||
using WireMock.Http;
|
||||
using WireMock.Proxy;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Server;
|
||||
|
||||
public partial class WireMockServer
|
||||
{
|
||||
private HttpClient? _httpClientForProxy;
|
||||
|
||||
private void InitProxyAndRecord(WireMockServerSettings settings)
|
||||
{
|
||||
if (settings.ProxyAndRecordSettings == null)
|
||||
{
|
||||
_httpClientForProxy = null;
|
||||
DeleteMapping(ProxyMappingGuid);
|
||||
return;
|
||||
}
|
||||
|
||||
_httpClientForProxy = HttpClientBuilder.Build(settings.ProxyAndRecordSettings);
|
||||
|
||||
var proxyRespondProvider = Given(Request.Create().WithPath("/*").UsingAnyMethod()).WithGuid(ProxyMappingGuid).WithTitle("Default Proxy Mapping on /*");
|
||||
if (settings.StartAdminInterface == true)
|
||||
{
|
||||
proxyRespondProvider.AtPriority(WireMockConstants.ProxyPriority);
|
||||
}
|
||||
|
||||
proxyRespondProvider.RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
|
||||
}
|
||||
|
||||
private async Task<IResponseMessage> ProxyAndRecordAsync(IRequestMessage requestMessage, WireMockServerSettings settings)
|
||||
{
|
||||
var requestUri = new Uri(requestMessage.Url);
|
||||
var proxyUri = new Uri(settings.ProxyAndRecordSettings!.Url);
|
||||
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
|
||||
|
||||
var proxyHelper = new ProxyHelper(settings);
|
||||
|
||||
var (responseMessage, mapping) = await proxyHelper.SendAsync(
|
||||
null,
|
||||
_settings.ProxyAndRecordSettings!,
|
||||
_httpClientForProxy!,
|
||||
requestMessage,
|
||||
proxyUriWithRequestPathAndQuery.AbsoluteUri
|
||||
).ConfigureAwait(false);
|
||||
|
||||
if (mapping != null)
|
||||
{
|
||||
if (settings.ProxyAndRecordSettings.SaveMapping)
|
||||
{
|
||||
_options.Mappings.TryAdd(mapping.Guid, mapping);
|
||||
}
|
||||
|
||||
if (settings.ProxyAndRecordSettings.SaveMappingToFile)
|
||||
{
|
||||
_mappingToFileSaver.SaveMappingToFile(mapping);
|
||||
}
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
@@ -58,4 +58,9 @@ public class ProxyAndRecordSettings : HttpClientSettings
|
||||
/// Default value is false.
|
||||
/// </summary>
|
||||
public bool UseDefinedRequestMatchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Append an unique GUID to the filename from the saved mapping file.
|
||||
/// </summary>
|
||||
public bool AppendGuidToSavedMappingFile { get; set; }
|
||||
}
|
||||
@@ -94,6 +94,7 @@ public static class WireMockServerSettingsParser
|
||||
SaveMappingForStatusCodePattern = parser.GetStringValue("SaveMappingForStatusCodePattern", "*"),
|
||||
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
|
||||
UseDefinedRequestMatchers = parser.GetBoolValue(nameof(ProxyAndRecordSettings.UseDefinedRequestMatchers)),
|
||||
AppendGuidToSavedMappingFile = parser.GetBoolValue(nameof(ProxyAndRecordSettings.AppendGuidToSavedMappingFile)),
|
||||
Url = proxyUrl!
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user