Skip to content

Commit 2d3e51f

Browse files
Updates
1 parent 763ffe1 commit 2d3e51f

File tree

10 files changed

+116
-4
lines changed

10 files changed

+116
-4
lines changed

samples/api-degradation-scenarios/.devproxy/devproxyrc.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
"enabled": true,
2424
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
2525
"configSection": "genericRandomErrorPlugin"
26+
},
27+
{
28+
"name": "MockResponsePlugin",
29+
"enabled": true,
30+
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
31+
"configSection": "mockResponsePlugin"
2632
}
2733
],
2834
"urlsToWatch": [
@@ -42,5 +48,9 @@
4248
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/genericrandomerrorplugin.schema.json",
4349
"errorsFile": "errors-503.json",
4450
"rate": 30
51+
},
52+
"mockResponsePlugin": {
53+
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json",
54+
"mocksFile": "mocks.json"
4555
}
4656
}

samples/api-degradation-scenarios/.devproxy/errors-503.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
{
1717
"name": "Retry-After",
1818
"value": "@dynamic"
19+
},
20+
{
21+
"name": "Access-Control-Allow-Origin",
22+
"value": "*"
1923
}
2024
],
2125
"body": {
@@ -35,6 +39,10 @@
3539
{
3640
"name": "Retry-After",
3741
"value": "@dynamic"
42+
},
43+
{
44+
"name": "Access-Control-Allow-Origin",
45+
"value": "*"
3846
}
3947
],
4048
"body": {
@@ -54,6 +62,10 @@
5462
{
5563
"name": "Retry-After",
5664
"value": "@dynamic"
65+
},
66+
{
67+
"name": "Access-Control-Allow-Origin",
68+
"value": "*"
5769
}
5870
],
5971
"body": {

samples/api-degradation-scenarios/.devproxy/intermittent-errors.devproxyrc.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"enabled": true,
1212
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
1313
"configSection": "genericRandomErrorPlugin"
14+
},
15+
{
16+
"name": "MockResponsePlugin",
17+
"enabled": true,
18+
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
19+
"configSection": "mockResponsePlugin"
1420
}
1521
],
1622
"urlsToWatch": [
@@ -20,5 +26,9 @@
2026
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/genericrandomerrorplugin.schema.json",
2127
"errorsFile": "errors-503.json",
2228
"rate": 30
29+
},
30+
"mockResponsePlugin": {
31+
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json",
32+
"mocksFile": "mocks.json"
2333
}
2434
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.mocksfile.schema.json",
3+
"mocks": [
4+
{
5+
"request": {
6+
"url": "https://api.example.com/*"
7+
},
8+
"response": {
9+
"statusCode": 200,
10+
"headers": [
11+
{
12+
"name": "Content-Type",
13+
"value": "application/json"
14+
},
15+
{
16+
"name": "Access-Control-Allow-Origin",
17+
"value": "*"
18+
}
19+
],
20+
"body": {
21+
"status": "ok",
22+
"message": "Request processed successfully"
23+
}
24+
}
25+
}
26+
]
27+
}

samples/api-degradation-scenarios/.devproxy/rate-limiting.devproxyrc.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"enabled": true,
1212
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
1313
"configSection": "rateLimitingPlugin"
14+
},
15+
{
16+
"name": "MockResponsePlugin",
17+
"enabled": true,
18+
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
19+
"configSection": "mockResponsePlugin"
1420
}
1521
],
1622
"urlsToWatch": [
@@ -20,5 +26,9 @@
2026
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/ratelimitingplugin.schema.json",
2127
"costPerRequest": 1,
2228
"rateLimit": 10
29+
},
30+
"mockResponsePlugin": {
31+
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json",
32+
"mocksFile": "mocks.json"
2333
}
2434
}

