From 4ad6d9367938f2e1962e0273689adb514797ca22 Mon Sep 17 00:00:00 2001 From: Mikayla Thompson Date: Fri, 4 Oct 2024 09:32:15 -0600 Subject: [PATCH] Add a doc about the architecture of the migration console (#1045) Signed-off-by: Mikayla Thompson --- docs/diagrams/migration-console-arch.svg | 2 + ...igration-console-library-source.excalidraw | 2431 +++++++++++++++++ docs/diagrams/migration-console-library.svg | 10 + docs/migration-console.md | 119 + 4 files changed, 2562 insertions(+) create mode 100644 docs/diagrams/migration-console-arch.svg create mode 100644 docs/diagrams/migration-console-library-source.excalidraw create mode 100644 docs/diagrams/migration-console-library.svg create mode 100644 docs/migration-console.md diff --git a/docs/diagrams/migration-console-arch.svg b/docs/diagrams/migration-console-arch.svg new file mode 100644 index 000000000..32b552c9c --- /dev/null +++ b/docs/diagrams/migration-console-arch.svg @@ -0,0 +1,2 @@ + +
Customer VPC
<div><b>Customer VPC</b><br></div>
Source Cluster
<div><b>Source Cluster</b></div>
Target Cluster
[Not supported by viewer]
Reindex-From-Snapshot
Service
[Not supported by viewer]
Replayer Service
<div><b>Replayer Service</b><br></div>
Shared Logs
EFS Volume
[Not supported by viewer]
Kafka Cluster
[Not supported by viewer]
Cloudwatch Metrics
<div><b>Cloudwatch Metrics</b><br></div>
Deployment
Environment
[Not supported by viewer]
Migration Console
<div><b>Migration Console</b><br></div>
migration-
services.yaml
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/diagrams/migration-console-library-source.excalidraw b/docs/diagrams/migration-console-library-source.excalidraw new file mode 100644 index 000000000..9f6644967 --- /dev/null +++ b/docs/diagrams/migration-console-library-source.excalidraw @@ -0,0 +1,2431 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/2.5.1", + "elements": [ + { + "type": "arrow", + "version": 528, + "versionNonce": 373249885, + "index": "am", + "isDeleted": false, + "id": "sc5ljO139VJebZtRI-8CY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -496.4054782823572, + "y": -521.0827518074575, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 245.20663923825094, + "height": 48.371671902401886, + "seed": 653324073, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727965969762, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "hI3MSugkgDaaqg8bD2uv5", + "gap": 22.794294021086728, + "focus": 0.21902151372247095 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 245.20663923825094, + 48.371671902401886 + ] + ] + }, + { + "type": "rectangle", + "version": 214, + "versionNonce": 1208212615, + "index": "an", + "isDeleted": false, + "id": "TmO8qTXa64z0K3Vlu4Iei", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -786.749348932779, + "y": -676.6053196326957, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 254.5914965900019, + "height": 249.90599554899651, + "seed": 1463493129, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "lbKc6IRp" + } + ], + "updated": 1716937146163, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 182, + "versionNonce": 899783753, + "index": "ao", + "isDeleted": false, + "id": "lbKc6IRp", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -684.4855906890475, + "y": -569.1523218581974, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 50.06398010253906, + "height": 35, + "seed": 695990505, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937469235, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "CLI", + "rawText": "CLI", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "TmO8qTXa64z0K3Vlu4Iei", + "originalText": "CLI", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 354, + "versionNonce": 268066983, + "index": "ap", + "isDeleted": false, + "id": "Ud5Si1gCxpxwFV5xPpThp", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -792.2277451614643, + "y": -407.77055733106306, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 263.1491939543717, + "height": 212.301706599582, + "seed": 1866396617, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "C64hjNOd" + }, + { + "id": "Z-Cogfz7pcLmqfV8xlTAF", + "type": "arrow" + } + ], + "updated": 1716937267371, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 336, + "versionNonce": 159112713, + "index": "aq", + "isDeleted": false, + "id": "C64hjNOd", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -718.935138235548, + "y": -319.1197040312721, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 116.56398010253906, + "height": 35, + "seed": 1017090729, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937470634, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "Web API", + "rawText": "Web API", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Ud5Si1gCxpxwFV5xPpThp", + "originalText": "Web API", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 931, + "versionNonce": 1946566397, + "index": "ar", + "isDeleted": false, + "id": "Z-Cogfz7pcLmqfV8xlTAF", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -508.1163476265317, + "y": -285.27817477542, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 261.4415364513728, + "height": 16.15839450763235, + "seed": 373904777, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727965969762, + "link": null, + "locked": false, + "startBinding": { + "elementId": "Ud5Si1gCxpxwFV5xPpThp", + "gap": 20.96220358056098, + "focus": 0.06049898221545567 + }, + "endBinding": { + "elementId": "hI3MSugkgDaaqg8bD2uv5", + "gap": 18.270266152139357, + "focus": -0.2815866721633738 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 261.4415364513728, + 16.15839450763235 + ] + ] + }, + { + "type": "rectangle", + "version": 218, + "versionNonce": 1643164009, + "index": "as", + "isDeleted": false, + "id": "hI3MSugkgDaaqg8bD2uv5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -228.40454502301952, + "y": -644.3279314081583, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 498.7453989101624, + "height": 604.5785032585296, + "seed": 1601682537, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "jYK5zu38VfhniTZ4uQb9q", + "type": "arrow" + }, + { + "id": "VYkzOS3WIRQI-juaFX9wm", + "type": "arrow" + }, + { + "type": "text", + "id": "23uvP31d" + }, + { + "id": "j-P5CxtJ1pGwubng0NvaP", + "type": "arrow" + }, + { + "id": "6ndSG_LPQCkJx2LppapAz", + "type": "arrow" + }, + { + "id": "Z-Cogfz7pcLmqfV8xlTAF", + "type": "arrow" + }, + { + "id": "sc5ljO139VJebZtRI-8CY", + "type": "arrow" + } + ], + "updated": 1716994005515, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 147, + "versionNonce": 995030791, + "index": "at", + "isDeleted": false, + "id": "23uvP31d", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -12.7118219120469, + "y": -639.3279314081583, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 67.35995268821716, + "height": 25, + "seed": 133580617, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937268149, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Library", + "rawText": "Library", + "textAlign": "center", + "verticalAlign": "top", + "containerId": "hI3MSugkgDaaqg8bD2uv5", + "originalText": "Library", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 453, + "versionNonce": 684516381, + "index": "au", + "isDeleted": false, + "id": "jYK5zu38VfhniTZ4uQb9q", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 282.3193185134342, + "y": -523.7082384449244, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 158.89547429717612, + "height": 105.29598233844911, + "seed": 2048947753, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727965969762, + "link": null, + "locked": false, + "startBinding": { + "elementId": "DGRfNbZqUvBlnfG8GYZ8G", + "gap": 23.230461595946792, + "focus": -0.40744892948502426 + }, + "endBinding": { + "elementId": "_zTunDuOQ4bTtidxM2k8_", + "gap": 23.380058979979424, + "focus": 0.5589761514048415 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 158.89547429717612, + -105.29598233844911 + ] + ] + }, + { + "type": "rectangle", + "version": 207, + "versionNonce": 1450599357, + "index": "av", + "isDeleted": false, + "id": "_zTunDuOQ4bTtidxM2k8_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 464.5948517905898, + "y": -704.7416092999871, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 220.33545174151624, + "height": 127.19004201000484, + "seed": 1222756617, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "t5vxFRHi" + }, + { + "id": "jYK5zu38VfhniTZ4uQb9q", + "type": "arrow" + } + ], + "updated": 1727965969762, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 200, + "versionNonce": 46817020, + "index": "aw", + "isDeleted": false, + "id": "t5vxFRHi", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 471.2426573122268, + "y": -666.1465882949847, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 207.0398406982422, + "height": 50, + "seed": 498450409, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727793683317, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Source Cluster\non self-managed EC2", + "rawText": "Source Cluster\non self-managed EC2", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "_zTunDuOQ4bTtidxM2k8_", + "originalText": "Source Cluster\non self-managed EC2", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 230, + "versionNonce": 751574724, + "index": "ax", + "isDeleted": false, + "id": "MiXIdaBZpsxLfnoqfCg3f", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 471.1761801226802, + "y": -553.5798537142626, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 207.04947106193887, + "height": 136.76291228759376, + "seed": 1722276553, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "VYkzOS3WIRQI-juaFX9wm", + "type": "arrow" + }, + { + "type": "text", + "id": "idO17qxQ" + } + ], + "updated": 1727793683317, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 257, + "versionNonce": 1822236540, + "index": "ay", + "isDeleted": false, + "id": "idO17qxQ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 480.9209931682981, + "y": -522.6983975704658, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 187.55984497070312, + "height": 75, + "seed": 1146329513, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727793683317, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Target Cluster\non Amazon\nOpenSearch Service", + "rawText": "Target Cluster\non Amazon OpenSearch Service", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "MiXIdaBZpsxLfnoqfCg3f", + "originalText": "Target Cluster\non Amazon OpenSearch Service", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 919, + "versionNonce": 20207741, + "index": "b01", + "isDeleted": false, + "id": "VYkzOS3WIRQI-juaFX9wm", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 285.18334648523546, + "y": -467.69128123871326, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 162.19220645205303, + "height": 18.54794515635308, + "seed": 473149001, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727965969762, + "link": null, + "locked": false, + "startBinding": { + "elementId": "DGRfNbZqUvBlnfG8GYZ8G", + "gap": 26.09448956774804, + "focus": -0.4771003707891943 + }, + "endBinding": { + "elementId": "MiXIdaBZpsxLfnoqfCg3f", + "gap": 23.800627185391704, + "focus": 0.1944828762841962 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 162.19220645205303, + -18.54794515635308 + ] + ] + }, + { + "type": "arrow", + "version": 531, + "versionNonce": 1077483197, + "index": "b02", + "isDeleted": false, + "id": "j-P5CxtJ1pGwubng0NvaP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 287.2405244657039, + "y": -117.99944145585079, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 160.54223549206068, + "height": 52.8145641944659, + "seed": 270073129, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727965969763, + "link": null, + "locked": false, + "startBinding": { + "elementId": "DGRfNbZqUvBlnfG8GYZ8G", + "gap": 28.151667548216494, + "focus": 0.5975896581267996 + }, + "endBinding": { + "elementId": "tqzJqxcbGujDg5LZWcObJ", + "gap": 18.18440008989603, + "focus": 0.051621758070718254 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 160.54223549206068, + 52.8145641944659 + ] + ] + }, + { + "type": "rectangle", + "version": 119, + "versionNonce": 1907970281, + "index": "b03", + "isDeleted": false, + "id": "jtoMud1rt-GVH0Lk5TCO5", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -208.82369703568418, + "y": -589.2180183144892, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 141.62724852923725, + "height": 529.6133804640942, + "seed": 1009872905, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1716994008287, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 15, + "versionNonce": 812021799, + "index": "b04", + "isDeleted": false, + "id": "obMwP28y", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -185.325230782816, + "y": -350.68140885314006, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 104.53992307186127, + "height": 25, + "seed": 1987610345, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937106999, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Middleware", + "rawText": "Middleware", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Middleware", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 177, + "versionNonce": 317056647, + "index": "b04V", + "isDeleted": false, + "id": "zZmtVyoUxjXbCR-sY5utc", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -67.48916101841894, + "y": -586.0956694137958, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 165.84105076414778, + "height": 523.750282860978, + "seed": 1232716233, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1716994010902, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 134, + "versionNonce": 608476617, + "index": "b05", + "isDeleted": false, + "id": "slrF8BjKJEuyf-8Cf7puQ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -57.13661711447094, + "y": -532.1031744466154, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 141.91478900700213, + "height": 95.81065730803766, + "seed": 1649451177, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "MrQCqzaS" + } + ], + "updated": 1717017095925, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 95, + "versionNonce": 1465908393, + "index": "b06", + "isDeleted": false, + "id": "MrQCqzaS", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -22.129186448831888, + "y": -496.6978457925966, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 71.89992767572403, + "height": 25, + "seed": 1051239305, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1717017095925, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Cluster", + "rawText": "Cluster", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "slrF8BjKJEuyf-8Cf7puQ", + "originalText": "Cluster", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 173, + "versionNonce": 1919003815, + "index": "b09", + "isDeleted": false, + "id": "UnHy-gJ0JMmmdzpZ3ukZi", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -56.843464850259124, + "y": -312.75319224835584, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 141.91478900700213, + "height": 95.81065730803766, + "seed": 448612969, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "w7NFe2ol" + } + ], + "updated": 1716937106999, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 132, + "versionNonce": 1929007271, + "index": "b0A", + "isDeleted": false, + "id": "w7NFe2ol", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -22.026039218828373, + "y": -277.347863594337, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 72.27993774414062, + "height": 25, + "seed": 525997385, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937106999, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Backfill", + "rawText": "Backfill", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "UnHy-gJ0JMmmdzpZ3ukZi", + "originalText": "Backfill", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 264, + "versionNonce": 556061961, + "index": "b0AV", + "isDeleted": false, + "id": "DGRfNbZqUvBlnfG8GYZ8G", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 97.16440907321396, + "y": -587.8586615525965, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 161.92444784427346, + "height": 523.3525555882508, + "seed": 1339720745, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "j-P5CxtJ1pGwubng0NvaP", + "type": "arrow" + }, + { + "id": "jYK5zu38VfhniTZ4uQb9q", + "type": "arrow" + }, + { + "id": "VYkzOS3WIRQI-juaFX9wm", + "type": "arrow" + }, + { + "id": "XgkVgs0NeDvTYpFezZgpr", + "type": "arrow" + }, + { + "id": "RMKLfzI4b_5vEjt4QmYxE", + "type": "arrow" + } + ], + "updated": 1716994014886, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 171, + "versionNonce": 1215134215, + "index": "b0B", + "isDeleted": false, + "id": "o6xeVeolrOrnimKAhT6Z8", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -55.21587724026995, + "y": -204.78445549369644, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 141.91478900700213, + "height": 95.81065730803766, + "seed": 942282505, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "xUHSpl7U" + } + ], + "updated": 1716937106999, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 139, + "versionNonce": 1490527175, + "index": "b0C", + "isDeleted": false, + "id": "xUHSpl7U", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -20.088453275385064, + "y": -181.8791268396776, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 71.65994107723236, + "height": 50, + "seed": 1522814441, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937106999, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Metrics\nSource", + "rawText": "Metrics Source", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "o6xeVeolrOrnimKAhT6Z8", + "originalText": "Metrics Source", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 249, + "versionNonce": 249800260, + "index": "b0D", + "isDeleted": false, + "id": "vc74yy-ePqJfg_43yGSY9", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 105.31153446155577, + "y": -310.56658807841995, + "strokeColor": "#2f9e44", + "backgroundColor": "#ffffff", + "width": 141.91478900700213, + "height": 95.81065730803766, + "seed": 1588897993, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "QxHV7dcR" + }, + { + "id": "XgkVgs0NeDvTYpFezZgpr", + "type": "arrow" + } + ], + "updated": 1727793683317, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 222, + "versionNonce": 2135150588, + "index": "b0E", + "isDeleted": false, + "id": "QxHV7dcR", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 118.15895291181891, + "y": -300.1612594244011, + "strokeColor": "#2f9e44", + "backgroundColor": "#ffffff", + "width": 116.21995210647583, + "height": 75, + "seed": 2107025321, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727793683317, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "RFS on ECS\nBackfill\nModel", + "rawText": "RFS on ECS Backfill Model", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "vc74yy-ePqJfg_43yGSY9", + "originalText": "RFS on ECS Backfill Model", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1038, + "versionNonce": 1601564327, + "index": "b0F", + "isDeleted": false, + "id": "M066T4UjwcZaz9n75Fwtw", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -221.2148656447198, + "y": -545.9020739382033, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 159.6771951240189, + "height": 82.98526694132079, + "seed": 831900297, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "XWtNM3xv" + }, + { + "id": "-wx3AcdaL4cU42UUETByR", + "type": "arrow" + } + ], + "updated": 1716995560785, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1025, + "versionNonce": 202439687, + "index": "b0G", + "isDeleted": false, + "id": "XWtNM3xv", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -196.8362213908158, + "y": -516.9094404675429, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 110.91990661621094, + "height": 25, + "seed": 594383209, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716995560786, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Environment", + "rawText": "Environment", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "M066T4UjwcZaz9n75Fwtw", + "originalText": "Environment", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 246, + "versionNonce": 249700295, + "index": "b0I", + "isDeleted": false, + "id": "5cio2Ikl", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -449.0792841529703, + "y": -441.1788232177382, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 155.2879180908203, + "height": 105, + "seed": 543492905, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937282609, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "Environment\n+ command\n+ args", + "rawText": "Environment\n+ command\n+ args", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Environment\n+ command\n+ args", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 34, + "versionNonce": 2120073991, + "index": "b0J", + "isDeleted": false, + "id": "iablSv0Q", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -39.901068376697594, + "y": -568.4032490430336, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 106.21991911530495, + "height": 25, + "seed": 1137425929, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937106999, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Interfaces", + "rawText": "Interfaces", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Interfaces", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 157, + "versionNonce": 1608370727, + "index": "b0L", + "isDeleted": false, + "id": "MmC7YsUc", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 108.72672088454499, + "y": -573.0359861404122, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 143.35988035798073, + "height": 25, + "seed": 1905857769, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937106999, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Implementation", + "rawText": "Implementation", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Implementation", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 278, + "versionNonce": 1671314884, + "index": "b0Q", + "isDeleted": false, + "id": "28YprHMFFqFfhepOCnSYJ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 105.69009589976918, + "y": -200.5965938426234, + "strokeColor": "#2f9e44", + "backgroundColor": "#ffffff", + "width": 141.91478900700213, + "height": 95.81065730803766, + "seed": 241296201, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "VX76m13O" + } + ], + "updated": 1727793683317, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 275, + "versionNonce": 1522561148, + "index": "b0R", + "isDeleted": false, + "id": "VX76m13O", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 122.28753434739065, + "y": -190.19126518860458, + "strokeColor": "#2f9e44", + "backgroundColor": "#ffffff", + "width": 108.71991211175919, + "height": 75, + "seed": 1756926505, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727793683317, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Cloudwatch\nMetrics\nModel", + "rawText": "Cloudwatch Metrics Model", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "28YprHMFFqFfhepOCnSYJ", + "originalText": "Cloudwatch Metrics Model", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 164, + "versionNonce": 1483791401, + "index": "b0T", + "isDeleted": false, + "id": "x3QbHQ2W89_f1Weh2Gwbe", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -185.73475673314556, + "y": 222.49826223030345, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 333.8799824221611, + "height": 271.8445337803746, + "seed": 1643568105, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "lrTOHtQJ" + } + ], + "updated": 1716937217772, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 168, + "versionNonce": 204828425, + "index": "b0U", + "isDeleted": false, + "id": "lrTOHtQJ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -74.25471883017048, + "y": 227.49826223030345, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 110.91990661621094, + "height": 25, + "seed": 1013282505, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937217772, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Environment", + "rawText": "Environment", + "textAlign": "center", + "verticalAlign": "top", + "containerId": "x3QbHQ2W89_f1Weh2Gwbe", + "originalText": "Environment", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 311, + "versionNonce": 1134863849, + "index": "b0V", + "isDeleted": false, + "id": "z9HycCiZ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -176.58465199667444, + "y": 283.4205291204919, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 315.6797802746296, + "height": 150, + "seed": 1207809449, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937217772, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "- get an empty one\n- get one based on YAML\n\nAll middleware layer functions\nget passed an Environment, plus\nargs", + "rawText": "- get an empty one\n- get one based on YAML\n\nAll middleware layer functions\nget passed an Environment, plus\nargs", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "- get an empty one\n- get one based on YAML\n\nAll middleware layer functions\nget passed an Environment, plus\nargs", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 376, + "versionNonce": 2140719081, + "index": "b0W", + "isDeleted": false, + "id": "nM9AWh8PwcvYUYTSFq6Ch", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -789.9721186066727, + "y": -167.59651288787813, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 263.1491939543717, + "height": 136.45742175982778, + "seed": 2011895945, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "CTJ9Hu4D" + }, + { + "id": "6ndSG_LPQCkJx2LppapAz", + "type": "arrow" + } + ], + "updated": 1716937209045, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 388, + "versionNonce": 1206678419, + "index": "b0X", + "isDeleted": false, + "id": "CTJ9Hu4D", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -724.8694836045845, + "y": -134.36780200796426, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 132.9439239501953, + "height": 70, + "seed": 1307123561, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727966473435, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "Additional\nFrontends", + "rawText": "Additional Frontends", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "nM9AWh8PwcvYUYTSFq6Ch", + "originalText": "Additional Frontends", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 188, + "versionNonce": 912313673, + "index": "b0Y", + "isDeleted": false, + "id": "d4jgtpkfgVlzXUyVbK1kx", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -226.55415865410816, + "y": -860.9946011558654, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 170.78322007735926, + "height": 151.46518525777208, + "seed": 1116358151, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "OKPyeCCZ" + }, + { + "id": "-wx3AcdaL4cU42UUETByR", + "type": "arrow" + } + ], + "updated": 1716995563960, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 92, + "versionNonce": 296093161, + "index": "b0Z", + "isDeleted": false, + "id": "OKPyeCCZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -202.76248605439338, + "y": -797.7620085269793, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 123.19987487792969, + "height": 25, + "seed": 1883332745, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716995563961, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "services.yaml", + "rawText": "services.yaml", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "d4jgtpkfgVlzXUyVbK1kx", + "originalText": "services.yaml", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 874, + "versionNonce": 1903127965, + "index": "b0a", + "isDeleted": false, + "id": "-wx3AcdaL4cU42UUETByR", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -146.05575883205972, + "y": -692.1072032160107, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 4.4241740051252805, + "height": 131.45083571051373, + "seed": 361896039, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727965969763, + "link": null, + "locked": false, + "startBinding": { + "elementId": "d4jgtpkfgVlzXUyVbK1kx", + "gap": 17.422212682082716, + "focus": 0.019990177277587305 + }, + "endBinding": { + "elementId": "M066T4UjwcZaz9n75Fwtw", + "gap": 14.754293567293644, + "focus": -0.13536988760719385 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -4.4241740051252805, + 131.45083571051373 + ] + ] + }, + { + "type": "arrow", + "version": 1016, + "versionNonce": 34609021, + "index": "b0b", + "isDeleted": false, + "id": "6ndSG_LPQCkJx2LppapAz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -515.291395098699, + "y": -106.17502621395657, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 269.8025850104224, + "height": 57.795245598418674, + "seed": 1294758279, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727966473486, + "link": null, + "locked": false, + "startBinding": { + "elementId": "nM9AWh8PwcvYUYTSFq6Ch", + "gap": 11.5315295536019, + "focus": 0.2473505164991294 + }, + "endBinding": { + "elementId": "hI3MSugkgDaaqg8bD2uv5", + "gap": 17.084265065257114, + "focus": -0.3401379633400158 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 269.8025850104224, + -57.795245598418674 + ] + ] + }, + { + "type": "rectangle", + "version": 210, + "versionNonce": 631972455, + "index": "b0i", + "isDeleted": false, + "id": "OA8mv5BEc3FSeAYDsxQpe", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 107.04635413669774, + "y": -532.1446693144109, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 141.91478900700213, + "height": 95.81065730803766, + "seed": 364644553, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "eAH5IuA1" + } + ], + "updated": 1716937320283, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 171, + "versionNonce": 688405895, + "index": "b0j", + "isDeleted": false, + "id": "eAH5IuA1", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 142.0537848023368, + "y": -496.73934066039203, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 71.89992767572403, + "height": 25, + "seed": 481429417, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716937320283, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Cluster", + "rawText": "Cluster", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "OA8mv5BEc3FSeAYDsxQpe", + "originalText": "Cluster", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 262, + "versionNonce": 1535437351, + "index": "b0r", + "isDeleted": false, + "id": "OfR3IfPrE1XOCw0VdVyWE", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -58.58545708321503, + "y": -422.9217562938601, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 141.91478900700213, + "height": 95.81065730803766, + "seed": 1422246407, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "74dgpIgf" + } + ], + "updated": 1716937329132, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 242, + "versionNonce": 970656009, + "index": "b0s", + "isDeleted": false, + "id": "74dgpIgf", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -19.368043515764384, + "y": -387.51642763984125, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 63.47996187210083, + "height": 25, + "seed": 1189996839, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1717016775550, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Replay", + "rawText": "Replay", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "OfR3IfPrE1XOCw0VdVyWE", + "originalText": "Replay", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 343, + "versionNonce": 68805956, + "index": "b10", + "isDeleted": false, + "id": "M8-xFoUg_fevT5yqMebnO", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 106.13847707235465, + "y": -420.80633928076884, + "strokeColor": "#2f9e44", + "backgroundColor": "#ffffff", + "width": 141.91478900700213, + "height": 95.81065730803766, + "seed": 1188576295, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "yfTbPCkI" + }, + { + "id": "RMKLfzI4b_5vEjt4QmYxE", + "type": "arrow" + } + ], + "updated": 1727793683317, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 345, + "versionNonce": 1322582268, + "index": "b11", + "isDeleted": false, + "id": "yfTbPCkI", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 120.88591230728576, + "y": -397.90101062675, + "strokeColor": "#2f9e44", + "backgroundColor": "#ffffff", + "width": 112.41991853713989, + "height": 50, + "seed": 1626087239, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727793683317, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Replayer on\nECS Model", + "rawText": "Replayer on ECS Model", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "M8-xFoUg_fevT5yqMebnO", + "originalText": "Replayer on ECS Model", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 286, + "versionNonce": 1974770884, + "index": "b19", + "isDeleted": false, + "id": "xfh94-DiNHpxZ6zp6yEgX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 474.2443605741705, + "y": -398.9116866884351, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 207.04947106193887, + "height": 136.76291228759376, + "seed": 1747896937, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "6ahQ1swk" + }, + { + "id": "RMKLfzI4b_5vEjt4QmYxE", + "type": "arrow" + } + ], + "updated": 1727793683317, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 315, + "versionNonce": 1661174140, + "index": "b1A", + "isDeleted": false, + "id": "6ahQ1swk", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 485.669171779197, + "y": -355.53023054463824, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 184.199848651886, + "height": 50, + "seed": 1117492553, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727793683317, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Replayer Container\nin Docker", + "rawText": "Replayer Container in Docker", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "xfh94-DiNHpxZ6zp6yEgX", + "originalText": "Replayer Container in Docker", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 296, + "versionNonce": 1644979268, + "index": "b1K", + "isDeleted": false, + "id": "WmTrx2DNdziyY6seg5YAZ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 466.30731897340763, + "y": -239.32612667424064, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 207.04947106193887, + "height": 136.76291228759376, + "seed": 1951819175, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "lq3Uan7s" + }, + { + "id": "XgkVgs0NeDvTYpFezZgpr", + "type": "arrow" + } + ], + "updated": 1727793683317, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 351, + "versionNonce": 1586360828, + "index": "b1L", + "isDeleted": false, + "id": "lq3Uan7s", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 512.0220929469888, + "y": -195.94467053044377, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 115.61992311477661, + "height": 50, + "seed": 1609111751, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727793683317, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "RFS Service\non ECS", + "rawText": "RFS Service\non ECS", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "WmTrx2DNdziyY6seg5YAZ", + "originalText": "RFS Service\non ECS", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 346, + "versionNonce": 251608004, + "index": "b1V", + "isDeleted": false, + "id": "tqzJqxcbGujDg5LZWcObJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 465.9671600476606, + "y": -88.23887048829181, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 207.04947106193887, + "height": 136.76291228759376, + "seed": 714853673, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "f4kZ9pKv" + }, + { + "id": "j-P5CxtJ1pGwubng0NvaP", + "type": "arrow" + } + ], + "updated": 1727793683317, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 391, + "versionNonce": 1349931644, + "index": "b1W", + "isDeleted": false, + "id": "f4kZ9pKv", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 515.1319395227505, + "y": -32.35741434449493, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 108.71991211175919, + "height": 25, + "seed": 500842505, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727793683317, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Cloudwatch", + "rawText": "Cloudwatch", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tqzJqxcbGujDg5LZWcObJ", + "originalText": "Cloudwatch", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 217, + "versionNonce": 2009707005, + "index": "b1g", + "isDeleted": false, + "id": "RMKLfzI4b_5vEjt4QmYxE", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 285.19211406775696, + "y": -359.210089498467, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 171.92261107493005, + "height": 22.78224644633997, + "seed": 2016509575, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727965969763, + "link": null, + "locked": false, + "startBinding": { + "elementId": "DGRfNbZqUvBlnfG8GYZ8G", + "gap": 26.103257150269542, + "focus": -0.17332627169500794 + }, + "endBinding": { + "elementId": "xfh94-DiNHpxZ6zp6yEgX", + "gap": 17.129635431483507, + "focus": -0.12290923001796712 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 171.92261107493005, + 22.78224644633997 + ] + ] + }, + { + "type": "arrow", + "version": 208, + "versionNonce": 1461480029, + "index": "b1h", + "isDeleted": false, + "id": "XgkVgs0NeDvTYpFezZgpr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 278.51211966807887, + "y": -244.4727417216799, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 174.44132794963673, + "height": 70.22697784608428, + "seed": 54949415, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727965969763, + "link": null, + "locked": false, + "startBinding": { + "elementId": "DGRfNbZqUvBlnfG8GYZ8G", + "gap": 19.423262750591448, + "focus": 0.140334559744473 + }, + "endBinding": { + "elementId": "WmTrx2DNdziyY6seg5YAZ", + "gap": 13.353871355692036, + "focus": -0.3975348278776473 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 174.44132794963673, + 70.22697784608428 + ] + ] + }, + { + "type": "text", + "version": 23, + "versionNonce": 1088176553, + "index": "b1j", + "isDeleted": false, + "id": "SUMtRwhC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -1.4257094510428487, + "y": -100.36425484532094, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 23.575993061065674, + "height": 35, + "seed": 272215945, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716994023206, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "...", + "rawText": "...", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "...", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 106, + "versionNonce": 526881545, + "index": "b1k", + "isDeleted": false, + "id": "8ZitKw81", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 165.9441358525794, + "y": -99.6185162089572, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 23.575993061065674, + "height": 35, + "seed": 1609358247, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716994027482, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "...", + "rawText": "...", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "...", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "theme": "light", + "viewBackgroundColor": "#ffffff", + "currentItemStrokeColor": "#2f9e44", + "currentItemBackgroundColor": "transparent", + "currentItemFillStyle": "solid", + "currentItemStrokeWidth": 2, + "currentItemStrokeStyle": "solid", + "currentItemRoughness": 1, + "currentItemOpacity": 100, + "currentItemFontFamily": 1, + "currentItemFontSize": 28, + "currentItemTextAlign": "left", + "currentItemStartArrowhead": null, + "currentItemEndArrowhead": "arrow", + "currentItemArrowType": "round", + "scrollX": 889.6686889293987, + "scrollY": 1085.5155452057438, + "zoom": { + "value": 0.560196 + }, + "currentItemRoundness": "round", + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "gridColor": { + "Bold": "rgba(217, 217, 217, 0.5)", + "Regular": "rgba(230, 230, 230, 0.5)" + }, + "currentStrokeOptions": null, + "frameRendering": { + "enabled": true, + "clip": true, + "name": true, + "outline": true + }, + "objectsSnapModeEnabled": false, + "activeTool": { + "type": "selection", + "customType": null, + "locked": false, + "lastActiveTool": null + } + }, + "prevTextMode": "parsed", + "files": {} +} \ No newline at end of file diff --git a/docs/diagrams/migration-console-library.svg b/docs/diagrams/migration-console-library.svg new file mode 100644 index 000000000..08b91043e --- /dev/null +++ b/docs/diagrams/migration-console-library.svg @@ -0,0 +1,10 @@ + + + + + + + + CLIWeb APILibrarySource Clusteron self-managed EC2Target Clusteron AmazonOpenSearch ServiceMiddlewareClusterBackfillMetricsSourceRFS on ECSBackfillModelEnvironmentEnvironment+ command+ argsInterfacesImplementationCloudwatchMetricsModelAdditionalFrontendsservices.yamlClusterReplayReplayer onECS ModelReplayer Containerin DockerRFS Serviceon ECSCloudwatch...... \ No newline at end of file diff --git a/docs/migration-console.md b/docs/migration-console.md new file mode 100644 index 000000000..0d6eee237 --- /dev/null +++ b/docs/migration-console.md @@ -0,0 +1,119 @@ +# Migration Console + +## Introduction + +**Overview** +The Migration Console serves as the control plane for orchestrating and managing the components of the Migration Assistant. It coordinates the activities of various components in the migration pipeline and provides a single point of interaction for users. The Migration Console can refer both to the ECS instance deployed in the user's account and selected VPC, and the command line application installed on that instance to interact with the Migration Assistant components. + +**Goals and Scope**: + +- Ensure centralized control and visibility into the migration process. +- Provide interfaces for managing communication between the Migration Console and other components. +- Operate statelessly with a transparent source of truth for predictable and configurable behavior. + +## System Architecture + +The Migration Console is deployed into the customer's VPC and maintains connections with most other components of the Migration Assistant. The below diagram is not comprehensive and does not illustrate any of the data flow between various other components. Additionally, it shows the deployment resulting from using the `deployment/cdk` tooling. A user may also deploy with Docker, in which case each of the ECS containers and Kafka in the diagram are actually Docker containers, the EFS volume is a shared volume, and Cloudwatch is replaced with Prometheus and Jaeger. Regardless, the Migration Console maintains contact with each of the components. + +![Migration Solution Architecture](diagrams/migration-console-arch.svg) +[Source](https://tiny.amazon.com/jmayhucf/desia2zIMi) + +### Components & their Relation to the Migration Console + +#### Deployment Environment + +In a Migration Assistant deployment on AWS, the Bootstrap Box is an EC2 instance that's used to deploy all other services and components of the solution, including the Migration Console. The Migration Console is accessed from the Bootstrap Box using the `./accessContainer` script which uses the AWS CLI `execute-command` function to start an interactive bash session on the Migration Console. This is how a user runs commands on the Migration Console. + +The Bootstrap Box doesn't exist in a open-source deployment, and instead the user generally uses their local system or another designated environment to deploy the Migration Console and other components. + +In either case, it is the responsibility of the deployment environment to populate a `migration-services.yaml` file on the Migration Console that describes the other services that are deployed. This includes the endpoints and authorization schemes of the clusters, the cluster names and service names for any ECS services, the Kafka broker endpoints, etc. + +#### Source Cluster + +The source cluster connection is optional. A customer can configure the `cdk.context.json` with source cluster details (endpoint, auth method, etc.), which are populated in the `migration-services.yaml` file. The Migration Console uses these details directly to make http requests, like `/_cat/indices`, and also passes them to other programs running on the Migration Console box, specifically `CreateSnapshot`. + +#### Target Cluster + +The target cluster is also populated in the `cdk.context.json` and the Migration Console uses the connection details to make http requests directly, as well as passing them to the `MetadataMigration` tool. Direct HTTP requests are used during an Reindex-from-Snapshot (RFS) migration to query the `.migrations_working_state` index and inform the user about the progress of the backfill. + +#### Kafka + +In a migration with replayer components deployed, the Migration Console has some utility tools to query or manipulate the Kafka cluster, to e.g. create, delete or describe topics. The Kafka broker endpoints are populated in the `migration-services.yaml` by the CDK deployment and also specify whether IAM properties should be added to the requests for AWS Managed Service Kafka. + +#### Reindex-From-Snapshot & Replayer Service + +The Reindex-From-Snapshot and Replayer services are deployed (if enabled) by the CDK scripts to ECS, in the same cluster as the Migration Console, or by the `docker-compose.yml` as Docker containers. In the AWS deployment, the Migration Console does not directly interact with either of these services. Instead, it uses the AWS API to manipulate them at the control-plane level by changing the number of desired services to disable, enable, and scale the services. + +#### Shared Logs Volume + +In an AWS deployment, the Shared Logs Volume is an EFS volume that's mounted to the Migration Console task, as well as the Replayer task (if deployed). In a Docker deployment, it's a shared volume between those containers. In both cases, logs are written to the volume from the Replayer (in the form of tuples) and processes on the Migration Console (specifically Metadata Migration). These logs can be accessed directly by the user (e.g. with shell commands `ls`, `cat`, `jq`, etc.) or, in the case of tuples, manipulated using Migration Console CLI commands. + +#### Cloudwatch Metrics + +The various services making up the Migration Assistant emit metrics and traces via an OpenTelemetry Collector to the configured metrics provider. In an AWS deployment, that's Cloudwatch & X-Ray, and in a Docker deployment it's Prometheus and Jaeger. The Migration Console contains basic functionality to query the metrics, and supports both the AWS and Docker deployment sources. + +## Library Architecture and Interface + +The Console Library is intended to be a layer that provides a unified way to access the many components involved in a migration, regardless of the specific options enabled and where they are deployed. + +It allows "frontends" (a CLI app, a Web API, etc.) to ask questions and control a migration while being insulated from the details of how to communicate with each component ("backend services"). + +The overall architecture can be seen in this diagram. Each of the subsections below discusses a component in more detail, moving from left (user) to right (deployed services). Green indicates examples, not definite implementations. + +![Library Diagram](diagrams/migration-console-library.svg) + +[source](diagrams/migration-console-library-source.excalidraw) (This is an [excalidraw](https://github.com/excalidraw/excalidraw) markdown file, not particularly human readable.) + +### Interfaces + +Currently, we have a couple of frontends that leverage the Migration Console library. The primary and most comprehensive is the command line interface (CLI), [source](https://github.com/opensearch-project/opensearch-migrations/blob/main/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/console_link/cli.py). There is also a web API that supports a small subset of commands, [source](https://github.com/opensearch-project/opensearch-migrations/tree/main/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/console_api). Additionally, the `cluster-curl` application exposes only cluster-related calls (currently [in PR here](https://github.com/opensearch-project/opensearch-migrations/pull/1046)), and the integ tests that run on the Migration Console ([source](https://github.com/opensearch-project/opensearch-migrations/tree/main/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/integ_test)) make extensive use of the console library and serve as another frontend, though in a different form-factor (i.e. not user-facing). + +We intend to support a full web API that matches the CLI by programatically generating both the API and the CLI from a spec (yet to be defined). In the short term, a subset of the functionality is exposed via a Web API. + +#### CLI + +In the near term of the Migration Assistant, the CLI is the primary way for users to manage and understand their migration. After deploying their tools, a user will log onto the Migration Console and use the CLI for tasks like starting and checking the progress of their historic backfill, turning on and off the replayer, running `_cat/indices` against the source and target cluster, etc. These functions will be performed in the same way by the user, regardless of whether their tools are deployed locally on Docker, remotely on AWS, a different hosting platform, or a combination thereof. + +#### Generation from a spec + +For the CLI and (standard) web API, the intention is that the “frontend” should be very small--essentially just the necessary code to get the user’s data from the input source (either CLI commands or http requests) into the library itself. To accomplish this, the actual endpoints in both cases could be generated from an API spec or one of them from the other. This will be a helpful way to minimize the developer effort to support additional commands and ensure that behavior is consistent between the two modalities. + +#### Custom Frontends + +As mentioned above, there are several smaller frontends that expose specific functionality (`cluster-curl`) or directly use the functionality (integ tests), leveraging the library to manage all direct communication with components, without the frontend needing to know how or where the components are deployed. These frontends install and import the library's middleware and models. In the future, these frontends could be expanded--for instance, we could write a "wizard" that walks a user step-by-step through a deployment and migration or an application to help manage multi-target performance testing. + +### Configuration & the Environment Object + +Configuration defines the services, connection details, and preferences for a migration. The "inner" parts of the library don't interact directly with any configuration files, they rely on an Environment object that contains and manages the implementation models for each involved component. The default behavior is that this Environment object is instantiated from a file at `/etc/migrations_services.yaml`. However, any frontend/user can specify a different file or can instantiate an Environment object via another strategy entirely. + +#### Configuration with a `services.yaml` file + +As discussed above and additionally in the next session, a `services.yaml` file is effectively an implementation detail and not the only way of specifying a configuration. However, in our current implementation, it is the default and most widely used way and therefore merits some discussion here. The YAML file has a fully defined spec in the [Migration Console README](https://github.com/opensearch-project/opensearch-migrations/blob/main/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/README.md#servicesyaml-spec). + +In general, there is one block in the YAML file for each object that will be instantiated, with all of the configuration details necessary to determine which model implementation should be created and used. The structure of the YAML is enforced by schemas in each model. + +#### The Environment Object + +One of the core objects used to interact with the library is an `Environment` object that contains and manages the implementation objects for each deployed service. It can be thought of as the in-code implementation of the `services.yaml` file. Each service described in the YAML will be mapped to its appropriate model, instantiated with the provided settings, and held in the Environment object. + +This Environment object will be a parameter to every command function in the middleware layer because it contains the full context of the deployed services. + +The frontend has a few options for how to interact with the Environment object. In the basic case, the frontend can ask the middleware layer to instantiate and populate the Environment. In this case, the middleware will load the YAML (from the default or a specified path), validate it, and create implementation models for each service involved. It will then return the Environment object to the frontend, and the frontend will supply it along with all command calls. + +In the "power user" case--likely to be used by the DMS API, which may not rely on a `services.yaml` file--the frontend can start with an empty Environment, and define and instantiate the underlying models itself. When that Environment is passed into the commands exposed by the middleware layer, it will be used as the source of truth for all deployed services. One option for tools taking this option would be to define a custom configuration format and include an Environment builder/factory to convert that configuration into a suitable Environment object. + +### Middleware Layer + +The middleware layer is the public-facing API of the library as a whole. As much logic as possible related to error handling, type checking, manipulating arguments, and calling functions on the underlying models should happen through the middleware layer. This allows the frontend interfaces (CLI, web API, etc.) to remain very thin and suitable for generation from a spec. + +Each call into the middleware layer should include three pieces of data: the command to be called (e.g. `backfill scale`), any arguments for it (e.g. `units=5`), and the Environment object (which in this case might include a `RFS on ECS Backfill` model). The middleware layer is responsible for calling the appropriate function on the model, validating and passing in the arguments, and handling errors during the execution, and passing the result back to the original caller. + +### Model Interfaces & Implementations + +Models contain the logic for interacting with each component of the migration. There are two subtypes here: "simple" models and those with multiple implementations. These aren't hard-and-fast distinctions. A model that currently only has one implementation may end up with additional implementations in the future. + +Models with multiple implementations have an [Abstract Base Class](https://docs.python.org/3/library/abc.html) that defines the interface for the model and sets a contract for implemented functions. Each implementation inherits from the base class. This means that the middleware layer doesn't know or care which implementation is being used because it relies on the contract of the abstract base class. + +For instance, a `Cluster` model is initialized with the endpoint and auth details for a given cluster and is responsible for using those details to make API calls to the cluster whether the user invokes a cluster command directly (e.g. `console cluster cat-indices`) or indirectly (e.g. when a user invokes `console snapshot status`, the `Snapshot` model makes a call to the `Cluster` model to check the status of the snapshot). This allows us to keep the logic to make a cluster API call exclusively in one place. Currently, we only have a single `Cluster` implementation, but in the future, perhaps a new (or very old) version of Elasticsearch or OpenSearch would need a different client and this would be encapsulated by creating a variation of the current `Cluster` model. This new version would handle the custom client without exposing that implementation detail to the middleware layer or the `Snapshot` model that asks for a given API call to be made. + +Effectively, the only component that needs to know which implementation of a model is being used is the Environment which makes the objects available to the middleware layer.