samples/api-degradation-scenarios/.devproxy/slow-responses.devproxyrc.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
"enabled": true,
77
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
88
"configSection": "latencyPlugin"
9+
},
10+
{
11+
"name": "MockResponsePlugin",
12+
"enabled": true,
13+
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
14+
"configSection": "mockResponsePlugin"
915
}
1016
],
1117
"urlsToWatch": [
@@ -15,5 +21,9 @@
1521
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/latencyplugin.schema.json",
1622
"minMs": 3000,
1723
"maxMs": 5000
24+
},
25+
"mockResponsePlugin": {
26+
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json",
27+
"mocksFile": "mocks.json"
1828
}
1929
}

samples/api-degradation-scenarios/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ This sample demonstrates how to simulate various API degradation scenarios to te
1818

1919
Version|Date|Comments
2020
-------|----|--------
21-
1.0|January 10, 2026|Initial release
21+
1.0|January 18, 2026|Initial release
2222

2323
## Prerequisites
2424

@@ -104,6 +104,7 @@ This sample demonstrates how to use Dev Proxy to simulate API degradation scenar
104104
| `.devproxy/rate-limiting.devproxyrc.json` | Rate limiting at 10 requests/minute |
105105
| `.devproxy/slow-responses.devproxyrc.json` | Random latency between 3-5 seconds |
106106
| `.devproxy/errors-503.json` | Error responses for the GenericRandomErrorPlugin |
107+
| `.devproxy/mocks.json` | Mock responses for successful requests |
107108
| `index.html` | Monitoring dashboard web app |
108109
| `package.json` | Node.js configuration to run the sample |
109110

samples/api-degradation-scenarios/assets/sample.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"longDescription": [
1010
"This sample demonstrates how to simulate various API degradation scenarios including intermittent errors, rate limiting, and slow responses to test your application's resilience."
1111
],
12-
"creationDateTime": "2026-01-10",
13-
"updateDateTime": "2026-01-10",
12+
"creationDateTime": "2026-01-18",
13+
"updateDateTime": "2026-01-18",
1414
"products": [
1515
"Dev Proxy"
1616
],
@@ -25,7 +25,7 @@
2525
},
2626
{
2727
"key": "MOCKS",
28-
"value": "No"
28+
"value": "Yes"
2929
},
3030
{
3131
"key": "PLUGIN",
1.69 MB
Loading

samples/api-degradation-scenarios/index.html

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ <h1>🔥 API Degradation Scenarios</h1>
255255
<h3>Total Requests</h3>
256256
<div class="metric-value neutral" id="totalRequests">0</div>
257257
</div>
258+
<div class="metric-card">
259+
<h3>Pending</h3>
260+
<div class="metric-value neutral" id="pendingRequests">0</div>
261+
</div>
258262
<div class="metric-card">
259263
<h3>Success Rate</h3>
260264
<div class="metric-value success" id="successRate">100%</div>
@@ -271,6 +275,10 @@ <h3>Errors (503)</h3>
271275
<h3>Rate Limited (429)</h3>
272276
<div class="metric-value warning" id="errors429">0</div>
273277
</div>
278+
<div class="metric-card">
279+
<h3>Other Errors</h3>
280+
<div class="metric-value error" id="otherErrors">0</div>
281+
</div>
274282
<div class="metric-card">
275283
<h3>Successful (2xx)</h3>
276284
<div class="metric-value success" id="successCount">0</div>
@@ -308,6 +316,13 @@ <h3>Response Distribution</h3>
308316
</div>
309317
<span class="count" id="error429Percent">0%</span>
310318
</div>
319+
<div class="error-bar">
320+
<span class="label">Other Errors</span>
321+
<div class="bar-container">
322+
<div class="bar error-503" id="otherErrorsBar" style="width: 0%"></div>
323+
</div>
324+
<span class="count" id="otherErrorsPercent">0%</span>
325+
</div>
311326
</div>
312327

313328
<div class="log-container">
@@ -319,9 +334,11 @@ <h3>Request Log</h3>
319334
<script>
320335
const stats = {
321336
total: 0,
337+
pending: 0,
322338
success: 0,
323339
error503: 0,
324340
error429: 0,
341+
otherErrors: 0,
325342
totalResponseTime: 0,
326343
responseTimes: []
327344
};
@@ -330,9 +347,14 @@ <h3>Request Log</h3>
330347

331348
function updateUI() {
332349
document.getElementById('totalRequests').textContent = stats.total;
350+
document.getElementById('pendingRequests').textContent = stats.pending;
351+
const pendingEl = document.getElementById('pendingRequests');
352+
pendingEl.textContent = stats.pending;
353+
pendingEl.className = 'metric-value ' + (stats.pending > 0 ? 'warning' : 'neutral');
333354
document.getElementById('successCount').textContent = stats.success;
334355
document.getElementById('errors503').textContent = stats.error503;
335356
document.getElementById('errors429').textContent = stats.error429;
357+
document.getElementById('otherErrors').textContent = stats.otherErrors;
336358

337359
const successRate = stats.total > 0 ? ((stats.success / stats.total) * 100).toFixed(1) : 100;
338360
const successRateEl = document.getElementById('successRate');
@@ -349,14 +371,17 @@ <h3>Request Log</h3>
349371
const successPercent = (stats.success / stats.total) * 100;
350372
const error503Percent = (stats.error503 / stats.total) * 100;
351373
const error429Percent = (stats.error429 / stats.total) * 100;
374+
const otherErrorsPercent = (stats.otherErrors / stats.total) * 100;
352375

353376
document.getElementById('successBar').style.width = successPercent + '%';
354377
document.getElementById('error503Bar').style.width = error503Percent + '%';
355378
document.getElementById('error429Bar').style.width = error429Percent + '%';
379+
document.getElementById('otherErrorsBar').style.width = otherErrorsPercent + '%';
356380

357381
document.getElementById('successPercent').textContent = successPercent.toFixed(0) + '%';
358382
document.getElementById('error503Percent').textContent = error503Percent.toFixed(0) + '%';
359383
document.getElementById('error429Percent').textContent = error429Percent.toFixed(0) + '%';
384+
document.getElementById('otherErrorsPercent').textContent = otherErrorsPercent.toFixed(0) + '%';
360385
}
361386
}
362387

@@ -387,6 +412,8 @@ <h3>Request Log</h3>
387412

388413
async function makeRequest() {
389414
const startTime = performance.now();
415+
stats.pending++;
416+
updateUI();
390417

391418
try {
392419
const response = await fetch('https://api.example.com/data', {
@@ -399,6 +426,7 @@ <h3>Request Log</h3>
399426
const endTime = performance.now();
400427
const responseTime = Math.round(endTime - startTime);
401428

429+
stats.pending--;
402430
stats.total++;
403431
stats.totalResponseTime += responseTime;
404432
stats.responseTimes.push(responseTime);
@@ -415,11 +443,13 @@ <h3>Request Log</h3>
415443
const retryAfter = response.headers.get('Retry-After');
416444
addLogEntry(response.status, responseTime, `Rate limited. Retry after: ${retryAfter || 'unknown'}s`);
417445
} else {
446+
stats.otherErrors++;
418447
addLogEntry(response.status, responseTime, `HTTP ${response.status}`);
419448
}
420449
} catch (error) {
421450
const endTime = performance.now();
422451
const responseTime = Math.round(endTime - startTime);
452+
stats.pending--;
423453
stats.total++;
424454
stats.totalResponseTime += responseTime;
425455

@@ -460,9 +490,11 @@ <h3>Request Log</h3>
460490

461491
function clearStats() {
462492
stats.total = 0;
493+
stats.pending = 0;
463494
stats.success = 0;
464495
stats.error503 = 0;
465496
stats.error429 = 0;
497+
stats.otherErrors = 0;
466498
stats.totalResponseTime = 0;
467499
stats.responseTimes = [];
468500

0 commit comments

Comments
 (0)