From c834c26106806a300c5d5f602cb640653b149d9a Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Thu, 18 Nov 2021 15:23:11 +0000 Subject: [PATCH 01/10] Bump next-version to 2.0 --- GitVersion.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/GitVersion.yml b/GitVersion.yml index fe060f21..1fd64b47 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -21,4 +21,8 @@ branches: - support - hotfix next-version: "1.1" - + develop: + mode: ContinuousDeployment + tag: alpha + regex: ^develop/\d\.\d$ +next-version: "2.0" From e88246840324492a9c0547ade2fbbaffb7c03bb9 Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Mon, 22 Nov 2021 12:07:39 +0000 Subject: [PATCH 02/10] Add non-MVC host support (use menes v3) (#352) --- GitVersion.yml | 1 - .../Marain.Tenancy.Cli/packages.lock.json | 202 ++++++------ .../Marain/Tenancy/Functions/Startup.cs | 2 +- .../packages.lock.json | 301 +++++++++--------- .../Marain.Tenancy.Hosting.AspNetCore.csproj | 4 +- .../TenancyServiceCollectionExtensions.cs | 61 +++- ...nancyStorageServiceCollectionExtensions.cs | 48 ++- .../Marain.Tenancy.OpenApi.Service.csproj | 2 +- .../Bindings/TenancyApiBindings.cs | 2 +- .../Marain.Tenancy.Specs/packages.lock.json | 292 ++++------------- Solutions/Marain.Tenancy.sln | 1 + 11 files changed, 414 insertions(+), 502 deletions(-) diff --git a/GitVersion.yml b/GitVersion.yml index 1fd64b47..32df2817 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -20,7 +20,6 @@ branches: - feature - support - hotfix -next-version: "1.1" develop: mode: ContinuousDeployment tag: alpha diff --git a/Solutions/Marain.Tenancy.Cli/packages.lock.json b/Solutions/Marain.Tenancy.Cli/packages.lock.json index d0f2ea75..5e2943f0 100644 --- a/Solutions/Marain.Tenancy.Cli/packages.lock.json +++ b/Solutions/Marain.Tenancy.Cli/packages.lock.json @@ -42,21 +42,21 @@ "Microsoft.Extensions.Hosting": { "type": "Direct", "requested": "[3.1.*, )", - "resolved": "3.1.20", - "contentHash": "JP+GmzY+Gqqjpm6Jp/m2xe2PrhPU/0A+AKdrqy/WvlrTF7JtYLuRCzcdXQQI11ooQ2C842IpLJf2N5jlkzl0UQ==", - "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20", - "Microsoft.Extensions.Configuration.CommandLine": "3.1.20", - "Microsoft.Extensions.Configuration.EnvironmentVariables": "3.1.20", - "Microsoft.Extensions.Configuration.UserSecrets": "3.1.20", - "Microsoft.Extensions.DependencyInjection": "3.1.20", - "Microsoft.Extensions.FileProviders.Physical": "3.1.20", - "Microsoft.Extensions.Hosting.Abstractions": "3.1.20", - "Microsoft.Extensions.Logging": "3.1.20", - "Microsoft.Extensions.Logging.Console": "3.1.20", - "Microsoft.Extensions.Logging.Debug": "3.1.20", - "Microsoft.Extensions.Logging.EventLog": "3.1.20", - "Microsoft.Extensions.Logging.EventSource": "3.1.20" + "resolved": "3.1.21", + "contentHash": "SZkklCAA1KMAo4qGMix43qUaBhjk0nfMLNcgik/GRxJ2H/W6a3woO2Q2ixlJN9XAqnJgYMMPVqGDbENguqrznw==", + "dependencies": { + "Microsoft.Extensions.Configuration": "3.1.21", + "Microsoft.Extensions.Configuration.CommandLine": "3.1.21", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "3.1.21", + "Microsoft.Extensions.Configuration.UserSecrets": "3.1.21", + "Microsoft.Extensions.DependencyInjection": "3.1.21", + "Microsoft.Extensions.FileProviders.Physical": "3.1.21", + "Microsoft.Extensions.Hosting.Abstractions": "3.1.21", + "Microsoft.Extensions.Logging": "3.1.21", + "Microsoft.Extensions.Logging.Console": "3.1.21", + "Microsoft.Extensions.Logging.Debug": "3.1.21", + "Microsoft.Extensions.Logging.EventLog": "3.1.21", + "Microsoft.Extensions.Logging.EventSource": "3.1.21" } }, "StyleCop.Analyzers": { @@ -250,200 +250,200 @@ }, "Microsoft.Extensions.Configuration": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "qN871hvjHs9pqVW1E8dXzww3hDXmAtSC0Mjvht+2choJN+KKLL/mQpX2Egkp9Wvox005bfmBrFW7svDDTjmuoQ==", + "resolved": "3.1.21", + "contentHash": "iFO6wyyv/mBr6v9wBJXG+i4baN1GOUf2ClwJilWSSE8CnWgEV2T7w4sTRmE73iS3tdHBiMMnQ2Ynyw8X78ayVw==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21" } }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "TpevBA1qF8XuuP5md8As81SHfhtAsVocH/i76F1WjYoOBpA9nwC3dmpN/YDi89efRzU6qk5AYvZ1ldCONtAYSQ==", + "resolved": "3.1.21", + "contentHash": "3Ef65E9wCkGJVPQZ7S7GtDJ8JXpCQ3c2b83XLIOINoVV7GSEjKyW/vycc3jQfdc5BIf/lnjodkDiKnjdTzXAZA==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Microsoft.Extensions.Configuration.Binder": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "eS6Q5oRKmBQKlgIjSXmgaF2jwSAuii+3UjTSN4jI2LH1N0utPNgZNtnOVXDU2tZiUOtQuAROBb8PZKgHgIgsYQ==", + "resolved": "3.1.21", + "contentHash": "gMI0aMhlJzOvqhREbENDufDaSwnxBs6COgEz+owrfFcb1J2yvBZqhN9YIayHn03JMvm8xtSmNzNL/ZCm7TWjsw==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21" } }, "Microsoft.Extensions.Configuration.CommandLine": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "Qfp9DpBuqRF4iEZ20p568fE9p1OG18hZmgMeC7A4SLsCjf+lBgF2gkl+GQYY5aqninZEqds19klmYEZF9sEogA==", + "resolved": "3.1.21", + "contentHash": "XwAttgBpOvasVPqS1XBq3+ncxwLMIZVWDOO+G8XCQhVhIu1rOByei9psFFMbU/4QBYYWuHEvsD4VvnrVrx3ffA==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21" } }, "Microsoft.Extensions.Configuration.EnvironmentVariables": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "117x0om5ZospcNDoUUwHjA/k8sEjGGE+E1R7B7hwo+ZcaWQtk8scnGWYBahKP9yzLpB11HNs3hlv23sSXToogQ==", + "resolved": "3.1.21", + "contentHash": "4nMwSpAIANpzegZxT05jO2IM30kdRtHSfJOBXI3V8fVXlhxsXBj5EEQGSOnSzzEaeBzHkjQFF4dxDHIgMuYwmQ==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21" } }, "Microsoft.Extensions.Configuration.FileExtensions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "qqfD7VfSDds340cuVggQQGlSoVuMYAtW6UIczf3UKV8CMfnP7CRc9mjlVl4R5/Jovbd5vkl56E6lg03W/ZWCtA==", + "resolved": "3.1.21", + "contentHash": "uAucC/Vq3/2duacja/sLbMKU9y2RJT9uloFT1xrl3MufDKFRAkSbIakw2Rv61XNqHCcEIHgsUiW/L7Tuz7Uomw==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20", - "Microsoft.Extensions.FileProviders.Physical": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21", + "Microsoft.Extensions.FileProviders.Physical": "3.1.21" } }, "Microsoft.Extensions.Configuration.Json": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "sNliq6gPP03/lC6dbtBv5EuMX8bnWBOsSaK6qg/TbPtZIV/i8RwxYWYW0Y+koepeLEVae3wtcUBX7sQfaCw3LQ==", + "resolved": "3.1.21", + "contentHash": "JATr/lcsjJM8R9hyylxWzR+fxteAf0xv2SBD5tpLj1qPVauuuwcgKe3swfMK/TyfP/tVHNeuLVlfBlcl6ZIhjQ==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20", - "Microsoft.Extensions.Configuration.FileExtensions": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21", + "Microsoft.Extensions.Configuration.FileExtensions": "3.1.21" } }, "Microsoft.Extensions.Configuration.UserSecrets": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "1ApvtSR35jfaWv5qdk/4opPDcCmsSiBygsAoVkI/qwIWeFY243S3HV9ZNRxS+61fDCOhlfDYm2JRvA4RRHbRXg==", + "resolved": "3.1.21", + "contentHash": "myw1iM0S+0Z1+TMbuRvAB/xLuTUVKecB08M+mCxLh3gsPsueAIXD/IA5xWhx2njKRXWhAXdayfycR6bZaY2wbg==", "dependencies": { - "Microsoft.Extensions.Configuration.Json": "3.1.20" + "Microsoft.Extensions.Configuration.Json": "3.1.21" } }, "Microsoft.Extensions.DependencyInjection": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "JAV97hx4y7qJ5mnjnUOSd+xDnMj2+51c8KVirhuU+rOW1LUnsmjhin86Tep6Q5tOHmNPOmmo6OHEFCdbZj5+zw==", + "resolved": "3.1.21", + "contentHash": "js24vxT9kzGfH7nc/EL9Yi2s5jQilFTxIYHIpX/oIEINVRW4qlnQXsfzsbXE5Y0BAG5TTidnfZ+IyOEsW9XTVA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "a2axLm7TfsB6rELiYDp7qx0S64h1FCFAFGz0WnPWgyshpvLWYM/XKwLHIPqiXuhtEp9kT4qBXRYsXMe6ZrxX0A==" + "resolved": "3.1.21", + "contentHash": "PWfBWk54+UcMYA/DqD0l/HSOlbnclR4kp6rYgI28s5zPZ8tIMetKa9+jk+cialrSbvz/+xs/JrXqy7VDiy/0dQ==" }, "Microsoft.Extensions.FileProviders.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "gR0rfQg7a1DJMlPDRii4fypu/M5tQ/0pf5mGF4jotcTCyT71wCwuONm1IruDJi+rWa4zPBPovRjdGa0Yx4Lxyg==", + "resolved": "3.1.21", + "contentHash": "52amnz03Px8X7Pw7uI6qrQPUx++Qq7MB5rhjJh+4YRq3NgUls4KqJDvOuGnnS4pRt2T8IbIrgYxRn2wMrW8Xwg==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Microsoft.Extensions.FileProviders.Physical": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "bewykuIeGb6Ro2Vq2/F1rq5jhmCsocDlgEKg2tMThsnfABXjlJbOXyjJl2GztXhtobsDpuOiWH48MM7qSONNtQ==", + "resolved": "3.1.21", + "contentHash": "w8vwWXVdFPX/hJptNybW6Nv21j3I6vOrztt3gwp0IPts+v56X9tNjR36ivx6CbEpDs2jP2kx8w8YOTYVwIuwgg==", "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "3.1.20", - "Microsoft.Extensions.FileSystemGlobbing": "3.1.20" + "Microsoft.Extensions.FileProviders.Abstractions": "3.1.21", + "Microsoft.Extensions.FileSystemGlobbing": "3.1.21" } }, "Microsoft.Extensions.FileSystemGlobbing": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "2Sz4v3iuv1ZXVxz2/SfdaDVsfbeHirmlFp2zcguyS9IHh2ZxnCzMOLjvmkf+vt/XFRQaIFIDepushHdkif4xsQ==" + "resolved": "3.1.21", + "contentHash": "Vao4dtipoDQf6jkfYql9MZWJm1U2gv5Ro4a0sMuE0K8Ze3+yRmSyNTtmZer8GLb99xAGyYa2JhfQlFobt269aA==" }, "Microsoft.Extensions.Hosting.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "c3MLwOS5rg35NfczXg/Fhce3SGVgRunfes0OTOQAAMcN57bqBRbp/HJdTK9j6FvNarataHgrU60N2EHC5jlbpg==", + "resolved": "3.1.21", + "contentHash": "0l0tDTMEkPzm/mz8J1msoqxih60pqwIEWsH0FIwGrkwEFpA3MzhL14T5j+iwg3hUawsfsxrwJVsMc9U3zo24yw==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", - "Microsoft.Extensions.FileProviders.Abstractions": "3.1.20", - "Microsoft.Extensions.Logging.Abstractions": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Microsoft.Extensions.FileProviders.Abstractions": "3.1.21", + "Microsoft.Extensions.Logging.Abstractions": "3.1.21" } }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "/CuUfjdPd0X6upL/783pzJTSGLm1XTHlonKcRYi5oGVHuN0ESHRjWwmBvrAPf8TXXL901K9oyxJ9mtG9pTmF8Q==", + "resolved": "3.1.21", + "contentHash": "5D0RMBkH4eliNeR2a3VFV4stIer/CsFTeAGo2Uv1dm2X9Ttz8n0lbc7gl8+NogTiKfGm1RqoLF0HtH/1V4wxmw==", "dependencies": { - "Microsoft.Extensions.Configuration.Binder": "3.1.20", - "Microsoft.Extensions.DependencyInjection": "3.1.20", - "Microsoft.Extensions.Logging.Abstractions": "3.1.20", - "Microsoft.Extensions.Options": "3.1.20" + "Microsoft.Extensions.Configuration.Binder": "3.1.21", + "Microsoft.Extensions.DependencyInjection": "3.1.21", + "Microsoft.Extensions.Logging.Abstractions": "3.1.21", + "Microsoft.Extensions.Options": "3.1.21" } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "pejtJ+FM3tRm9Ssy9VO1PMkxlpkwbO+iQmK/Ot9DqgW3zjeLSQg3bEPI6klU70yoRSDwpiI8E71RdzU+vn/bTQ==" + "resolved": "3.1.21", + "contentHash": "FTEjNPyjJ4eXp+dAP8YfH/MRk0LAKXhQ6FHOX9Wju7AB0/huyjG7NQGWFrnDmviPyCMzR1ZitjT/Zv27JfEsEw==" }, "Microsoft.Extensions.Logging.Configuration": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "+k33hBevAq2hZi4tHnsQwtZDXAkD79MTntOvX5ID6kMgU6piqthMLMoK5uMJAh7vec8ORMhwSIkhjYaQ7wx4gw==", + "resolved": "3.1.21", + "contentHash": "E2rKFPOPAiDdPszCN0VWOpRoqZ0gBfIXkX5K9l93ZgK4z7RyqYDD/gqpF33bc0OZTjGovgItrZ/zHawazplMrA==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.20", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.20" + "Microsoft.Extensions.Logging": "3.1.21", + "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.21" } }, "Microsoft.Extensions.Logging.Console": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "v9GpjBR3YBNSnbNj1C4hQmRofUDpya1CgQwZo3IuXbun2JbSmHs1sVxuMyEh8sdU7Bo8gGyA3zdtEwE+16oiVA==", + "resolved": "3.1.21", + "contentHash": "wLKHCHAhQxBTwwznLySdLnJEmpo/l9+LeqEOrMNkHXfDu+Cx0cVX1U/m1PV2JJonpwEqeChE311OCLF+MZv1iA==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.Logging": "3.1.20", - "Microsoft.Extensions.Logging.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.Logging": "3.1.21", + "Microsoft.Extensions.Logging.Configuration": "3.1.21" } }, "Microsoft.Extensions.Logging.Debug": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "LvxBeG8ZbCajA2jXVpLGjllDIQr4fi/7orA6IgjDypJ9vBSQTBXnGA1cbc/VmzJOT3JQUAp+5uUPA+ihhh5rsg==", + "resolved": "3.1.21", + "contentHash": "/WZhDvqehx5Ls1A7JfyNjXTpmeeTCt1LEbq1ScNgYuf8KVGypurvBKbiksGcumQ+T+izgXiLlcLWFDu3pQm+9Q==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.20" + "Microsoft.Extensions.Logging": "3.1.21" } }, "Microsoft.Extensions.Logging.EventLog": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "IuF/ldRrQbfoHPrIAWA3My7UabsKYzzd7LLgll1uhl9HgeJJIAd0C+4wV2Iekqn7ZwyZxHa1ME2xo2TFNgaJ/g==", + "resolved": "3.1.21", + "contentHash": "MDWWRs8qT2ppfiueVZhSWyJVhsgWY6Yryy2wpn5HCI78I6GKaq1g42m46mL4ftgPJQvGW+d3MAch62b9MgZCKQ==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.20", + "Microsoft.Extensions.Logging": "3.1.21", "System.Diagnostics.EventLog": "4.7.0" } }, "Microsoft.Extensions.Logging.EventSource": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "Qwv4Dc/Egp9wPidVHOszud6AAN4TU9y9ooMf6YJnVCHDoghS5eQRtF5QPAg/cJKPMSr12eKEx09a4VNjyV0Q9g==", + "resolved": "3.1.21", + "contentHash": "N290999NEj1ZgtpV4SIbYNP+dCh2wC2wFQWphFi0DGDe+4YAvMk1B6jnv7rCeqK5+sYNcg+27JLQc2tN44lthg==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.20" + "Microsoft.Extensions.Logging": "3.1.21" } }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "K5h3xUrYP8mbGZeGAm/vcWjol2wBh2V1vV+Vz02DCKlZ/99Y8ecKJwdpH+elfdqcEFXy76jk+I1nBsmhPKeCgw==", + "resolved": "3.1.21", + "contentHash": "lLI84rWombp1a6RF8VKBP9Iu4AYif5GqyxDYrkwvnMt1hagwRyJQpm6EiamFRyQYdGpEpTZNblUygYY7dEn9xg==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Microsoft.Extensions.Options.ConfigurationExtensions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "vmh27AY00NDg6+4P5NbLnhKsrNMBtfcFAoE0Pim7yNAB46ev44vu2O5a3AINUoRl9Kovik72Wgn8qA4IpQu+vg==", + "resolved": "3.1.21", + "contentHash": "8SXTqWPYOYdM0O51/cB7wzVsqFemCGMbcHb82Ix5bmsHO8stcb7YKXERiQ18JSigVogb828gCTK8gMfiSGO4ug==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.Configuration.Binder": "3.1.20", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", - "Microsoft.Extensions.Options": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.Configuration.Binder": "3.1.21", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Microsoft.Extensions.Options": "3.1.21" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "RHHWUHzW8y+dyNBIBmo2EQbpCC6xFQcFMpLhNcpzw3zP0rxJdhmTTdy5eXvhlkNi3vqM4Af5Qqb5xgYwqaoaJQ==" + "resolved": "3.1.21", + "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" }, "Microsoft.IdentityModel.Clients.ActiveDirectory": { "type": "Transitive", @@ -963,7 +963,7 @@ "System.Interactive": { "type": "Transitive", "resolved": "3.2.0", - "contentHash": "8j5PArcXRlri+zUhcSUpyFMHUWQ35ns7BNrzT3vnmTYKE90EckgFdg9N5QoR8d6eFVICludo87ue8SL+peMT2g==" + "contentHash": "hoXiC7r+WvT/oQ/QcsCgIJMEcXKXyM26BvIcFVRgEMzXk9URu8oR2ADqrnHwIRiJmxQC/q8b3KTQSkdoFRO4TA==" }, "System.IO": { "type": "Transitive", @@ -1082,7 +1082,7 @@ "System.Net.Http": { "type": "Transitive", "resolved": "4.3.4", - "contentHash": "Fj7e73NNHwof97gFPTJuq8gv6G895yxkZt14DVnZdEh4gvKl8WrksCwNjIp/JeYX/yu/qxM/iOv9ai+ZY3Fp7Q==", + "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", "dependencies": { "Microsoft.NETCore.Platforms": "1.1.1", "System.Collections": "4.3.0", diff --git a/Solutions/Marain.Tenancy.Host.Functions/Marain/Tenancy/Functions/Startup.cs b/Solutions/Marain.Tenancy.Host.Functions/Marain/Tenancy/Functions/Startup.cs index dea4b4cb..58bb3e58 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/Marain/Tenancy/Functions/Startup.cs +++ b/Solutions/Marain.Tenancy.Host.Functions/Marain/Tenancy/Functions/Startup.cs @@ -33,7 +33,7 @@ public void Configure(IWebJobsBuilder builder) services.AddSingleton(sp => sp.GetRequiredService().GetSection("TenantCloudBlobContainerFactoryOptions").Get()); - services.AddTenancyApiOnBlobStorage(this.GetRootTenantStorageConfiguration, this.ConfigureOpenApiHost); + services.AddTenancyApiOnBlobStorageWithOpenApiActionResultHosting(this.GetRootTenantStorageConfiguration, this.ConfigureOpenApiHost); } private BlobStorageConfiguration GetRootTenantStorageConfiguration(IServiceProvider serviceProvider) diff --git a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json index 75c51a14..7e729325 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json +++ b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json @@ -25,12 +25,12 @@ "Microsoft.Extensions.Logging.Console": { "type": "Direct", "requested": "[3.1.*, )", - "resolved": "3.1.20", - "contentHash": "v9GpjBR3YBNSnbNj1C4hQmRofUDpya1CgQwZo3IuXbun2JbSmHs1sVxuMyEh8sdU7Bo8gGyA3zdtEwE+16oiVA==", + "resolved": "3.1.21", + "contentHash": "wLKHCHAhQxBTwwznLySdLnJEmpo/l9+LeqEOrMNkHXfDu+Cx0cVX1U/m1PV2JJonpwEqeChE311OCLF+MZv1iA==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.Logging": "3.1.20", - "Microsoft.Extensions.Logging.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.Logging": "3.1.21", + "Microsoft.Extensions.Logging.Configuration": "3.1.21" } }, "Microsoft.NET.Sdk.Functions": { @@ -149,15 +149,15 @@ }, "Menes.Abstractions": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "uNJTJhw3gHx2NYuQUt8YV/UGtPhqzvN+Xh1QWLia0ZmUByNJ19GcDtCE4pPfabnPp2eL23NhJUN7UvhWWeUNog==", + "resolved": "3.0.0-preview.5", + "contentHash": "6gOemt+Y+DoIZTrnhlyxurjOpZevjRYyPBgP7UC3tLd28lOOtcBNYQTS8vYWr4+wF40j+0BmM4C1gYhrI3+qIg==", "dependencies": { "Corvus.ContentHandling": "2.0.4", "Corvus.Extensions": "1.1.2", "Corvus.Extensions.Newtonsoft.Json": "2.0.2", "Corvus.Monitoring.Instrumentation.Abstractions": "1.2.0", "Microsoft.CSharp": "4.7.0", - "Microsoft.Extensions.Logging": "3.1.13", + "Microsoft.Extensions.Logging": "3.1.15", "Microsoft.OpenApi.Readers": "1.2.3", "System.Interactive": "4.1.1", "System.Text.Encodings.Web": "4.7.2", @@ -166,20 +166,18 @@ }, "Menes.Hosting": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "wRXHxNfI9Bwl7Qnpz74HfZeDNFSjMHBNjXmpn7yuErxtP8ujjGxqZEOdiPPQ457N4prmShbOVPaYtQVdbaXnNw==", + "resolved": "3.0.0-preview.5", + "contentHash": "ul2Jljp/5RTBnKKjPUSLP4XJMF72jCDw0w5ra/0gVTrQ+kFOKUoxshE4MEGqXhENFzZLsYVUUbvGVNWUN7F1ew==", "dependencies": { - "Menes.Abstractions": "2.0.1" + "Menes.Abstractions": "3.0.0-preview.5" } }, "Menes.Hosting.AspNetCore": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "Zpzf8AHD7BQ7gOBe52Dw+tcZc+eh/7HLrCe9YHkw5PqjaF6SpvMfSpKowSTJLF1p5CVqQIxuNIyITl2/rYTDJQ==", + "resolved": "3.0.0-preview.5", + "contentHash": "+DJ5ggmxjsUsy0UkJDgM7YJeGDdnXQL1RCzYEDCdbDaTOfj7Rp1b0RE7bI3Z9bhphURJtY5fd/tuWQVZ5UNf3g==", "dependencies": { - "Menes.Hosting": "2.0.1", - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Mvc.Core": "2.2.5" + "Menes.Hosting": "3.0.0-preview.5" } }, "Microsoft.ApplicationInsights": { @@ -201,99 +199,99 @@ }, "Microsoft.AspNetCore.Authentication.Abstractions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "VloMLDJMf3n/9ic5lCBOa42IBYJgyB1JhzLsL68Zqg+2bEPWfGBj/xCJy/LrKTArN0coOcZp3wyVTZlx0y9pHQ==", + "resolved": "2.1.0", + "contentHash": "7hfl2DQoATexr0OVw8PwJSNqnu9gsbSkuHkwmHdss5xXCuY2nIfsTjj2NoKeGtp6N94ECioAP78FUfFOMj+TTg==", "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.Extensions.Logging.Abstractions": "2.2.0", - "Microsoft.Extensions.Options": "2.2.0" + "Microsoft.AspNetCore.Http.Abstractions": "2.1.0", + "Microsoft.Extensions.Logging.Abstractions": "2.1.0", + "Microsoft.Extensions.Options": "2.1.0" } }, "Microsoft.AspNetCore.Authentication.Core": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "XlVJzJ5wPOYW+Y0J6Q/LVTEyfS4ssLXmt60T0SPP+D8abVhBTl+cgw2gDHlyKYIkcJg7btMVh383NDkMVqD/fg==", + "resolved": "2.1.0", + "contentHash": "NKbmBzPW2zTaZLNKkCIL7LMpr4XfXVOPJ5SNzikTe2PX3juLkupb/5oTF45wiw5srUbU6QD0cY9u3jgYUELwnQ==", "dependencies": { - "Microsoft.AspNetCore.Authentication.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Http": "2.2.0", - "Microsoft.AspNetCore.Http.Extensions": "2.2.0" + "Microsoft.AspNetCore.Authentication.Abstractions": "2.1.0", + "Microsoft.AspNetCore.Http": "2.1.0", + "Microsoft.AspNetCore.Http.Extensions": "2.1.0" } }, "Microsoft.AspNetCore.Authorization": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "/L0W8H3jMYWyaeA9gBJqS/tSWBegP9aaTM0mjRhxTttBY9z4RVDRYJ2CwPAmAXIuPr3r1sOw+CS8jFVRGHRezQ==", + "resolved": "2.1.0", + "contentHash": "QUMtMVY7mQeJWlP8wmmhZf1HEGM/V8prW/XnYeKDpEniNBCRw0a3qktRb9aBU0vR+bpJwWZ0ibcB8QOvZEmDHQ==", "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "2.2.0", - "Microsoft.Extensions.Options": "2.2.0" + "Microsoft.Extensions.Logging.Abstractions": "2.1.0", + "Microsoft.Extensions.Options": "2.1.0" } }, "Microsoft.AspNetCore.Authorization.Policy": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "aJCo6niDRKuNg2uS2WMEmhJTooQUGARhV2ENQ2tO5443zVHUo19MSgrgGo9FIrfD+4yKPF8Q+FF33WkWfPbyKw==", + "resolved": "2.1.0", + "contentHash": "e/wxbmwHza+Y6hmM/xiQdsVX5Xh0cPHFbDTGR3kIK7a+jyBSc8CPAJOA5g0ziikLEp5Cm/Qux+CsWad53QoNOw==", "dependencies": { - "Microsoft.AspNetCore.Authentication.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Authorization": "2.2.0" + "Microsoft.AspNetCore.Authentication.Abstractions": "2.1.0", + "Microsoft.AspNetCore.Authorization": "2.1.0" } }, "Microsoft.AspNetCore.Hosting.Abstractions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "ubycklv+ZY7Kutdwuy1W4upWcZ6VFR8WUXU7l7B2+mvbDBBPAcfpi+E+Y5GFe+Q157YfA3C49D2GCjAZc7Mobw==", + "resolved": "2.1.0", + "contentHash": "1TQgBfd/NPZLR2o/h6l5Cml2ZCF5hsyV4h9WEwWwAIavrbdTnaNozGGcTOd4AOgQvogMM9UM1ajflm9Cwd0jLQ==", "dependencies": { - "Microsoft.AspNetCore.Hosting.Server.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.Extensions.Hosting.Abstractions": "2.2.0" + "Microsoft.AspNetCore.Hosting.Server.Abstractions": "2.1.0", + "Microsoft.AspNetCore.Http.Abstractions": "2.1.0", + "Microsoft.Extensions.Hosting.Abstractions": "2.1.0" } }, "Microsoft.AspNetCore.Hosting.Server.Abstractions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "1PMijw8RMtuQF60SsD/JlKtVfvh4NORAhF4wjysdABhlhTrYmtgssqyncR0Stq5vqtjplZcj6kbT4LRTglt9IQ==", + "resolved": "2.1.0", + "contentHash": "YTKMi2vHX6P+WHEVpW/DS+eFHnwivCSMklkyamcK1ETtc/4j8H3VR0kgW8XIBqukNxhD8k5wYt22P7PhrWSXjQ==", "dependencies": { - "Microsoft.AspNetCore.Http.Features": "2.2.0", - "Microsoft.Extensions.Configuration.Abstractions": "2.2.0" + "Microsoft.AspNetCore.Http.Features": "2.1.0", + "Microsoft.Extensions.Configuration.Abstractions": "2.1.0" } }, "Microsoft.AspNetCore.Http": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "YogBSMotWPAS/X5967pZ+yyWPQkThxhmzAwyCHCSSldzYBkW5W5d6oPfBaPqQOnSHYTpSOSOkpZoAce0vwb6+A==", + "resolved": "2.1.0", + "contentHash": "eAPryjDRH41EYY2sOMHCu+tHXLI6PUN1AsOPKst6GbiIoMi8wJCiPcE4h9418tKje1oUzmMc2Iz8fFPPVamfaw==", "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.AspNetCore.WebUtilities": "2.2.0", - "Microsoft.Extensions.ObjectPool": "2.2.0", - "Microsoft.Extensions.Options": "2.2.0", - "Microsoft.Net.Http.Headers": "2.2.0" + "Microsoft.AspNetCore.Http.Abstractions": "2.1.0", + "Microsoft.AspNetCore.WebUtilities": "2.1.0", + "Microsoft.Extensions.ObjectPool": "2.1.0", + "Microsoft.Extensions.Options": "2.1.0", + "Microsoft.Net.Http.Headers": "2.1.0" } }, "Microsoft.AspNetCore.Http.Abstractions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "Nxs7Z1q3f1STfLYKJSVXCs1iBl+Ya6E8o4Oy1bCxJ/rNI44E/0f6tbsrVqAWfB7jlnJfyaAtIalBVxPKUPQb4Q==", + "resolved": "2.1.0", + "contentHash": "vbFDyKsSYBnxl3+RABtN79b0vsTcG66fDY8vD6Nqvu9uLtSej70Q5NcbGlnN6bJpZci5orSdgFTHMhBywivDPg==", "dependencies": { - "Microsoft.AspNetCore.Http.Features": "2.2.0", + "Microsoft.AspNetCore.Http.Features": "2.1.0", "System.Text.Encodings.Web": "4.5.0" } }, "Microsoft.AspNetCore.Http.Extensions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "2DgZ9rWrJtuR7RYiew01nGRzuQBDaGHGmK56Rk54vsLLsCdzuFUPqbDTJCS1qJQWTbmbIQ9wGIOjpxA1t0l7/w==", + "resolved": "2.1.0", + "contentHash": "M8Gk5qrUu5nFV7yE3SZgATt/5B1a5Qs8ZnXXeO/Pqu68CEiBHJWc10sdGdO5guc3zOFdm7H966mVnpZtEX4vSA==", "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.Extensions.FileProviders.Abstractions": "2.2.0", - "Microsoft.Net.Http.Headers": "2.2.0", + "Microsoft.AspNetCore.Http.Abstractions": "2.1.0", + "Microsoft.Extensions.FileProviders.Abstractions": "2.1.0", + "Microsoft.Net.Http.Headers": "2.1.0", "System.Buffers": "4.5.0" } }, "Microsoft.AspNetCore.Http.Features": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "ziFz5zH8f33En4dX81LW84I6XrYXKf9jg6aM39cM+LffN9KJahViKZ61dGMSO2gd3e+qe5yBRwsesvyqlZaSMg==", + "resolved": "2.1.0", + "contentHash": "UmkUePxRjsQW0j5euFFscBwjvTu25b8+qIK/2fI3GvcqQ+mkwgbWNAT8b/Gkoei1m2bTWC07lSdutuRDPPLcJA==", "dependencies": { - "Microsoft.Extensions.Primitives": "2.2.0" + "Microsoft.Extensions.Primitives": "2.1.0" } }, "Microsoft.AspNetCore.JsonPatch": { @@ -307,33 +305,32 @@ }, "Microsoft.AspNetCore.Mvc.Abstractions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "ET6uZpfVbGR1NjCuLaLy197cQ3qZUjzl7EG5SL4GfJH/c9KRE89MMBrQegqWsh0w1iRUB/zQaK0anAjxa/pz4g==", + "resolved": "2.1.0", + "contentHash": "NhocJc6vRjxjM8opxpbjYhdN7WbsW07eT5hZOzv87bPxwEL98Hw+D+JIu9DsPm0ce7Rao1qN1BP7w8GMhRFH0Q==", "dependencies": { - "Microsoft.AspNetCore.Routing.Abstractions": "2.2.0", - "Microsoft.Net.Http.Headers": "2.2.0" + "Microsoft.AspNetCore.Routing.Abstractions": "2.1.0", + "Microsoft.Net.Http.Headers": "2.1.0" } }, "Microsoft.AspNetCore.Mvc.Core": { "type": "Transitive", - "resolved": "2.2.5", - "contentHash": "/8sr8ixIUD57UFwUntha9bOwex7/AkZfdk1f9oNJG1Ek7p/uuKVa7fuHmYZpQOf35Oxrt+2Ku4WPwMSbNxOuWg==", - "dependencies": { - "Microsoft.AspNetCore.Authentication.Core": "2.2.0", - "Microsoft.AspNetCore.Authorization.Policy": "2.2.0", - "Microsoft.AspNetCore.Hosting.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Http": "2.2.0", - "Microsoft.AspNetCore.Http.Extensions": "2.2.0", - "Microsoft.AspNetCore.Mvc.Abstractions": "2.2.0", - "Microsoft.AspNetCore.ResponseCaching.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Routing": "2.2.0", - "Microsoft.AspNetCore.Routing.Abstractions": "2.2.0", - "Microsoft.Extensions.DependencyInjection": "2.2.0", + "resolved": "2.1.0", + "contentHash": "AtNtFLtFgZglupwiRK/9ksFg1xAXyZ1otmKtsNSFn9lIwHCQd1xZHIph7GTZiXVWn51jmauIUTUMSWdpaJ+f+A==", + "dependencies": { + "Microsoft.AspNetCore.Authentication.Core": "2.1.0", + "Microsoft.AspNetCore.Authorization.Policy": "2.1.0", + "Microsoft.AspNetCore.Hosting.Abstractions": "2.1.0", + "Microsoft.AspNetCore.Http": "2.1.0", + "Microsoft.AspNetCore.Http.Extensions": "2.1.0", + "Microsoft.AspNetCore.Mvc.Abstractions": "2.1.0", + "Microsoft.AspNetCore.ResponseCaching.Abstractions": "2.1.0", + "Microsoft.AspNetCore.Routing": "2.1.0", + "Microsoft.Extensions.DependencyInjection": "2.1.0", "Microsoft.Extensions.DependencyModel": "2.1.0", - "Microsoft.Extensions.FileProviders.Abstractions": "2.2.0", - "Microsoft.Extensions.Logging.Abstractions": "2.2.0", + "Microsoft.Extensions.FileProviders.Abstractions": "2.1.0", + "Microsoft.Extensions.Logging.Abstractions": "2.1.0", "System.Diagnostics.DiagnosticSource": "4.5.0", - "System.Threading.Tasks.Extensions": "4.5.1" + "System.Threading.Tasks.Extensions": "4.5.0" } }, "Microsoft.AspNetCore.Mvc.Formatters.Json": { @@ -358,38 +355,38 @@ }, "Microsoft.AspNetCore.ResponseCaching.Abstractions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "CIHWEKrHzZfFp7t57UXsueiSA/raku56TgRYauV/W1+KAQq6vevz60zjEKaazt3BI76zwMz3B4jGWnCwd8kwQw==", + "resolved": "2.1.0", + "contentHash": "Ht/KGFWYqcUDDi+VMPkQNzY7wQ0I2SdqXMEPl6AsOW8hmO3ZS4jIPck6HGxIdlk7ftL9YITJub0cxBmnuq+6zQ==", "dependencies": { - "Microsoft.Extensions.Primitives": "2.2.0" + "Microsoft.Extensions.Primitives": "2.1.0" } }, "Microsoft.AspNetCore.Routing": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "jAhDBy0wryOnMhhZTtT9z63gJbvCzFuLm8yC6pHzuVu9ZD1dzg0ltxIwT4cfwuNkIL/TixdKsm3vpVOpG8euWQ==", + "resolved": "2.1.0", + "contentHash": "eRdsCvtUlLsh0O2Q8JfcpTUhv0m5VCYkgjZTCdniGAq7F31B3gNrBTn9VMqz14m+ZxPUzNqudfDFVTAQlrI/5Q==", "dependencies": { - "Microsoft.AspNetCore.Http.Extensions": "2.2.0", - "Microsoft.AspNetCore.Routing.Abstractions": "2.2.0", - "Microsoft.Extensions.Logging.Abstractions": "2.2.0", - "Microsoft.Extensions.ObjectPool": "2.2.0", - "Microsoft.Extensions.Options": "2.2.0" + "Microsoft.AspNetCore.Http.Extensions": "2.1.0", + "Microsoft.AspNetCore.Routing.Abstractions": "2.1.0", + "Microsoft.Extensions.Logging.Abstractions": "2.1.0", + "Microsoft.Extensions.ObjectPool": "2.1.0", + "Microsoft.Extensions.Options": "2.1.0" } }, "Microsoft.AspNetCore.Routing.Abstractions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "lRRaPN7jDlUCVCp9i0W+PB0trFaKB0bgMJD7hEJS9Uo4R9MXaMC8X2tJhPLmeVE3SGDdYI4QNKdVmhNvMJGgPQ==", + "resolved": "2.1.0", + "contentHash": "LXmnHeb3v+HTfn74M46s+4wLaMkplj1Yl2pRf+2mfDDsQ7PN0+h8AFtgip5jpvBvFHQ/Pei7S+cSVsSTHE67fQ==", "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0" + "Microsoft.AspNetCore.Http.Abstractions": "2.1.0" } }, "Microsoft.AspNetCore.WebUtilities": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "9ErxAAKaDzxXASB/b5uLEkLgUWv1QbeVxyJYEHQwMaxXOeFFVkQxiq8RyfVcifLU7NR0QY0p3acqx4ZpYfhHDg==", + "resolved": "2.1.0", + "contentHash": "xBy8JGXQ3tVSYzLl/LtN3c9EeB75khFSB2Kw2HWmF+McU0Ltva7R4JBRH0Rb4LgkcjYyyJdf+09PZalQFwsT+Q==", "dependencies": { - "Microsoft.Net.Http.Headers": "2.2.0", + "Microsoft.Net.Http.Headers": "2.1.0", "System.Text.Encodings.Web": "4.5.0" } }, @@ -618,26 +615,26 @@ }, "Microsoft.Extensions.Configuration": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "qN871hvjHs9pqVW1E8dXzww3hDXmAtSC0Mjvht+2choJN+KKLL/mQpX2Egkp9Wvox005bfmBrFW7svDDTjmuoQ==", + "resolved": "3.1.21", + "contentHash": "iFO6wyyv/mBr6v9wBJXG+i4baN1GOUf2ClwJilWSSE8CnWgEV2T7w4sTRmE73iS3tdHBiMMnQ2Ynyw8X78ayVw==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21" } }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "TpevBA1qF8XuuP5md8As81SHfhtAsVocH/i76F1WjYoOBpA9nwC3dmpN/YDi89efRzU6qk5AYvZ1ldCONtAYSQ==", + "resolved": "3.1.21", + "contentHash": "3Ef65E9wCkGJVPQZ7S7GtDJ8JXpCQ3c2b83XLIOINoVV7GSEjKyW/vycc3jQfdc5BIf/lnjodkDiKnjdTzXAZA==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Microsoft.Extensions.Configuration.Binder": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "eS6Q5oRKmBQKlgIjSXmgaF2jwSAuii+3UjTSN4jI2LH1N0utPNgZNtnOVXDU2tZiUOtQuAROBb8PZKgHgIgsYQ==", + "resolved": "3.1.21", + "contentHash": "gMI0aMhlJzOvqhREbENDufDaSwnxBs6COgEz+owrfFcb1J2yvBZqhN9YIayHn03JMvm8xtSmNzNL/ZCm7TWjsw==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21" } }, "Microsoft.Extensions.Configuration.EnvironmentVariables": { @@ -669,16 +666,16 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "JAV97hx4y7qJ5mnjnUOSd+xDnMj2+51c8KVirhuU+rOW1LUnsmjhin86Tep6Q5tOHmNPOmmo6OHEFCdbZj5+zw==", + "resolved": "3.1.21", + "contentHash": "js24vxT9kzGfH7nc/EL9Yi2s5jQilFTxIYHIpX/oIEINVRW4qlnQXsfzsbXE5Y0BAG5TTidnfZ+IyOEsW9XTVA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "a2axLm7TfsB6rELiYDp7qx0S64h1FCFAFGz0WnPWgyshpvLWYM/XKwLHIPqiXuhtEp9kT4qBXRYsXMe6ZrxX0A==" + "resolved": "3.1.21", + "contentHash": "PWfBWk54+UcMYA/DqD0l/HSOlbnclR4kp6rYgI28s5zPZ8tIMetKa9+jk+cialrSbvz/+xs/JrXqy7VDiy/0dQ==" }, "Microsoft.Extensions.DependencyModel": { "type": "Transitive", @@ -694,10 +691,10 @@ }, "Microsoft.Extensions.FileProviders.Abstractions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "EcnaSsPTqx2MGnHrmWOD0ugbuuqVT8iICqSqPzi45V5/MA1LjUNb0kwgcxBGqizV1R+WeBK7/Gw25Jzkyk9bIw==", + "resolved": "2.1.0", + "contentHash": "itv+7XBu58pxi8mykxx9cUO1OOVYe0jmQIZVSZVp5lOcLxB7sSV2bnHiI1RSu6Nxne/s6+oBla3ON5CCMSmwhQ==", "dependencies": { - "Microsoft.Extensions.Primitives": "2.2.0" + "Microsoft.Extensions.Primitives": "2.1.0" } }, "Microsoft.Extensions.FileProviders.Physical": { @@ -728,69 +725,69 @@ }, "Microsoft.Extensions.Hosting.Abstractions": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "+k4AEn68HOJat5gj1TWa6X28WlirNQO9sPIIeQbia+91n03esEtMSSoekSTpMjUzjqtJWQN3McVx0GvSPFHF/Q==", + "resolved": "2.1.0", + "contentHash": "BpMaoBxdXr5VD0yk7rYN6R8lAU9X9JbvsPveNdKT+llIn3J5s4sxpWqaSG/NnzTzTLU5eJE5nrecTl7clg/7dQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "2.2.0", - "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", - "Microsoft.Extensions.FileProviders.Abstractions": "2.2.0", - "Microsoft.Extensions.Logging.Abstractions": "2.2.0" + "Microsoft.Extensions.Configuration.Abstractions": "2.1.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.0", + "Microsoft.Extensions.FileProviders.Abstractions": "2.1.0", + "Microsoft.Extensions.Logging.Abstractions": "2.1.0" } }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "/CuUfjdPd0X6upL/783pzJTSGLm1XTHlonKcRYi5oGVHuN0ESHRjWwmBvrAPf8TXXL901K9oyxJ9mtG9pTmF8Q==", + "resolved": "3.1.21", + "contentHash": "5D0RMBkH4eliNeR2a3VFV4stIer/CsFTeAGo2Uv1dm2X9Ttz8n0lbc7gl8+NogTiKfGm1RqoLF0HtH/1V4wxmw==", "dependencies": { - "Microsoft.Extensions.Configuration.Binder": "3.1.20", - "Microsoft.Extensions.DependencyInjection": "3.1.20", - "Microsoft.Extensions.Logging.Abstractions": "3.1.20", - "Microsoft.Extensions.Options": "3.1.20" + "Microsoft.Extensions.Configuration.Binder": "3.1.21", + "Microsoft.Extensions.DependencyInjection": "3.1.21", + "Microsoft.Extensions.Logging.Abstractions": "3.1.21", + "Microsoft.Extensions.Options": "3.1.21" } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "pejtJ+FM3tRm9Ssy9VO1PMkxlpkwbO+iQmK/Ot9DqgW3zjeLSQg3bEPI6klU70yoRSDwpiI8E71RdzU+vn/bTQ==" + "resolved": "3.1.21", + "contentHash": "FTEjNPyjJ4eXp+dAP8YfH/MRk0LAKXhQ6FHOX9Wju7AB0/huyjG7NQGWFrnDmviPyCMzR1ZitjT/Zv27JfEsEw==" }, "Microsoft.Extensions.Logging.Configuration": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "+k33hBevAq2hZi4tHnsQwtZDXAkD79MTntOvX5ID6kMgU6piqthMLMoK5uMJAh7vec8ORMhwSIkhjYaQ7wx4gw==", + "resolved": "3.1.21", + "contentHash": "E2rKFPOPAiDdPszCN0VWOpRoqZ0gBfIXkX5K9l93ZgK4z7RyqYDD/gqpF33bc0OZTjGovgItrZ/zHawazplMrA==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.20", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.20" + "Microsoft.Extensions.Logging": "3.1.21", + "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.21" } }, "Microsoft.Extensions.ObjectPool": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "gA8H7uQOnM5gb+L0uTNjViHYr+hRDqCdfugheGo/MxQnuHzmhhzCBTIPm19qL1z1Xe0NEMabfcOBGv9QghlZ8g==" + "resolved": "2.1.0", + "contentHash": "tIbO45cohqexTJPXBubpwluycDT+6OWy2m7PukG37XMrtQ6Zv4AnoLrgUTaCmpWihSs5RZHKvThiAJFcBlR3AA==" }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "K5h3xUrYP8mbGZeGAm/vcWjol2wBh2V1vV+Vz02DCKlZ/99Y8ecKJwdpH+elfdqcEFXy76jk+I1nBsmhPKeCgw==", + "resolved": "3.1.21", + "contentHash": "lLI84rWombp1a6RF8VKBP9Iu4AYif5GqyxDYrkwvnMt1hagwRyJQpm6EiamFRyQYdGpEpTZNblUygYY7dEn9xg==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Microsoft.Extensions.Options.ConfigurationExtensions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "vmh27AY00NDg6+4P5NbLnhKsrNMBtfcFAoE0Pim7yNAB46ev44vu2O5a3AINUoRl9Kovik72Wgn8qA4IpQu+vg==", + "resolved": "3.1.21", + "contentHash": "8SXTqWPYOYdM0O51/cB7wzVsqFemCGMbcHb82Ix5bmsHO8stcb7YKXERiQ18JSigVogb828gCTK8gMfiSGO4ug==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.Configuration.Binder": "3.1.20", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", - "Microsoft.Extensions.Options": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.Configuration.Binder": "3.1.21", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Microsoft.Extensions.Options": "3.1.21" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "RHHWUHzW8y+dyNBIBmo2EQbpCC6xFQcFMpLhNcpzw3zP0rxJdhmTTdy5eXvhlkNi3vqM4Af5Qqb5xgYwqaoaJQ==" + "resolved": "3.1.21", + "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" }, "Microsoft.IdentityModel.Clients.ActiveDirectory": { "type": "Transitive", @@ -814,17 +811,17 @@ }, "Microsoft.Net.Http.Headers": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "iZNkjYqlo8sIOI0bQfpsSoMTmB/kyvmV2h225ihyZT33aTp48ZpF6qYnXxzSXmHt8DpBAwBTX+1s1UFLbYfZKg==", + "resolved": "2.1.0", + "contentHash": "c08F7C7BGgmjrq9cr7382pBRhcimBx24YOv4M4gtzMIuVKmxGoRr5r9A2Hke9v7Nx7zKKCysk6XpuZasZX4oeg==", "dependencies": { - "Microsoft.Extensions.Primitives": "2.2.0", + "Microsoft.Extensions.Primitives": "2.1.0", "System.Buffers": "4.5.0" } }, "Microsoft.NETCore.Platforms": { "type": "Transitive", "resolved": "2.1.2", - "contentHash": "7J7veIH7Mu6zc4llWnM7YRgTv9+Ew+JWkkDj0K7cEe8wuFA6HRt6STtwux2g+qjpDXeYeWsK0UQ3uIgRiTYHIg==" + "contentHash": "mOJy3M0UN+LUG21dLGMxaWZEP6xYpQEpLuvuEQBaownaX4YuhH6NmNUlN9si+vNkAS6dwJ//N1O4DmLf2CikVg==" }, "Microsoft.NETCore.Targets": { "type": "Transitive", @@ -1412,7 +1409,7 @@ "System.Net.Http": { "type": "Transitive", "resolved": "4.3.4", - "contentHash": "Fj7e73NNHwof97gFPTJuq8gv6G895yxkZt14DVnZdEh4gvKl8WrksCwNjIp/JeYX/yu/qxM/iOv9ai+ZY3Fp7Q==", + "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", "dependencies": { "Microsoft.NETCore.Platforms": "1.1.1", "System.Collections": "4.3.0", @@ -2250,7 +2247,7 @@ "dependencies": { "Corvus.Tenancy.Storage.Azure.Blob": "2.0.13", "Marain.Tenancy.OpenApi.Service": "1.0.0", - "Menes.Hosting.AspNetCore": "2.0.1" + "Menes.Hosting.AspNetCore": "3.0.0-preview.5" } }, "marain.tenancy.openapi.service": { diff --git a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj index f0fe2554..8c055bb0 100644 --- a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj +++ b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj @@ -2,7 +2,7 @@ - netstandard2.0;netstandard2.1 + netcoreapp3.1 @@ -18,7 +18,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyServiceCollectionExtensions.cs b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyServiceCollectionExtensions.cs index e0ad9b18..43826850 100644 --- a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyServiceCollectionExtensions.cs +++ b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyServiceCollectionExtensions.cs @@ -26,15 +26,68 @@ public static class TenancyServiceCollectionExtensions /// The service collection. /// Optional callback for additional host configuration. /// The service collection, to enable chaining. + [Obsolete("Use AddTenancyApiWithOpenApiActionResultHosting, or consider changing to AddTenancyApiWithAspNetPipelineHosting")] public static IServiceCollection AddTenancyApi( this IServiceCollection services, Action configureHost = null) + { + return AddTenancyApiWithOpenApiActionResultHosting(services, configureHost); + } + + /// + /// Add services required by the Operations Status API. + /// + /// The service collection. + /// Optional callback for additional host configuration. + /// The service collection, to enable chaining. + public static IServiceCollection AddTenancyApiWithAspNetPipelineHosting( + this IServiceCollection services, + Action configureHost = null) { if (services.Any(s => typeof(TenancyService).IsAssignableFrom(s.ServiceType))) { return services; } + services.AddEverythingExceptHosting(); + + services.AddOpenApiAspNetPipelineHosting((config) => + { + config.Documents.RegisterOpenApiServiceWithEmbeddedDefinition(); + configureHost?.Invoke(config); + }); + + return services; + } + + /// + /// Add services required by the Operations Status API. + /// + /// The service collection. + /// Optional callback for additional host configuration. + /// The service collection, to enable chaining. + public static IServiceCollection AddTenancyApiWithOpenApiActionResultHosting( + this IServiceCollection services, + Action configureHost = null) + { + if (services.Any(s => typeof(TenancyService).IsAssignableFrom(s.ServiceType))) + { + return services; + } + + services.AddEverythingExceptHosting(); + + services.AddOpenApiActionResultHosting((config) => + { + config.Documents.RegisterOpenApiServiceWithEmbeddedDefinition(); + configureHost?.Invoke(config); + }); + + return services; + } + + private static void AddEverythingExceptHosting(this IServiceCollection services) + { // This has to be done first to ensure that the HalDocumentConverter beats the ContentConverter services.AddHalDocumentMapper(); services.AddHalDocumentMapper(); @@ -57,14 +110,6 @@ public static IServiceCollection AddTenancyApi( sp => sp.GetRequiredService() .GetSection("TenantCacheConfiguration") .Get() ?? new TenantCacheConfiguration()); - - services.AddOpenApiHttpRequestHosting((config) => - { - config.Documents.RegisterOpenApiServiceWithEmbeddedDefinition(); - configureHost?.Invoke(config); - }); - - return services; } } } diff --git a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyStorageServiceCollectionExtensions.cs b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyStorageServiceCollectionExtensions.cs index e5c6c0dd..5296e265 100644 --- a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyStorageServiceCollectionExtensions.cs +++ b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyStorageServiceCollectionExtensions.cs @@ -32,7 +32,7 @@ public static IServiceCollection AddTenancyBlobContainer( } /// - /// Add the temnancy api. + /// Add the tenancy api. /// /// The service collection. /// @@ -40,14 +40,58 @@ public static IServiceCollection AddTenancyBlobContainer( /// /// The optional action to configure the host. /// The modified service collection. + [Obsolete("Use AddTenancyApiOnBlobStorageWithOpenApiActionResultHosting, or consider changing to AddTenancyApiOnBlobStorageWithAspNetPipelineHosting")] public static IServiceCollection AddTenancyApiOnBlobStorage( this IServiceCollection services, Func getRootTenantStorageConfiguration, Action configureHost = null) { - services.AddTenancyBlobContainer(getRootTenantStorageConfiguration); + AddTenancyApiOnBlobStorageCore(services, getRootTenantStorageConfiguration); services.AddTenancyApi(configureHost); return services; } + + /// + /// Add the tenancy api. + /// + /// The service collection. + /// + /// A function that will retrieve storage configuration for the root tenant. + /// + /// The optional action to configure the host. + /// The modified service collection. + public static IServiceCollection AddTenancyApiOnBlobStorageWithOpenApiActionResultHosting( + this IServiceCollection services, + Func getRootTenantStorageConfiguration, + Action configureHost = null) + { + AddTenancyApiOnBlobStorageCore(services, getRootTenantStorageConfiguration); + services.AddTenancyApiWithOpenApiActionResultHosting(configureHost); + return services; + } + + /// + /// Add the tenancy api. + /// + /// The service collection. + /// + /// A function that will retrieve storage configuration for the root tenant. + /// + /// The optional action to configure the host. + /// The modified service collection. + public static IServiceCollection AddTenancyApiOnBlobStorageWithAspNetPipelineHosting( + this IServiceCollection services, + Func getRootTenantStorageConfiguration, + Action configureHost = null) + { + AddTenancyApiOnBlobStorageCore(services, getRootTenantStorageConfiguration); + services.AddTenancyApiWithAspNetPipelineHosting(configureHost); + return services; + } + + private static void AddTenancyApiOnBlobStorageCore(IServiceCollection services, Func getRootTenantStorageConfiguration) + { + services.AddTenancyBlobContainer(getRootTenantStorageConfiguration); + } } } diff --git a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj index 318b7f57..f92b6a61 100644 --- a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj +++ b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj @@ -2,7 +2,7 @@ - netstandard2.0;netstandard2.1 + netcoreapp3.1 enable diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyApiBindings.cs b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyApiBindings.cs index 4954c719..00f6fa8b 100644 --- a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyApiBindings.cs +++ b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyApiBindings.cs @@ -36,7 +36,7 @@ public static void SetupFeature(FeatureContext featureContext) .AddJsonFile("local.settings.json", true, true) .Build(); - serviceCollection.AddTenancyApiOnBlobStorage( + serviceCollection.AddTenancyApiOnBlobStorageWithOpenApiActionResultHosting( _ => config.GetSection("RootTenantBlobStorageConfigurationOptions").Get()); }); } diff --git a/Solutions/Marain.Tenancy.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Specs/packages.lock.json index ea7f6af8..70d2c676 100644 --- a/Solutions/Marain.Tenancy.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Specs/packages.lock.json @@ -18,29 +18,29 @@ "Microsoft.Extensions.Configuration": { "type": "Direct", "requested": "[3.1.*, )", - "resolved": "3.1.20", - "contentHash": "qN871hvjHs9pqVW1E8dXzww3hDXmAtSC0Mjvht+2choJN+KKLL/mQpX2Egkp9Wvox005bfmBrFW7svDDTjmuoQ==", + "resolved": "3.1.21", + "contentHash": "iFO6wyyv/mBr6v9wBJXG+i4baN1GOUf2ClwJilWSSE8CnWgEV2T7w4sTRmE73iS3tdHBiMMnQ2Ynyw8X78ayVw==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21" } }, "Microsoft.Extensions.Configuration.EnvironmentVariables": { "type": "Direct", "requested": "[3.1.*, )", - "resolved": "3.1.20", - "contentHash": "117x0om5ZospcNDoUUwHjA/k8sEjGGE+E1R7B7hwo+ZcaWQtk8scnGWYBahKP9yzLpB11HNs3hlv23sSXToogQ==", + "resolved": "3.1.21", + "contentHash": "4nMwSpAIANpzegZxT05jO2IM30kdRtHSfJOBXI3V8fVXlhxsXBj5EEQGSOnSzzEaeBzHkjQFF4dxDHIgMuYwmQ==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21" } }, "Microsoft.Extensions.Configuration.Json": { "type": "Direct", "requested": "[3.1.*, )", - "resolved": "3.1.20", - "contentHash": "sNliq6gPP03/lC6dbtBv5EuMX8bnWBOsSaK6qg/TbPtZIV/i8RwxYWYW0Y+koepeLEVae3wtcUBX7sQfaCw3LQ==", + "resolved": "3.1.21", + "contentHash": "JATr/lcsjJM8R9hyylxWzR+fxteAf0xv2SBD5tpLj1qPVauuuwcgKe3swfMK/TyfP/tVHNeuLVlfBlcl6ZIhjQ==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20", - "Microsoft.Extensions.Configuration.FileExtensions": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21", + "Microsoft.Extensions.Configuration.FileExtensions": "3.1.21" } }, "BoDi": { @@ -241,15 +241,15 @@ }, "Menes.Abstractions": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "uNJTJhw3gHx2NYuQUt8YV/UGtPhqzvN+Xh1QWLia0ZmUByNJ19GcDtCE4pPfabnPp2eL23NhJUN7UvhWWeUNog==", + "resolved": "3.0.0-preview.5", + "contentHash": "6gOemt+Y+DoIZTrnhlyxurjOpZevjRYyPBgP7UC3tLd28lOOtcBNYQTS8vYWr4+wF40j+0BmM4C1gYhrI3+qIg==", "dependencies": { "Corvus.ContentHandling": "2.0.4", "Corvus.Extensions": "1.1.2", "Corvus.Extensions.Newtonsoft.Json": "2.0.2", "Corvus.Monitoring.Instrumentation.Abstractions": "1.2.0", "Microsoft.CSharp": "4.7.0", - "Microsoft.Extensions.Logging": "3.1.13", + "Microsoft.Extensions.Logging": "3.1.15", "Microsoft.OpenApi.Readers": "1.2.3", "System.Interactive": "4.1.1", "System.Text.Encodings.Web": "4.7.2", @@ -258,20 +258,18 @@ }, "Menes.Hosting": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "wRXHxNfI9Bwl7Qnpz74HfZeDNFSjMHBNjXmpn7yuErxtP8ujjGxqZEOdiPPQ457N4prmShbOVPaYtQVdbaXnNw==", + "resolved": "3.0.0-preview.5", + "contentHash": "ul2Jljp/5RTBnKKjPUSLP4XJMF72jCDw0w5ra/0gVTrQ+kFOKUoxshE4MEGqXhENFzZLsYVUUbvGVNWUN7F1ew==", "dependencies": { - "Menes.Abstractions": "2.0.1" + "Menes.Abstractions": "3.0.0-preview.5" } }, "Menes.Hosting.AspNetCore": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "Zpzf8AHD7BQ7gOBe52Dw+tcZc+eh/7HLrCe9YHkw5PqjaF6SpvMfSpKowSTJLF1p5CVqQIxuNIyITl2/rYTDJQ==", + "resolved": "3.0.0-preview.5", + "contentHash": "+DJ5ggmxjsUsy0UkJDgM7YJeGDdnXQL1RCzYEDCdbDaTOfj7Rp1b0RE7bI3Z9bhphURJtY5fd/tuWQVZ5UNf3g==", "dependencies": { - "Menes.Hosting": "2.0.1", - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Mvc.Core": "2.2.5" + "Menes.Hosting": "3.0.0-preview.5" } }, "Microsoft.ApplicationInsights": { @@ -291,103 +289,6 @@ "Newtonsoft.Json.Bson": "1.0.1" } }, - "Microsoft.AspNetCore.Authentication.Abstractions": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "VloMLDJMf3n/9ic5lCBOa42IBYJgyB1JhzLsL68Zqg+2bEPWfGBj/xCJy/LrKTArN0coOcZp3wyVTZlx0y9pHQ==", - "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.Extensions.Logging.Abstractions": "2.2.0", - "Microsoft.Extensions.Options": "2.2.0" - } - }, - "Microsoft.AspNetCore.Authentication.Core": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "XlVJzJ5wPOYW+Y0J6Q/LVTEyfS4ssLXmt60T0SPP+D8abVhBTl+cgw2gDHlyKYIkcJg7btMVh383NDkMVqD/fg==", - "dependencies": { - "Microsoft.AspNetCore.Authentication.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Http": "2.2.0", - "Microsoft.AspNetCore.Http.Extensions": "2.2.0" - } - }, - "Microsoft.AspNetCore.Authorization": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "/L0W8H3jMYWyaeA9gBJqS/tSWBegP9aaTM0mjRhxTttBY9z4RVDRYJ2CwPAmAXIuPr3r1sOw+CS8jFVRGHRezQ==", - "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "2.2.0", - "Microsoft.Extensions.Options": "2.2.0" - } - }, - "Microsoft.AspNetCore.Authorization.Policy": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "aJCo6niDRKuNg2uS2WMEmhJTooQUGARhV2ENQ2tO5443zVHUo19MSgrgGo9FIrfD+4yKPF8Q+FF33WkWfPbyKw==", - "dependencies": { - "Microsoft.AspNetCore.Authentication.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Authorization": "2.2.0" - } - }, - "Microsoft.AspNetCore.Hosting.Abstractions": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "ubycklv+ZY7Kutdwuy1W4upWcZ6VFR8WUXU7l7B2+mvbDBBPAcfpi+E+Y5GFe+Q157YfA3C49D2GCjAZc7Mobw==", - "dependencies": { - "Microsoft.AspNetCore.Hosting.Server.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.Extensions.Hosting.Abstractions": "2.2.0" - } - }, - "Microsoft.AspNetCore.Hosting.Server.Abstractions": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "1PMijw8RMtuQF60SsD/JlKtVfvh4NORAhF4wjysdABhlhTrYmtgssqyncR0Stq5vqtjplZcj6kbT4LRTglt9IQ==", - "dependencies": { - "Microsoft.AspNetCore.Http.Features": "2.2.0", - "Microsoft.Extensions.Configuration.Abstractions": "2.2.0" - } - }, - "Microsoft.AspNetCore.Http": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "YogBSMotWPAS/X5967pZ+yyWPQkThxhmzAwyCHCSSldzYBkW5W5d6oPfBaPqQOnSHYTpSOSOkpZoAce0vwb6+A==", - "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.AspNetCore.WebUtilities": "2.2.0", - "Microsoft.Extensions.ObjectPool": "2.2.0", - "Microsoft.Extensions.Options": "2.2.0", - "Microsoft.Net.Http.Headers": "2.2.0" - } - }, - "Microsoft.AspNetCore.Http.Abstractions": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "Nxs7Z1q3f1STfLYKJSVXCs1iBl+Ya6E8o4Oy1bCxJ/rNI44E/0f6tbsrVqAWfB7jlnJfyaAtIalBVxPKUPQb4Q==", - "dependencies": { - "Microsoft.AspNetCore.Http.Features": "2.2.0", - "System.Text.Encodings.Web": "4.5.0" - } - }, - "Microsoft.AspNetCore.Http.Extensions": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "2DgZ9rWrJtuR7RYiew01nGRzuQBDaGHGmK56Rk54vsLLsCdzuFUPqbDTJCS1qJQWTbmbIQ9wGIOjpxA1t0l7/w==", - "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", - "Microsoft.Extensions.FileProviders.Abstractions": "2.2.0", - "Microsoft.Net.Http.Headers": "2.2.0", - "System.Buffers": "4.5.0" - } - }, - "Microsoft.AspNetCore.Http.Features": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "ziFz5zH8f33En4dX81LW84I6XrYXKf9jg6aM39cM+LffN9KJahViKZ61dGMSO2gd3e+qe5yBRwsesvyqlZaSMg==", - "dependencies": { - "Microsoft.Extensions.Primitives": "2.2.0" - } - }, "Microsoft.AspNetCore.JsonPatch": { "type": "Transitive", "resolved": "2.2.0", @@ -397,65 +298,6 @@ "Newtonsoft.Json": "11.0.2" } }, - "Microsoft.AspNetCore.Mvc.Abstractions": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "ET6uZpfVbGR1NjCuLaLy197cQ3qZUjzl7EG5SL4GfJH/c9KRE89MMBrQegqWsh0w1iRUB/zQaK0anAjxa/pz4g==", - "dependencies": { - "Microsoft.AspNetCore.Routing.Abstractions": "2.2.0", - "Microsoft.Net.Http.Headers": "2.2.0" - } - }, - "Microsoft.AspNetCore.Mvc.Core": { - "type": "Transitive", - "resolved": "2.2.5", - "contentHash": "/8sr8ixIUD57UFwUntha9bOwex7/AkZfdk1f9oNJG1Ek7p/uuKVa7fuHmYZpQOf35Oxrt+2Ku4WPwMSbNxOuWg==", - "dependencies": { - "Microsoft.AspNetCore.Authentication.Core": "2.2.0", - "Microsoft.AspNetCore.Authorization.Policy": "2.2.0", - "Microsoft.AspNetCore.Hosting.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Http": "2.2.0", - "Microsoft.AspNetCore.Http.Extensions": "2.2.0", - "Microsoft.AspNetCore.Mvc.Abstractions": "2.2.0", - "Microsoft.AspNetCore.ResponseCaching.Abstractions": "2.2.0", - "Microsoft.AspNetCore.Routing": "2.2.0", - "Microsoft.AspNetCore.Routing.Abstractions": "2.2.0", - "Microsoft.Extensions.DependencyInjection": "2.2.0", - "Microsoft.Extensions.DependencyModel": "2.1.0", - "Microsoft.Extensions.FileProviders.Abstractions": "2.2.0", - "Microsoft.Extensions.Logging.Abstractions": "2.2.0", - "System.Diagnostics.DiagnosticSource": "4.5.0", - "System.Threading.Tasks.Extensions": "4.5.1" - } - }, - "Microsoft.AspNetCore.ResponseCaching.Abstractions": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "CIHWEKrHzZfFp7t57UXsueiSA/raku56TgRYauV/W1+KAQq6vevz60zjEKaazt3BI76zwMz3B4jGWnCwd8kwQw==", - "dependencies": { - "Microsoft.Extensions.Primitives": "2.2.0" - } - }, - "Microsoft.AspNetCore.Routing": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "jAhDBy0wryOnMhhZTtT9z63gJbvCzFuLm8yC6pHzuVu9ZD1dzg0ltxIwT4cfwuNkIL/TixdKsm3vpVOpG8euWQ==", - "dependencies": { - "Microsoft.AspNetCore.Http.Extensions": "2.2.0", - "Microsoft.AspNetCore.Routing.Abstractions": "2.2.0", - "Microsoft.Extensions.Logging.Abstractions": "2.2.0", - "Microsoft.Extensions.ObjectPool": "2.2.0", - "Microsoft.Extensions.Options": "2.2.0" - } - }, - "Microsoft.AspNetCore.Routing.Abstractions": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "lRRaPN7jDlUCVCp9i0W+PB0trFaKB0bgMJD7hEJS9Uo4R9MXaMC8X2tJhPLmeVE3SGDdYI4QNKdVmhNvMJGgPQ==", - "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.2.0" - } - }, "Microsoft.AspNetCore.WebUtilities": { "type": "Transitive", "resolved": "2.2.0", @@ -618,8 +460,8 @@ }, "Microsoft.DotNet.PlatformAbstractions": { "type": "Transitive", - "resolved": "2.1.0", - "contentHash": "9KPDwvb/hLEVXYruVHVZ8BkebC8j17DmPb56LnqRF74HqSPLjCkrlFUjOtFpQPA2DeADBRTI/e69aCfRBfrhxw==", + "resolved": "1.0.3", + "contentHash": "rF92Gp5L2asYrFNf0cKNBxzzGLh1krHuj6TRDk9wdjN2qdvJLaNYOn1s9oYkMlptYX436KiEFqxhLB+I5veXvQ==", "dependencies": { "System.AppContext": "4.1.0", "System.Collections": "4.0.11", @@ -651,27 +493,27 @@ }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "TpevBA1qF8XuuP5md8As81SHfhtAsVocH/i76F1WjYoOBpA9nwC3dmpN/YDi89efRzU6qk5AYvZ1ldCONtAYSQ==", + "resolved": "3.1.21", + "contentHash": "3Ef65E9wCkGJVPQZ7S7GtDJ8JXpCQ3c2b83XLIOINoVV7GSEjKyW/vycc3jQfdc5BIf/lnjodkDiKnjdTzXAZA==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Microsoft.Extensions.Configuration.Binder": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "eS6Q5oRKmBQKlgIjSXmgaF2jwSAuii+3UjTSN4jI2LH1N0utPNgZNtnOVXDU2tZiUOtQuAROBb8PZKgHgIgsYQ==", + "resolved": "3.1.21", + "contentHash": "gMI0aMhlJzOvqhREbENDufDaSwnxBs6COgEz+owrfFcb1J2yvBZqhN9YIayHn03JMvm8xtSmNzNL/ZCm7TWjsw==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21" } }, "Microsoft.Extensions.Configuration.FileExtensions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "qqfD7VfSDds340cuVggQQGlSoVuMYAtW6UIczf3UKV8CMfnP7CRc9mjlVl4R5/Jovbd5vkl56E6lg03W/ZWCtA==", + "resolved": "3.1.21", + "contentHash": "uAucC/Vq3/2duacja/sLbMKU9y2RJT9uloFT1xrl3MufDKFRAkSbIakw2Rv61XNqHCcEIHgsUiW/L7Tuz7Uomw==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.20", - "Microsoft.Extensions.FileProviders.Physical": "3.1.20" + "Microsoft.Extensions.Configuration": "3.1.21", + "Microsoft.Extensions.FileProviders.Physical": "3.1.21" } }, "Microsoft.Extensions.DependencyInjection": { @@ -684,15 +526,15 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "a2axLm7TfsB6rELiYDp7qx0S64h1FCFAFGz0WnPWgyshpvLWYM/XKwLHIPqiXuhtEp9kT4qBXRYsXMe6ZrxX0A==" + "resolved": "3.1.21", + "contentHash": "PWfBWk54+UcMYA/DqD0l/HSOlbnclR4kp6rYgI28s5zPZ8tIMetKa9+jk+cialrSbvz/+xs/JrXqy7VDiy/0dQ==" }, "Microsoft.Extensions.DependencyModel": { "type": "Transitive", - "resolved": "2.1.0", - "contentHash": "nS2XKqi+1A1umnYNLX2Fbm/XnzCxs5i+zXVJ3VC6r9t2z0NZr9FLnJN4VQpKigdcWH/iFTbMuX6M6WQJcTjVIg==", + "resolved": "1.0.3", + "contentHash": "Z3o19EnheuegmvgpCzwoSlnCWxYA6qIUhvKJ7ifKHHvU7U+oYR/gliLiL3LVYOOeGMEEzkpJ5W67sOcXizGtlw==", "dependencies": { - "Microsoft.DotNet.PlatformAbstractions": "2.1.0", + "Microsoft.DotNet.PlatformAbstractions": "1.0.3", "Newtonsoft.Json": "9.0.1", "System.Diagnostics.Debug": "4.0.11", "System.Dynamic.Runtime": "4.0.11", @@ -701,36 +543,25 @@ }, "Microsoft.Extensions.FileProviders.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "gR0rfQg7a1DJMlPDRii4fypu/M5tQ/0pf5mGF4jotcTCyT71wCwuONm1IruDJi+rWa4zPBPovRjdGa0Yx4Lxyg==", + "resolved": "3.1.21", + "contentHash": "52amnz03Px8X7Pw7uI6qrQPUx++Qq7MB5rhjJh+4YRq3NgUls4KqJDvOuGnnS4pRt2T8IbIrgYxRn2wMrW8Xwg==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Microsoft.Extensions.FileProviders.Physical": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "bewykuIeGb6Ro2Vq2/F1rq5jhmCsocDlgEKg2tMThsnfABXjlJbOXyjJl2GztXhtobsDpuOiWH48MM7qSONNtQ==", + "resolved": "3.1.21", + "contentHash": "w8vwWXVdFPX/hJptNybW6Nv21j3I6vOrztt3gwp0IPts+v56X9tNjR36ivx6CbEpDs2jP2kx8w8YOTYVwIuwgg==", "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "3.1.20", - "Microsoft.Extensions.FileSystemGlobbing": "3.1.20" + "Microsoft.Extensions.FileProviders.Abstractions": "3.1.21", + "Microsoft.Extensions.FileSystemGlobbing": "3.1.21" } }, "Microsoft.Extensions.FileSystemGlobbing": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "2Sz4v3iuv1ZXVxz2/SfdaDVsfbeHirmlFp2zcguyS9IHh2ZxnCzMOLjvmkf+vt/XFRQaIFIDepushHdkif4xsQ==" - }, - "Microsoft.Extensions.Hosting.Abstractions": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "+k4AEn68HOJat5gj1TWa6X28WlirNQO9sPIIeQbia+91n03esEtMSSoekSTpMjUzjqtJWQN3McVx0GvSPFHF/Q==", - "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "2.2.0", - "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", - "Microsoft.Extensions.FileProviders.Abstractions": "2.2.0", - "Microsoft.Extensions.Logging.Abstractions": "2.2.0" - } + "resolved": "3.1.21", + "contentHash": "Vao4dtipoDQf6jkfYql9MZWJm1U2gv5Ro4a0sMuE0K8Ze3+yRmSyNTtmZer8GLb99xAGyYa2JhfQlFobt269aA==" }, "Microsoft.Extensions.Logging": { "type": "Transitive", @@ -767,35 +598,30 @@ "Microsoft.Extensions.Logging.Configuration": "3.1.20" } }, - "Microsoft.Extensions.ObjectPool": { - "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "gA8H7uQOnM5gb+L0uTNjViHYr+hRDqCdfugheGo/MxQnuHzmhhzCBTIPm19qL1z1Xe0NEMabfcOBGv9QghlZ8g==" - }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "K5h3xUrYP8mbGZeGAm/vcWjol2wBh2V1vV+Vz02DCKlZ/99Y8ecKJwdpH+elfdqcEFXy76jk+I1nBsmhPKeCgw==", + "resolved": "3.1.21", + "contentHash": "lLI84rWombp1a6RF8VKBP9Iu4AYif5GqyxDYrkwvnMt1hagwRyJQpm6EiamFRyQYdGpEpTZNblUygYY7dEn9xg==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Microsoft.Extensions.Options.ConfigurationExtensions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "vmh27AY00NDg6+4P5NbLnhKsrNMBtfcFAoE0Pim7yNAB46ev44vu2O5a3AINUoRl9Kovik72Wgn8qA4IpQu+vg==", + "resolved": "3.1.21", + "contentHash": "8SXTqWPYOYdM0O51/cB7wzVsqFemCGMbcHb82Ix5bmsHO8stcb7YKXERiQ18JSigVogb828gCTK8gMfiSGO4ug==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.Configuration.Binder": "3.1.20", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", - "Microsoft.Extensions.Options": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.Configuration.Binder": "3.1.21", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Microsoft.Extensions.Options": "3.1.21" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "RHHWUHzW8y+dyNBIBmo2EQbpCC6xFQcFMpLhNcpzw3zP0rxJdhmTTdy5eXvhlkNi3vqM4Af5Qqb5xgYwqaoaJQ==" + "resolved": "3.1.21", + "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" }, "Microsoft.IdentityModel.Clients.ActiveDirectory": { "type": "Transitive", @@ -1579,7 +1405,7 @@ "System.Net.Http": { "type": "Transitive", "resolved": "4.3.4", - "contentHash": "Fj7e73NNHwof97gFPTJuq8gv6G895yxkZt14DVnZdEh4gvKl8WrksCwNjIp/JeYX/yu/qxM/iOv9ai+ZY3Fp7Q==", + "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", "dependencies": { "Microsoft.NETCore.Platforms": "1.1.1", "System.Collections": "4.3.0", @@ -2461,7 +2287,7 @@ "dependencies": { "Corvus.Tenancy.Storage.Azure.Blob": "2.0.13", "Marain.Tenancy.OpenApi.Service": "1.0.0", - "Menes.Hosting.AspNetCore": "2.0.1" + "Menes.Hosting.AspNetCore": "3.0.0-preview.5" } }, "marain.tenancy.openapi.service": { diff --git a/Solutions/Marain.Tenancy.sln b/Solutions/Marain.Tenancy.sln index ae0ba122..1e14a31a 100644 --- a/Solutions/Marain.Tenancy.sln +++ b/Solutions/Marain.Tenancy.sln @@ -7,6 +7,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DevOps", "DevOps", "{D29CAB ProjectSection(SolutionItems) = preProject ..\azure-pipelines.release.yml = ..\azure-pipelines.release.yml ..\azure-pipelines.yml = ..\azure-pipelines.yml + ..\GitVersion.yml = ..\GitVersion.yml EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marain.Tenancy.OpenApi.Service", "Marain.Tenancy.OpenApi.Service\Marain.Tenancy.OpenApi.Service.csproj", "{CFD86B72-E715-4C79-A5B5-A86648617581}" From dba927a86e1ae8926d154b5773c5d87b6399081e Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Wed, 1 Dec 2021 10:40:42 +0000 Subject: [PATCH 03/10] Implement tenant blob store on tenancy v3 (#355) --- .gitignore | 2 + .../Marain.Tenancy.Cli/packages.lock.json | 8 +- ...Marain.Tenancy.ClientTenantProvider.csproj | 2 +- .../Marain.Tenancy.Host.Functions.csproj | 2 + .../Marain/Tenancy/Functions/Startup.cs | 32 +- .../local.settings.template.json | 11 +- .../packages.lock.json | 1009 +++------- .../Marain.Tenancy.Hosting.AspNetCore.csproj | 1 - ...nancyStorageServiceCollectionExtensions.cs | 97 - .../Marain.Tenancy.OpenApi.Service.csproj | 2 +- .../Marain/Tenancy/OpenApi/TenancyService.cs | 7 +- .../Integration/Bindings/FunctionBindings.cs | 5 +- .../Bindings/TenancyApiBindings.cs | 44 - .../Integration/Bindings/TestTenantCleanup.cs | 56 + .../Features/TenancyApi.feature.cs | 366 ---- ...enancyClientWithCachingDisabled.feature.cs | 928 --------- ...TenancyClientWithCachingEnabled.feature.cs | 559 ------ .../Integration/Steps/TenancyApiSteps.cs | 83 +- .../Integration/Steps/TenancyClientSteps.cs | 12 +- .../Marain.Tenancy.Specs.v3.ncrunchproject | 7 + .../Marain.Tenancy.Specs/packages.lock.json | 368 +--- .../Bindings/ITenancyContainerSetup.cs | 31 + .../Bindings/ScenarioDiContainer.cs | 114 ++ .../TenancyContainerSetupDirectToStorage.cs | 148 ++ .../Bindings/TenancyContainerSetupViaApi.cs | 145 ++ .../Bindings/TenantProperties.cs | 26 + .../Bindings/TenantSetupSteps.cs | 128 ++ .../Bindings/TenantStepsBase.cs | 78 + .../Features/CreateTenant.feature | 55 + .../Features/CreateTenant.feature.multi.cs | 26 + .../Features/DeleteTenant.feature | 28 + .../Features/DeleteTenant.feature.multi.cs | 26 + .../Features/EnumerateChildTenants.feature | 38 + .../EnumerateChildTenants.feature.multi.cs | 26 + .../Features/GetTenant.feature | 57 + .../Features/GetTenant.feature.multi.cs | 26 + .../Features/ModifyTenantProperties.feature | 116 ++ .../ModifyTenantProperties.feature.multi.cs | 26 + .../Features/RenameTenant.feature | 22 + .../Features/RenameTenant.feature.multi.cs | 26 + ...ncy.Storage.Azure.BlobStorage.Specs.csproj | 72 + .../MultiMode/IMultiModeTest.cs | 18 + .../MultiMode/MultiSetupTestBase.cs | 123 ++ .../MultiMode/SetupModes.cs | 41 + .../StepDefinitions/CreateTenantSteps.cs | 130 ++ .../StepDefinitions/DeleteTenantSteps.cs | 31 + .../EnumerateChildTenantsSteps.cs | 78 + .../StepDefinitions/GetTenantSteps.cs | 151 ++ .../ModifyTenantPropertiesSteps.cs | 89 + .../StepDefinitions/RenameTenantSteps.cs | 34 + .../local.settings.template.json | 16 + .../packages.lock.json | 1776 +++++++++++++++++ .../specflow.json | 5 + .../AssemblyAttributes.cs | 7 + ...n.Tenancy.Storage.Azure.BlobStorage.csproj | 27 + .../AzureBlobStorageTenantStore.cs | 399 ++++ ...zureBlobStorageTenantStoreConfiguration.cs | 41 + ...yBlobStorageServiceCollectionExtensions.cs | 89 + Solutions/Marain.Tenancy.sln | 17 +- Solutions/Marain.Tenancy.v3.ncrunchsolution | 6 + azure-pipelines.yml | 2 +- 61 files changed, 4782 insertions(+), 3113 deletions(-) delete mode 100644 Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyStorageServiceCollectionExtensions.cs delete mode 100644 Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyApiBindings.cs create mode 100644 Solutions/Marain.Tenancy.Specs/Integration/Bindings/TestTenantCleanup.cs delete mode 100644 Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyApi.feature.cs delete mode 100644 Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyClientWithCachingDisabled.feature.cs delete mode 100644 Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyClientWithCachingEnabled.feature.cs create mode 100644 Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.v3.ncrunchproject create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/ITenancyContainerSetup.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/ScenarioDiContainer.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantProperties.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantStepsBase.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature.multi.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature.multi.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/EnumerateChildTenants.feature create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/EnumerateChildTenants.feature.multi.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/GetTenant.feature create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/GetTenant.feature.multi.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/ModifyTenantProperties.feature create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/ModifyTenantProperties.feature.multi.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature.multi.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/IMultiModeTest.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/MultiSetupTestBase.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/SetupModes.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/CreateTenantSteps.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/DeleteTenantSteps.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/EnumerateChildTenantsSteps.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/GetTenantSteps.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/ModifyTenantPropertiesSteps.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/RenameTenantSteps.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/local.settings.template.json create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/specflow.json create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/AssemblyAttributes.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStoreConfiguration.cs create mode 100644 Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Microsoft/Extensions/DependencyInjection/TenancyBlobStorageServiceCollectionExtensions.cs create mode 100644 Solutions/Marain.Tenancy.v3.ncrunchsolution diff --git a/.gitignore b/.gitignore index 72fb66e8..870ddfc7 100644 --- a/.gitignore +++ b/.gitignore @@ -339,3 +339,5 @@ local.settings.json appsettings.json **/MsDeploy + +*.feature.cs \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Cli/packages.lock.json b/Solutions/Marain.Tenancy.Cli/packages.lock.json index 5e2943f0..6be21e86 100644 --- a/Solutions/Marain.Tenancy.Cli/packages.lock.json +++ b/Solutions/Marain.Tenancy.Cli/packages.lock.json @@ -140,12 +140,12 @@ }, "Corvus.Tenancy.Abstractions": { "type": "Transitive", - "resolved": "2.0.13", - "contentHash": "uZxeWtTHYmjI580a+MnrwvgW5KLjhXbDA6o0A5Xo1xPRC3cn2xPXXvfO+ClHtJuyh2bzL8gaWjXyj85N4q5oVg==", + "resolved": "3.0.0-v3-blob.11", + "contentHash": "bRhFGCHioBAMbGxPLmfIXKYWq9Tx18gMPZ5aISVgVoRErxt9TNIOkLhQG3WkjayX22bA9zWSm9vg4qG3DIsRPg==", "dependencies": { "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Microsoft.AspNet.WebApi.Client": { @@ -1751,7 +1751,7 @@ "marain.tenancy.clienttenantprovider": { "type": "Project", "dependencies": { - "Corvus.Tenancy.Abstractions": "2.0.13", + "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", "Marain.Tenancy.Client": "1.0.0", "Microsoft.AspNetCore.WebUtilities": "2.2.0" } diff --git a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj index 102676f6..cd4bed8d 100644 --- a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj +++ b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj @@ -17,7 +17,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Solutions/Marain.Tenancy.Host.Functions/Marain.Tenancy.Host.Functions.csproj b/Solutions/Marain.Tenancy.Host.Functions/Marain.Tenancy.Host.Functions.csproj index 8da3ed5f..876bcc46 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/Marain.Tenancy.Host.Functions.csproj +++ b/Solutions/Marain.Tenancy.Host.Functions/Marain.Tenancy.Host.Functions.csproj @@ -40,12 +40,14 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/Solutions/Marain.Tenancy.Host.Functions/Marain/Tenancy/Functions/Startup.cs b/Solutions/Marain.Tenancy.Host.Functions/Marain/Tenancy/Functions/Startup.cs index 58bb3e58..6d72f948 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/Marain/Tenancy/Functions/Startup.cs +++ b/Solutions/Marain.Tenancy.Host.Functions/Marain/Tenancy/Functions/Startup.cs @@ -7,39 +7,35 @@ namespace Marain.Tenancy.ControlHost { using System; - using System.Linq; - using Corvus.Azure.Storage.Tenancy; + + using Corvus.Storage.Azure.BlobStorage; + using Menes; - using Microsoft.ApplicationInsights; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.Azure.WebJobs; - using Microsoft.Azure.WebJobs.Hosting; + + using Microsoft.Azure.Functions.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; /// /// Startup code for the Function. /// - public class Startup : IWebJobsStartup + public class Startup : FunctionsStartup { /// - public void Configure(IWebJobsBuilder builder) + public override void Configure(IFunctionsHostBuilder builder) { IServiceCollection services = builder.Services; + IConfiguration configuration = builder.GetContext().Configuration; services.AddApplicationInsightsInstrumentationTelemetry(); services.AddLogging(); - services.AddSingleton(sp => sp.GetRequiredService().GetSection("TenantCloudBlobContainerFactoryOptions").Get()); - - services.AddTenancyApiOnBlobStorageWithOpenApiActionResultHosting(this.GetRootTenantStorageConfiguration, this.ConfigureOpenApiHost); - } - - private BlobStorageConfiguration GetRootTenantStorageConfiguration(IServiceProvider serviceProvider) - { - IConfiguration config = serviceProvider.GetRequiredService(); - return config.GetSection("RootTenantBlobStorageConfigurationOptions").Get(); + BlobContainerConfiguration rootStorageConfiguration = configuration + .GetSection("RootBlobStorageConfiguration") + .Get(); + services.AddTenantStoreOnAzureBlobStorage(rootStorageConfiguration); + services.AddTenancyApiWithOpenApiActionResultHosting(this.ConfigureOpenApiHost); } private void ConfigureOpenApiHost(IOpenApiHostConfiguration config) @@ -57,4 +53,4 @@ private void ConfigureOpenApiHost(IOpenApiHostConfiguration config) config.Documents.AddSwaggerEndpoint(); } } -} +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Host.Functions/local.settings.template.json b/Solutions/Marain.Tenancy.Host.Functions/local.settings.template.json index 754a6463..fd2c79d6 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/local.settings.template.json +++ b/Solutions/Marain.Tenancy.Host.Functions/local.settings.template.json @@ -8,12 +8,13 @@ "APPINSIGHTS_INSTRUMENTATIONKEY": "", "AI:DeveloperMode": "true", - "TenantCloudBlobContainerFactoryOptions__AzureServicesAuthConnectionString": "", - "TenantCacheConfiguration__GetTenantResponseCacheControlHeaderValue": "max-age=300", - "RootTenantBlobStorageConfigurationOptions__AccountName": "", - "RootTenantBlobStorageConfigurationOptions__RootTenantBlobStorageConfiguration__KeyVaultName": "", - "RootTenantBlobStorageConfigurationOptions__RootTenantBlobStorageConfiguration__AccountKeySecretName": "" + "RootBlobStorageConfiguration__ConnectionStringPlainText": "UseDevelopmentStorage=true" + + // Or, e.g.: + //"RootBlobStorageConfiguration__AccountName": "", + //"RootBlobStorageConfiguration__AccessKeyInKeyVault__VaultName": "", + //"RootBlobStorageConfiguration__AccessKeyInKeyVault__SecretName": "" } } \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json index 7e729325..9737083f 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json +++ b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json @@ -22,6 +22,16 @@ "Microsoft.SourceLink.GitHub": "1.0.0" } }, + "Microsoft.Azure.Functions.Extensions": { + "type": "Direct", + "requested": "[1.1.0, )", + "resolved": "1.1.0", + "contentHash": "zYKtQQoS1fdzufxFApuMFiFtoi9QAGH6McXxntpylwLKgKjmCMWdgUd1dcekzTKNR9DPSDPRLiulvukqXnpWrQ==", + "dependencies": { + "Microsoft.Azure.WebJobs": "3.0.18", + "Microsoft.Extensions.DependencyInjection": "2.1.0" + } + }, "Microsoft.Extensions.Logging.Console": { "type": "Direct", "requested": "[3.1.*, )", @@ -63,18 +73,62 @@ "resolved": "1.1.118", "contentHash": "Onx6ovGSqXSK07n/0eM3ZusiNdB6cIlJdabQhWGgJp3Vooy9AaLS/tigeybOJAobqbtggTamoWndz72JscZBvw==" }, - "Corvus.Azure.Storage.Tenancy": { + "Azure.Core": { + "type": "Transitive", + "resolved": "1.19.0", + "contentHash": "lcDjG635DPE4fU5tqSueVMmzrx0QrIfPuY0+y6evHN5GanQ0GB+/4nuMHMmoNPwEow6OUPkJu4cZQxfHJQXPdA==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.0.0", + "System.Buffers": "4.5.1", + "System.Diagnostics.DiagnosticSource": "4.6.0", + "System.Memory": "4.5.4", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.4.1", + "contentHash": "yuxWej20CUtK2HUU4jm9Vft1wPw2NWKpwS9Zr0hJyph0dp7vgihlzlujR26UdhmvgdMdswsFRZL+k0HcaS07tw==", + "dependencies": { + "Azure.Core": "1.17.0", + "Microsoft.Identity.Client": "4.30.1", + "Microsoft.Identity.Client.Extensions.Msal": "2.18.4", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.5.0", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Security.KeyVault.Secrets": { + "type": "Transitive", + "resolved": "4.2.0", + "contentHash": "ujVMKVzEtVNQom5A0iEXSDovNGoSidV0RO5QlOBFfcIZlXwFnBmO5OhOfS4D/F1gbMNCCFS3re39qd/Bgh6+QQ==", + "dependencies": { + "Azure.Core": "1.15.0", + "System.Memory": "4.5.4", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Storage.Blobs": { + "type": "Transitive", + "resolved": "12.10.0", + "contentHash": "yaijs9DPfn34C/X4TX+0TAxANEhuKSrFE650gkF9g1pz/nQljv86zOOtDwNwD5UsAY5LyrOiCASGo2dhuIxvdg==", + "dependencies": { + "Azure.Storage.Common": "12.9.0", + "System.Text.Json": "4.6.0" + } + }, + "Azure.Storage.Common": { "type": "Transitive", - "resolved": "2.0.13", - "contentHash": "naqlx/mpp9OXw0DWQCUMZ93mmyLiLDdk+SSxR9iBMdZXgy/76iO331C5L1Ee24pKizqIq8tmibN35sUr9KN8KA==", + "resolved": "12.9.0", + "contentHash": "GuoigTmzz9HrCGdcdu7LyjD4pDr2XPt72LlWWTDyno+nYrjyuNwpwRFBvK/brxJvQFRHofQcBskf8vOxVxnI8g==", "dependencies": { - "Corvus.Tenancy.Abstractions": "2.0.13", - "Microsoft.Azure.Cosmos.Table": "1.0.8", - "Microsoft.Azure.KeyVault": "3.0.5", - "Microsoft.Azure.Services.AppAuthentication": "1.6.2", - "Microsoft.Azure.Storage.Blob": "11.2.3", - "Microsoft.Extensions.Logging.Abstractions": "3.1.20", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.20" + "Azure.Core": "1.19.0" } }, "Corvus.ContentHandling": { @@ -115,6 +169,22 @@ "Newtonsoft.Json": "11.0.2" } }, + "Corvus.Identity.Abstractions": { + "type": "Transitive", + "resolved": "3.0.0-identity-configuration.3", + "contentHash": "wLZih7d7jz6WoDjVHMrLzxM72GqF88g3n7JOGLpPbTbu+Q7Qekc9sSSM8PBFjVyURaQwuk/Xq/cyj3hKIFDRkQ==" + }, + "Corvus.Identity.Azure": { + "type": "Transitive", + "resolved": "3.0.0-identity-configuration.3", + "contentHash": "r3d24icyK7g07cvaiIymJxwL5S6te77sHFBFZb5XRGRqUzsLePBbccmW4G2x3zb1efvduObR0Uh32tqmiDZy8A==", + "dependencies": { + "Azure.Identity": "1.4.1", + "Azure.Security.KeyVault.Secrets": "4.2.0", + "Corvus.Identity.Abstractions": "3.0.0-identity-configuration.3", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" + } + }, "Corvus.Json.Abstractions": { "type": "Transitive", "resolved": "2.0.5", @@ -128,23 +198,42 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" } }, - "Corvus.Tenancy.Abstractions": { + "Corvus.Storage.Azure.BlobStorage": { "type": "Transitive", - "resolved": "2.0.13", - "contentHash": "uZxeWtTHYmjI580a+MnrwvgW5KLjhXbDA6o0A5Xo1xPRC3cn2xPXXvfO+ClHtJuyh2bzL8gaWjXyj85N4q5oVg==", + "resolved": "3.0.0-1-refactor-from-tenancy.10", + "contentHash": "xzy+Z5ZzpJ4GEh2MxQ4IlufXtosjwcY1Tk0Xg8SyQ2ktVHLWbly2emkEqiESFjVLUoM3sNVqd46eqflP6eXkqw==", "dependencies": { - "Corvus.ContentHandling.Json": "2.0.11", - "Corvus.Extensions": "1.1.4", - "Microsoft.Extensions.Primitives": "3.1.20" + "Azure.Storage.Blobs": "12.10.0", + "Corvus.Storage.Common": "3.0.0-1-refactor-from-tenancy.10" + } + }, + "Corvus.Storage.Azure.BlobStorage.Tenancy": { + "type": "Transitive", + "resolved": "3.0.0-make-v2config-legacy-public.3", + "contentHash": "6m+s8Ki5m7xl0tXtjUdE/1SsFlkip5/rNh3REy3tQKg8oHUO4VHbj3CjjMFBrAtQQ/wb95aHiL1az3R8pJBceA==", + "dependencies": { + "Corvus.Storage.Azure.BlobStorage": "3.0.0-1-refactor-from-tenancy.10", + "Corvus.Tenancy.Abstractions": "3.0.0-make-v2config-legacy-public.3" + } + }, + "Corvus.Storage.Common": { + "type": "Transitive", + "resolved": "3.0.0-1-refactor-from-tenancy.10", + "contentHash": "bDirPOYtbvitnSB9efYfiwfJsc/mI9ObP6qa5zAQvwzWHxUPGqY5o82AWKRk/7ADmWw26B1kzmyZGFWF4eY8jw==", + "dependencies": { + "Azure.Security.KeyVault.Secrets": "4.2.0", + "Corvus.Identity.Azure": "3.0.0-identity-configuration.3", + "Microsoft.Extensions.Configuration.Binder": "3.1.21" } }, - "Corvus.Tenancy.Storage.Azure.Blob": { + "Corvus.Tenancy.Abstractions": { "type": "Transitive", - "resolved": "2.0.13", - "contentHash": "dOiRROsPh90WZsejYWSQlIspeC9sGbpzuVFrc+GbfbFoUNvxSpxsFdD2ZNsdOWWE+gBYOIRHMMek1hL2welMTw==", + "resolved": "3.0.0-v3-blob.11", + "contentHash": "bRhFGCHioBAMbGxPLmfIXKYWq9Tx18gMPZ5aISVgVoRErxt9TNIOkLhQG3WkjayX22bA9zWSm9vg4qG3DIsRPg==", "dependencies": { - "Corvus.Azure.Storage.Tenancy": "2.0.13", - "Corvus.Tenancy.Abstractions": "2.0.13" + "Corvus.ContentHandling.Json": "2.0.11", + "Corvus.Extensions": "1.1.4", + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Menes.Abstractions": { @@ -390,110 +479,11 @@ "System.Text.Encodings.Web": "4.5.0" } }, - "Microsoft.Azure.Cosmos.Table": { - "type": "Transitive", - "resolved": "1.0.8", - "contentHash": "ToeEd1yijM7nQfLYvdFLG//RjKPmfqm45eOm86UAKrxtyGI/CXqP8iL74mzBp6mZ9A/K/ZYA2fVdpH0xHR5Keg==", - "dependencies": { - "Microsoft.Azure.DocumentDB.Core": "2.11.2", - "Microsoft.OData.Core": "7.6.4", - "Newtonsoft.Json": "10.0.2" - } - }, - "Microsoft.Azure.DocumentDB.Core": { - "type": "Transitive", - "resolved": "2.11.2", - "contentHash": "cA8eWrTFbYrkHrz095x4CUGb7wqQgA1slzFZCYexhNwz6Zcn3v+S1yvWMGwGRmRjT0MKU9tYdFWgLfT0OjSycw==", - "dependencies": { - "NETStandard.Library": "1.6.0", - "Newtonsoft.Json": "9.0.1", - "System.Collections.Immutable": "1.3.0", - "System.Collections.NonGeneric": "4.0.1", - "System.Collections.Specialized": "4.0.1", - "System.Diagnostics.TraceSource": "4.0.0", - "System.Dynamic.Runtime": "4.0.11", - "System.Linq.Queryable": "4.0.1", - "System.Net.Http": "4.3.4", - "System.Net.NameResolution": "4.0.0", - "System.Net.NetworkInformation": "4.1.0", - "System.Net.Requests": "4.0.11", - "System.Net.Security": "4.3.2", - "System.Net.WebHeaderCollection": "4.0.1", - "System.Runtime.Serialization.Primitives": "4.1.1", - "System.Security.SecureString": "4.0.0" - } - }, "Microsoft.Azure.Functions.Analyzers": { "type": "Transitive", "resolved": "1.0.0", "contentHash": "8nQq/IlK9BMBchRw3lfChSKaFNjMUOxXcPcDC3rkMd5PeWRm54nz2Owr6fZjPHMYJ36XX/9PGOfjn4jyiRojjw==" }, - "Microsoft.Azure.KeyVault": { - "type": "Transitive", - "resolved": "3.0.5", - "contentHash": "hbWw44JCJhk7e+CFeqSD1iQ2k4MP6bVVahEd9Cd1OP6JNyy0Y/S+9almtadH3vUoeDQsBAoQmzGImNoK3gxpog==", - "dependencies": { - "Microsoft.Azure.KeyVault.WebKey": "3.0.5", - "Microsoft.Rest.ClientRuntime": "[2.3.20, 3.0.0)", - "Microsoft.Rest.ClientRuntime.Azure": "[3.3.18, 4.0.0)", - "Newtonsoft.Json": "10.0.3", - "System.Net.Http": "4.3.4" - } - }, - "Microsoft.Azure.KeyVault.Core": { - "type": "Transitive", - "resolved": "2.0.4", - "contentHash": "BSdPbmZ1BvptdfgECniezEwfQLAyT11MsOm4btXdswjIm8BkLK9eX//yO8ExlafErJg1tAKpCxfNyLTHSlXJvA==", - "dependencies": { - "System.Runtime": "4.1.0", - "System.Threading.Tasks": "4.0.11" - } - }, - "Microsoft.Azure.KeyVault.WebKey": { - "type": "Transitive", - "resolved": "3.0.5", - "contentHash": "LmvQxr3qaK1rEMcsQCIz88T4LT6Mskd3mS425iXGFargt/FHS/p4lT++gBlsB3IZyU/opM7v8Yruzp13xu/I8g==", - "dependencies": { - "Microsoft.Rest.ClientRuntime": "[2.3.20, 3.0.0)", - "Microsoft.Rest.ClientRuntime.Azure": "[3.3.18, 4.0.0)", - "Newtonsoft.Json": "10.0.3", - "System.Collections": "4.3.0", - "System.Collections.Concurrent": "4.3.0", - "System.Linq": "4.3.0", - "System.Net.Http": "4.3.4", - "System.Runtime": "4.3.0", - "System.Security.Cryptography.Algorithms": "4.3.0", - "System.Security.Cryptography.Cng": "4.3.0" - } - }, - "Microsoft.Azure.Services.AppAuthentication": { - "type": "Transitive", - "resolved": "1.6.2", - "contentHash": "rSQhTv43ionr9rWvE4vxIe/i73XR5hoBYfh7UUgdaVOGW1MZeikR9RmgaJhonTylimCcCuJvrU0zXsSIFOsTGw==", - "dependencies": { - "Microsoft.IdentityModel.Clients.ActiveDirectory": "5.2.9", - "System.Diagnostics.Process": "4.3.0" - } - }, - "Microsoft.Azure.Storage.Blob": { - "type": "Transitive", - "resolved": "11.2.3", - "contentHash": "gM48FyiinUQq+fiUFHf0hGwQaTug4b+zYcYjbZ1KpxC3RkSgOd3twL9Yv9MqpvTkMcexGLwtELYIBhaTQ3zd9A==", - "dependencies": { - "Microsoft.Azure.Storage.Common": "11.2.3", - "NETStandard.Library": "2.0.1" - } - }, - "Microsoft.Azure.Storage.Common": { - "type": "Transitive", - "resolved": "11.2.3", - "contentHash": "WqX0ckhXQSUIBEq6wd2xgFz3KPjIONfDdgNg1ClQYxYTvuXQv3g3cnL9DGXCvuxEFZNPk0BJdQeW+uZwGqdDjw==", - "dependencies": { - "Microsoft.Azure.KeyVault.Core": "2.0.4", - "NETStandard.Library": "2.0.1", - "Newtonsoft.Json": "10.0.2" - } - }, "Microsoft.Azure.WebJobs": { "type": "Transitive", "resolved": "3.0.23", @@ -561,6 +551,11 @@ "System.Runtime.Loader": "4.3.0" } }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "K63Y4hORbBcKLWH5wnKgzyn7TOfYzevIEwIedQHBIkmkEBA9SCqgvom+XTuE+fAFGvINGkhFItaZ2dvMGdT5iw==" + }, "Microsoft.Build.Tasks.Git": { "type": "Transitive", "resolved": "1.0.0", @@ -789,24 +784,18 @@ "resolved": "3.1.21", "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" }, - "Microsoft.IdentityModel.Clients.ActiveDirectory": { + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.30.1", + "contentHash": "xk8tJeGfB2yD3+d7a0DXyV7/HYyEG10IofUHYHoPYKmDbroi/j9t1BqSHgbq1nARDjg7m8Ki6e21AyNU7e/R4Q==" + }, + "Microsoft.Identity.Client.Extensions.Msal": { "type": "Transitive", - "resolved": "5.2.9", - "contentHash": "WhBAG/9hWiMHIXve4ZgwXP3spRwf7kFFfejf76QA5BvumgnPp8iDkDCiJugzAcpW1YaHB526z1UVxHhVT1E5qw==", + "resolved": "2.18.4", + "contentHash": "HpG4oLwhQsy0ce7OWq9iDdLtJKOvKRStIKoSEOeBMKuohfuOWNDyhg8fMAJkpG/kFeoe4J329fiMHcJmmB+FPw==", "dependencies": { - "Microsoft.CSharp": "4.3.0", - "NETStandard.Library": "1.6.1", - "System.ComponentModel.TypeConverter": "4.3.0", - "System.Dynamic.Runtime": "4.3.0", - "System.Net.Http": "4.3.4", - "System.Private.Uri": "4.3.2", - "System.Runtime.Serialization.Formatters": "4.3.0", - "System.Runtime.Serialization.Json": "4.3.0", - "System.Runtime.Serialization.Primitives": "4.3.0", - "System.Security.Cryptography.X509Certificates": "4.3.0", - "System.Security.SecureString": "4.3.0", - "System.Xml.XDocument": "4.3.0", - "System.Xml.XmlDocument": "4.3.0" + "Microsoft.Identity.Client": "4.30.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" } }, "Microsoft.Net.Http.Headers": { @@ -825,46 +814,14 @@ }, "Microsoft.NETCore.Targets": { "type": "Transitive", - "resolved": "1.1.3", - "contentHash": "3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==" - }, - "Microsoft.OData.Core": { - "type": "Transitive", - "resolved": "7.6.4", - "contentHash": "/EjnJezMBjXf8OjcShhGzPY7pOO0CopgoZGhS6xsP3t2uhC+O72IBHgtQ7F3v1rRXWVtJwLGhzE1GfJUlx3c4Q==", - "dependencies": { - "Microsoft.OData.Edm": "[7.6.4]", - "Microsoft.Spatial": "[7.6.4]" - } - }, - "Microsoft.OData.Edm": { - "type": "Transitive", - "resolved": "7.6.4", - "contentHash": "MSSmA6kIfpgFTtNpOnnayoSj/6KSzHC1U9KOjF7cTA1PG4tZ7rIMi1pvjFc8CmYEvP4cxGl/+vrCn+HpK26HTQ==" + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" }, "Microsoft.OpenApi": { "type": "Transitive", "resolved": "1.2.3", "contentHash": "Nug3rO+7Kl5/SBAadzSMAVgqDlfGjJZ0GenQrLywJ84XGKO0uRqkunz5Wyl0SDwcR71bAATXvSdbdzPrYRYKGw==" }, - "Microsoft.Rest.ClientRuntime": { - "type": "Transitive", - "resolved": "2.3.20", - "contentHash": "bw/H1nO4JdnhTagPHWIFQwtlQ6rb2jqw5RTrqPsPqzrjhJxc7P6MyNGdf4pgHQdzdpBSNOfZTEQifoUkxmzYXQ==", - "dependencies": { - "Newtonsoft.Json": "10.0.3" - } - }, - "Microsoft.Rest.ClientRuntime.Azure": { - "type": "Transitive", - "resolved": "3.3.18", - "contentHash": "pCtem10PRQYvzRiwJVInsccsqB0NrTjW83NF3zWk1LpN3IS0AneZKq89RyogDT7mRMT1Li/mLY8N8kU6RAiK0g==", - "dependencies": { - "Microsoft.Rest.ClientRuntime": "[2.3.17, 3.0.0)", - "NETStandard.Library": "1.6.1", - "Newtonsoft.Json": "10.0.3" - } - }, "Microsoft.SourceLink.Common": { "type": "Transitive", "resolved": "1.0.0", @@ -879,11 +836,6 @@ "Microsoft.SourceLink.Common": "1.0.0" } }, - "Microsoft.Spatial": { - "type": "Transitive", - "resolved": "7.6.4", - "contentHash": "3mB+Frn4LU4yb5ie9R752QiRn0Hvp9PITkSRofV/Lzm9EyLM87Fy9ziqgz75O/c712dh6GxuypMSBUGmNFwMeA==" - }, "Microsoft.Win32.Primitives": { "type": "Transitive", "resolved": "4.3.0", @@ -894,21 +846,6 @@ "System.Runtime": "4.3.0" } }, - "Microsoft.Win32.Registry": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Lw1/VwLH1yxz6SfFEjVRCN0pnflLEsWgnV4qsdJ512/HhTwnKXUG+zDQ4yTO3K/EJQemGoNaBHX5InISNKTzUQ==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "System.Collections": "4.3.0", - "System.Globalization": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Runtime.Handles": "4.3.0", - "System.Runtime.InteropServices": "4.3.0" - } - }, "ncrontab.signed": { "type": "Transitive", "resolved": "3.3.0", @@ -924,10 +861,53 @@ }, "NETStandard.Library": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "oA6nwv9MhEKYvLpjZ0ggSpb1g4CQViDVQjLUcDWg598jtvJbpfeP2reqwI1GLW2TbxC/Ml7xL6BBR1HmKPXlTg==", + "resolved": "1.6.1", + "contentHash": "WcSp3+vP+yHNgS8EV5J7pZ9IRpeDuARBPN28by8zqff1wJQXm26PVU8L3/fYLBJVU7BtDyqNVWq2KlCVvSSR4A==", "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0" + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.Win32.Primitives": "4.3.0", + "System.AppContext": "4.3.0", + "System.Collections": "4.3.0", + "System.Collections.Concurrent": "4.3.0", + "System.Console": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tools": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Calendars": "4.3.0", + "System.IO": "4.3.0", + "System.IO.Compression": "4.3.0", + "System.IO.Compression.ZipFile": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Linq": "4.3.0", + "System.Linq.Expressions": "4.3.0", + "System.Net.Http": "4.3.0", + "System.Net.Primitives": "4.3.0", + "System.Net.Sockets": "4.3.0", + "System.ObjectModel": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Security.Cryptography.X509Certificates": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encoding.Extensions": "4.3.0", + "System.Text.RegularExpressions": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "System.Threading.Timer": "4.3.0", + "System.Xml.ReaderWriter": "4.3.0", + "System.Xml.XDocument": "4.3.0" } }, "Newtonsoft.Json": { @@ -946,18 +926,18 @@ }, "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "7VSGO0URRKoMEAq0Sc9cRz8mb6zbyx/BZDEWhgPdzzpmFhkam3fJ1DAGWFXBI4nGlma+uPKpfuMQP5LXRnOH5g==" + "resolved": "4.3.0", + "contentHash": "HdSSp5MnJSsg08KMfZThpuLPJpPwE5hBXvHwoKWosyHHfe8Mh5WKT0ylEOf6yNzX6Ngjxe4Whkafh5q7Ymac4Q==" }, "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "0oAaTAm6e2oVH+/Zttt0cuhGaePQYKII1dY8iaqP7CvOpVKgLybKRFvQjXR2LtxXOXTVPNv14j0ot8uV+HrUmw==" + "resolved": "4.3.0", + "contentHash": "+yH1a49wJMy8Zt4yx5RhJrxO/DBDByAiCzNwiETI+1S4mPdCu0OY4djdciC7Vssk0l22wQaDLrXxXkp+3+7bVA==" }, "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "G24ibsCNi5Kbz0oXWynBoRgtGvsw5ZSVEWjv13/KiCAM8C6wz9zzcCniMeQFIkJ2tasjo2kXlvlBZhplL51kGg==" + "resolved": "4.3.0", + "contentHash": "c3YNH1GQJbfIPJeCnr4avseugSqPrxwIqzthYyZDN6EuOyNOzq+y2KSUfRcXauya1sF4foESTgwM5e1A8arAKw==" }, "runtime.native.System": { "type": "Transitive", @@ -968,19 +948,19 @@ "Microsoft.NETCore.Targets": "1.1.0" } }, - "runtime.native.System.Net.Http": { + "runtime.native.System.IO.Compression": { "type": "Transitive", "resolved": "4.3.0", - "contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==", + "contentHash": "INBPonS5QPEgn7naufQFXJEp3zX6L4bwHgJ/ZH78aBTpeNfQMtf7C6VrAFhlq2xxWBveIOWyFzQjJ8XzHMhdOQ==", "dependencies": { "Microsoft.NETCore.Platforms": "1.1.0", "Microsoft.NETCore.Targets": "1.1.0" } }, - "runtime.native.System.Net.Security": { + "runtime.native.System.Net.Http": { "type": "Transitive", "resolved": "4.3.0", - "contentHash": "M2nN92ePS8BgQ2oi6Jj3PlTUzadYSIWLdZrHY1n1ZcW9o4wAQQ6W+aQ2lfq1ysZQfVCgDwY58alUdowrzezztg==", + "contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==", "dependencies": { "Microsoft.NETCore.Platforms": "1.1.0", "Microsoft.NETCore.Targets": "1.1.0" @@ -996,30 +976,30 @@ }, "runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "QR1OwtwehHxSeQvZKXe+iSd+d3XZNkEcuWMFYa2i0aG1l+lR739HPicKMlTbJst3spmeekDVBUS7SeS26s4U/g==", + "resolved": "4.3.0", + "contentHash": "NS1U+700m4KFRHR5o4vo9DSlTmlCKu/u7dtE5sUHVIPB+xpXxYQvgBgA6wEIeCz6Yfn0Z52/72WYsToCEPJnrw==", "dependencies": { - "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2" + "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" } }, "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "I+GNKGg2xCHueRd1m9PzeEW7WLbNNLznmTuEi8/vZX71HudUbx1UTwlGkiwMri7JLl8hGaIAWnA/GONhu+LOyQ==" + "resolved": "4.3.0", + "contentHash": "b3pthNgxxFcD+Pc0WSEoC0+md3MyhRS6aCEeenvNE3Fdw1HyJ18ZhRFVJJzIeR/O/jpxPboB805Ho0T3Ul7w8A==" }, "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "1Z3TAq1ytS1IBRtPXJvEUZdVsfWfeNEhBkbiOCGEl9wwAfsjP2lz3ZFDx5tq8p60/EqbS0HItG5piHuB71RjoA==" + "resolved": "4.3.0", + "contentHash": "KeLz4HClKf+nFS7p/6Fi/CqyLXh81FpiGzcmuS8DGi9lUqSnZ6Es23/gv2O+1XVGfrbNmviF7CckBpavkBoIFQ==" }, "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": { "type": "Transitive", @@ -1028,28 +1008,28 @@ }, "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "6mU/cVmmHtQiDXhnzUImxIcDL48GbTk+TsptXyJA+MIOG9LRjPoAQC/qBFB7X+UNyK86bmvGwC8t+M66wsYC8w==" + "resolved": "4.3.0", + "contentHash": "X7IdhILzr4ROXd8mI1BUCQMSHSQwelUlBjF1JyTKCjXaOGn2fB4EKBxQbCK2VjO3WaWIdlXZL3W6TiIVnrhX4g==" }, "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "vjwG0GGcTW/PPg6KVud8F9GLWYuAV1rrw1BKAqY0oh4jcUqg15oYF1+qkGR2x2ZHM4DQnWKQ7cJgYbfncz/lYg==" + "resolved": "4.3.0", + "contentHash": "nyFNiCk/r+VOiIqreLix8yN+q3Wga9+SE8BCgkf+2BwEKiNx6DyvFjCgkfV743/grxv8jHJ8gUK4XEQw7yzRYg==" }, "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "7KMFpTkHC/zoExs+PwP8jDCWcrK9H6L7soowT80CUx3e+nxP/AFnq0AQAW5W76z2WYbLAYCRyPfwYFG6zkvQRw==" + "resolved": "4.3.0", + "contentHash": "ytoewC6wGorL7KoCAvRfsgoJPJbNq+64k2SqW6JcOAebWsFUvCCYgfzQMrnpvPiEl4OrblUlhF2ji+Q1+SVLrQ==" }, "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "xrlmRCnKZJLHxyyLIqkZjNXqgxnKdZxfItrPkjI+6pkRo5lHX8YvSZlWrSI5AVwLMi4HbNWP7064hcAWeZKp5w==" + "resolved": "4.3.0", + "contentHash": "I8bKw2I8k58Wx7fMKQJn2R8lamboCAiHfHeV/pS65ScKWMMI0+wJkLYlEKvgW1D/XvSl/221clBoR2q9QNNM7A==" }, "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "leXiwfiIkW7Gmn7cgnNcdtNAU70SjmKW3jxGj1iKHOvdn0zRWsgv/l2OJUO5zdGdiv2VRFnAsxxhDgMzofPdWg==" + "resolved": "4.3.0", + "contentHash": "VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg==" }, "SharpYaml": { "type": "Transitive", @@ -1061,16 +1041,16 @@ }, "System.AppContext": { "type": "Transitive", - "resolved": "4.1.0", - "contentHash": "3QjO4jNV7PdKkmQAVp9atA+usVnKRwI3Kx1nMwJ93T0LcQfx7pKAYk0nKz5wn1oP5iqlhZuy6RXOFdhr7rDwow==", + "resolved": "4.3.0", + "contentHash": "fKC+rmaLfeIzUhagxY17Q9siv/sPrjjKcfNg1Ic8IlQkZLipo8ljcaZQu4VtI4Jqbzjc2VTjzGLF6WmsRXAEgA==", "dependencies": { - "System.Runtime": "4.1.0" + "System.Runtime": "4.3.0" } }, "System.Buffers": { "type": "Transitive", - "resolved": "4.5.0", - "contentHash": "pL2ChpaRRWI/p4LXyy4RgeWlYF2sgfj/pnVMvBqwNFr5cXg7CXNnWZWxrOONLg8VGdFB8oB+EG2Qw4MLgTOe+A==" + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" }, "System.Collections": { "type": "Transitive", @@ -1104,76 +1084,21 @@ "resolved": "5.0.0", "contentHash": "FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==" }, - "System.Collections.NonGeneric": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "prtjIEMhGUnQq6RnPEYLpFt8AtLbp9yq2zxOSrY7KJJZrw25Fi97IzBqY7iqssbM61Ek5b8f3MG/sG1N2sN5KA==", - "dependencies": { - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Threading": "4.3.0" - } - }, - "System.Collections.Specialized": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Epx8PoVZR0iuOnJJDzp7pWvdfMMOAvpUo95pC4ScH2mJuXkKA2Y4aR3cG9qt2klHgSons1WFh4kcGW7cSXvrxg==", - "dependencies": { - "System.Collections.NonGeneric": "4.3.0", - "System.Globalization": "4.3.0", - "System.Globalization.Extensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Threading": "4.3.0" - } - }, - "System.ComponentModel": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "VyGn1jGRZVfxnh8EdvDCi71v3bMXrsu8aYJOwoV7SNDLVhiEqwP86pPMyRGsDsxhXAm2b3o9OIqeETfN5qfezw==", - "dependencies": { - "System.Runtime": "4.3.0" - } - }, "System.ComponentModel.Annotations": { "type": "Transitive", "resolved": "4.4.0", "contentHash": "29K3DQ+IGU7LBaMjTo7SI7T7X/tsMtLvz1p56LJ556Iu0Dw3pKZw5g8yCYCWMRxrOF0Hr0FU0FwW0o42y2sb3A==" }, - "System.ComponentModel.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "j8GUkCpM8V4d4vhLIIoBLGey2Z5bCkMVNjEZseyAlm4n5arcsJOeI3zkUP+zvZgzsbLTYh4lYeP/ZD/gdIAPrw==", - "dependencies": { - "System.ComponentModel": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0" - } - }, - "System.ComponentModel.TypeConverter": { + "System.Console": { "type": "Transitive", "resolved": "4.3.0", - "contentHash": "16pQ6P+EdhcXzPiEK4kbA953Fu0MNG2ovxTZU81/qsCd1zPRsKc3uif5NgvllCY598k6bI0KUyKW8fanlfaDQg==", + "contentHash": "DHDrIxiqk1h03m6khKWV2X8p/uvN79rgSqpilL6uzpmSfxfU5ng8VcPtW4qsDsQDHiTv6IPV9TmD5M/vElPNLg==", "dependencies": { - "System.Collections": "4.3.0", - "System.Collections.NonGeneric": "4.3.0", - "System.Collections.Specialized": "4.3.0", - "System.ComponentModel": "4.3.0", - "System.ComponentModel.Primitives": "4.3.0", - "System.Globalization": "4.3.0", - "System.Linq": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Extensions": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Threading": "4.3.0" + "System.Text.Encoding": "4.3.0" } }, "System.Diagnostics.Debug": { @@ -1191,34 +1116,6 @@ "resolved": "5.0.0", "contentHash": "tCQTzPsGZh/A9LhhA6zrqCRV4hOHsK90/G7q3Khxmn6tnB1PuNU0cRaKANP2AWcF9bn0zsuOoZOSrHuJk6oNBA==" }, - "System.Diagnostics.Process": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "J0wOX07+QASQblsfxmIMFc9Iq7KTXYL3zs2G/Xc704Ylv3NpuVdo6gij6V3PGiptTxqsK0K7CdXenRvKUnkA2g==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.Win32.Primitives": "4.3.0", - "Microsoft.Win32.Registry": "4.3.0", - "System.Collections": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.IO.FileSystem": "4.3.0", - "System.IO.FileSystem.Primitives": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Runtime.Handles": "4.3.0", - "System.Runtime.InteropServices": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Text.Encoding.Extensions": "4.3.0", - "System.Threading": "4.3.0", - "System.Threading.Tasks": "4.3.0", - "System.Threading.Thread": "4.3.0", - "System.Threading.ThreadPool": "4.3.0", - "runtime.native.System": "4.3.0" - } - }, "System.Diagnostics.Tools": { "type": "Transitive", "resolved": "4.3.0", @@ -1257,23 +1154,24 @@ }, "System.Dynamic.Runtime": { "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "SNVi1E/vfWUAs/WYKhE9+qlS6KqK0YVhnlT0HQtr8pMIA8YX3lwy3uPMownDwdYISBdmAF/2holEIldVp85Wag==", + "resolved": "4.0.11", + "contentHash": "db34f6LHYM0U0JpE+sOmjar27BnqTVkbLJhgfwMpTdgTigG/Hna3m2MYVwnFzGGKnEJk2UXFuoVTr8WUbU91/A==", "dependencies": { - "System.Collections": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Linq": "4.3.0", - "System.Linq.Expressions": "4.3.0", - "System.ObjectModel": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Emit": "4.3.0", - "System.Reflection.Emit.ILGeneration": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Threading": "4.3.0" + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Globalization": "4.0.11", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Emit": "4.0.1", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Threading": "4.0.11" } }, "System.Globalization": { @@ -1327,6 +1225,44 @@ "System.Threading.Tasks": "4.3.0" } }, + "System.IO.Compression": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Buffers": "4.3.0", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "runtime.native.System": "4.3.0", + "runtime.native.System.IO.Compression": "4.3.0" + } + }, + "System.IO.Compression.ZipFile": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "G4HwjEsgIwy3JFBduZ9quBkAu+eUwjIdJleuNSgmUojbH6O3mlvEIme+GHx/cLlTAPcrnnL7GqvB9pTlWRfhOg==", + "dependencies": { + "System.Buffers": "4.3.0", + "System.IO": "4.3.0", + "System.IO.Compression": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Text.Encoding": "4.3.0" + } + }, "System.IO.FileSystem": { "type": "Transitive", "resolved": "4.3.0", @@ -1386,32 +1322,26 @@ "System.Threading": "4.3.0" } }, - "System.Linq.Queryable": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "Yn/WfYe9RoRfmSLvUt2JerP0BTGGykCZkQPgojaxgzF2N0oPo+/AhB8TXOpdCcNlrG3VRtsamtK2uzsp3cqRVw==", - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Linq": "4.1.0", - "System.Linq.Expressions": "4.1.0", - "System.Reflection": "4.1.0", - "System.Reflection.Extensions": "4.0.1", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0" - } - }, "System.Memory": { "type": "Transitive", "resolved": "4.5.4", "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, "System.Net.Http": { "type": "Transitive", - "resolved": "4.3.4", - "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", + "resolved": "4.3.0", + "contentHash": "sYg+FtILtRQuYWSIAuNOELwVuVsxVyJGWQyOnlAzhV4xvhyFnON1bAzYYC+jjRW8JREM45R0R5Dgi8MTC5sEwA==", "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Platforms": "1.1.0", "System.Collections": "4.3.0", "System.Diagnostics.Debug": "4.3.0", "System.Diagnostics.DiagnosticSource": "4.3.0", @@ -1436,58 +1366,7 @@ "System.Threading.Tasks": "4.3.0", "runtime.native.System": "4.3.0", "runtime.native.System.Net.Http": "4.3.0", - "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2" - } - }, - "System.Net.NameResolution": { - "type": "Transitive", - "resolved": "4.0.0", - "contentHash": "JdqRdM1Qym3YehqdKIi5LHrpypP4JMfxKQSNCJ2z4WawkG0il+N3XfNeJOxll2XrTnG7WgYYPoeiu/KOwg0DQw==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "System.Collections": "4.0.11", - "System.Diagnostics.Tracing": "4.1.0", - "System.Globalization": "4.0.11", - "System.Net.Primitives": "4.0.11", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.Handles": "4.0.1", - "System.Runtime.InteropServices": "4.1.0", - "System.Security.Principal.Windows": "4.0.0", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "runtime.native.System": "4.0.0" - } - }, - "System.Net.NetworkInformation": { - "type": "Transitive", - "resolved": "4.1.0", - "contentHash": "Q0rfeiW6QsiZuicGjrFA7cRr2+kXex0JIljTTxzI09GIftB8k+aNL31VsQD1sI2g31cw7UGDTgozA/FgeNSzsQ==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "Microsoft.Win32.Primitives": "4.0.1", - "System.Collections": "4.0.11", - "System.Diagnostics.Tracing": "4.1.0", - "System.Globalization": "4.0.11", - "System.IO": "4.1.0", - "System.IO.FileSystem": "4.0.1", - "System.IO.FileSystem.Primitives": "4.0.1", - "System.Linq": "4.1.0", - "System.Net.Primitives": "4.0.11", - "System.Net.Sockets": "4.1.0", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.Handles": "4.0.1", - "System.Runtime.InteropServices": "4.1.0", - "System.Security.Principal.Windows": "4.0.0", - "System.Threading": "4.0.11", - "System.Threading.Overlapped": "4.0.1", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Thread": "4.0.0", - "System.Threading.ThreadPool": "4.0.10", - "runtime.native.System": "4.0.0" + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" } }, "System.Net.Primitives": { @@ -1501,84 +1380,23 @@ "System.Runtime.Handles": "4.3.0" } }, - "System.Net.Requests": { - "type": "Transitive", - "resolved": "4.0.11", - "contentHash": "vxGt7C0cZixN+VqoSW4Yakc1Y9WknmxauDqzxgpw/FnBdz4kQNN51l4wxdXX5VY1xjqy//+G+4CvJWp1+f+y6Q==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tracing": "4.1.0", - "System.Globalization": "4.0.11", - "System.IO": "4.1.0", - "System.Net.Http": "4.1.0", - "System.Net.Primitives": "4.0.11", - "System.Net.WebHeaderCollection": "4.0.1", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11" - } - }, - "System.Net.Security": { + "System.Net.Sockets": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "xT2jbYpbBo3ha87rViHoTA6WdvqOAW37drmqyx/6LD8p7HEPT2qgdxoimRzWtPg8Jh4X5G9BV2seeTv4x6FYlA==", + "resolved": "4.3.0", + "contentHash": "m6icV6TqQOAdgt5N/9I5KNpjom/5NFtkmGseEH+AK/hny8XrytLH3+b5M8zL/Ycg3fhIocFpUMyl/wpFnVRvdw==", "dependencies": { "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.Win32.Primitives": "4.3.0", - "System.Collections": "4.3.0", - "System.Collections.Concurrent": "4.3.0", - "System.Diagnostics.Tracing": "4.3.0", - "System.Globalization": "4.3.0", - "System.Globalization.Extensions": "4.3.0", + "Microsoft.NETCore.Targets": "1.1.0", "System.IO": "4.3.0", "System.Net.Primitives": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Runtime.Handles": "4.3.0", - "System.Runtime.InteropServices": "4.3.0", - "System.Security.Claims": "4.3.0", - "System.Security.Cryptography.Algorithms": "4.3.0", - "System.Security.Cryptography.Encoding": "4.3.0", - "System.Security.Cryptography.OpenSsl": "4.3.0", - "System.Security.Cryptography.Primitives": "4.3.0", - "System.Security.Cryptography.X509Certificates": "4.3.0", - "System.Security.Principal": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Threading": "4.3.0", - "System.Threading.Tasks": "4.3.0", - "System.Threading.ThreadPool": "4.3.0", - "runtime.native.System": "4.3.0", - "runtime.native.System.Net.Security": "4.3.0", - "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2" - } - }, - "System.Net.Sockets": { - "type": "Transitive", - "resolved": "4.1.0", - "contentHash": "xAz0N3dAV/aR/9g8r0Y5oEqU1JRsz29F5EGb/WVHmX3jVSLqi2/92M5hTad2aNWovruXrJpJtgZ9fccPMG9uSw==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "Microsoft.NETCore.Targets": "1.0.1", - "System.IO": "4.1.0", - "System.Net.Primitives": "4.0.11", - "System.Runtime": "4.1.0", - "System.Threading.Tasks": "4.0.11" + "System.Threading.Tasks": "4.3.0" } }, - "System.Net.WebHeaderCollection": { + "System.Numerics.Vectors": { "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "XX2TIAN+wBSAIV51BU2FvvXMdstUa8b0FBSZmDWjZdwUMmggQSifpTOZ5fNH20z9ZCg2fkV1L5SsZnpO2RQDRQ==", - "dependencies": { - "System.Collections": "4.0.11", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.Extensions": "4.1.0" - } + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" }, "System.ObjectModel": { "type": "Transitive", @@ -1592,47 +1410,6 @@ "System.Threading": "4.3.0" } }, - "System.Private.DataContractSerialization": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "yDaJ2x3mMmjdZEDB4IbezSnCsnjQ4BxinKhRAaP6kEgL6Bb6jANWphs5SzyD8imqeC/3FxgsuXT6ykkiH1uUmA==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Collections.Concurrent": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Linq": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Emit.ILGeneration": "4.3.0", - "System.Reflection.Emit.Lightweight": "4.3.0", - "System.Reflection.Extensions": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Runtime.Serialization.Primitives": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Text.Encoding.Extensions": "4.3.0", - "System.Text.RegularExpressions": "4.3.0", - "System.Threading": "4.3.0", - "System.Threading.Tasks": "4.3.0", - "System.Xml.ReaderWriter": "4.3.0", - "System.Xml.XDocument": "4.3.0", - "System.Xml.XmlDocument": "4.3.0", - "System.Xml.XmlSerializer": "4.3.0" - } - }, - "System.Private.Uri": { - "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "o1+7RJnu3Ik3PazR7Z7tJhjPdE000Eq2KGLLWhqJJKXj04wrS8lwb1OFtDF9jzXXADhUuZNJZlPc98uwwqmpFA==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.1", - "Microsoft.NETCore.Targets": "1.1.3" - } - }, "System.Reflection": { "type": "Transitive", "resolved": "4.3.0", @@ -1777,16 +1554,16 @@ }, "System.Runtime.InteropServices.RuntimeInformation": { "type": "Transitive", - "resolved": "4.0.0", - "contentHash": "hWPhJxc453RCa8Z29O91EmfGeZIHX1ZH2A8L6lYQVSaKzku2DfArSfMEb1/MYYzPQRJZeu0c9dmYeJKxW5Fgng==", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==", "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "System.Reflection": "4.1.0", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Threading": "4.0.11", - "runtime.native.System": "4.0.0" + "System.Reflection": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Threading": "4.3.0", + "runtime.native.System": "4.3.0" } }, "System.Runtime.Loader": { @@ -1810,51 +1587,6 @@ "System.Runtime.Extensions": "4.3.0" } }, - "System.Runtime.Serialization.Formatters": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "KT591AkTNFOTbhZlaeMVvfax3RqhH1EJlcwF50Wm7sfnBLuHiOeZRRKrr1ns3NESkM20KPZ5Ol/ueMq5vg4QoQ==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Reflection": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Serialization.Primitives": "4.3.0" - } - }, - "System.Runtime.Serialization.Json": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "CpVfOH0M/uZ5PH+M9+Gu56K0j9lJw3M+PKRegTkcrY/stOIvRUeonggxNrfBYLA5WOHL2j15KNJuTuld3x4o9w==", - "dependencies": { - "System.IO": "4.3.0", - "System.Private.DataContractSerialization": "4.3.0", - "System.Runtime": "4.3.0" - } - }, - "System.Runtime.Serialization.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==", - "dependencies": { - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0" - } - }, - "System.Security.Claims": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "P/+BR/2lnc4PNDHt/TPBAWHVMLMRHsyYZbU1NphW4HIWzCggz8mJbTQQ3MKljFE7LS3WagmVFuBgoLcFzYXlkA==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Security.Principal": "4.3.0" - } - }, "System.Security.Cryptography.Algorithms": { "type": "Transitive", "resolved": "4.3.0", @@ -1967,6 +1699,11 @@ "System.Threading.Tasks": "4.3.0" } }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "wLBKzFnDCxP12VL9ANydSYhk59fC4cvOr9ypYQLPnAj48NQIhqnjdD2yhP8yEKyBJEjERWS9DisKL7rX5eU25Q==" + }, "System.Security.Cryptography.X509Certificates": { "type": "Transitive", "resolved": "4.3.0", @@ -1999,50 +1736,6 @@ "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" } }, - "System.Security.Principal": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "I1tkfQlAoMM2URscUtpcRo/hX0jinXx6a/KUtEQoz3owaYwl3qwsO8cbzYVVnjxrzxjHo3nJC+62uolgeGIS9A==", - "dependencies": { - "System.Runtime": "4.3.0" - } - }, - "System.Security.Principal.Windows": { - "type": "Transitive", - "resolved": "4.0.0", - "contentHash": "iFx15AF3RMEPZn3COh8+Bb2Thv2zsmLd93RchS1b8Mj5SNYeGqbYNCSn5AES1+gq56p4ujGZPrl0xN7ngkXOHg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "Microsoft.Win32.Primitives": "4.0.1", - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Reflection": "4.1.0", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.Handles": "4.0.1", - "System.Runtime.InteropServices": "4.1.0", - "System.Security.Claims": "4.0.1", - "System.Security.Principal": "4.0.1", - "System.Text.Encoding": "4.0.11", - "System.Threading": "4.0.11" - } - }, - "System.Security.SecureString": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "PnXp38O9q/2Oe4iZHMH60kinScv6QiiL2XH54Pj2t0Y6c2zKPEiAZsM/M3wBOHLNTBDFP0zfy13WN2M0qFz5jg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Handles": "4.3.0", - "System.Runtime.InteropServices": "4.3.0", - "System.Security.Cryptography.Primitives": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Threading": "4.3.0" - } - }, "System.Text.Encoding": { "type": "Transitive", "resolved": "4.3.0", @@ -2078,6 +1771,11 @@ "resolved": "4.7.2", "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.6.0", + "contentHash": "4F8Xe+JIkVoDJ8hDAZ7HqLkjctN/6WItJIzQaifBwClC7wmoLSda/Sv2i6i1kycqDb3hWF4JCVbpAweyOKHEUA==" + }, "System.Text.RegularExpressions": { "type": "Transitive", "resolved": "4.3.0", @@ -2095,17 +1793,6 @@ "System.Threading.Tasks": "4.3.0" } }, - "System.Threading.Overlapped": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "f7aLuLkBoCQM2kng7zqLFBXz9Gk48gDK8lk1ih9rH/1arJJzZK9gJwNvPDhL6Ps/l6rwOr8jw+4FCHL0KKWiEg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.Handles": "4.0.1" - } - }, "System.Threading.Tasks": { "type": "Transitive", "resolved": "4.3.0", @@ -2126,23 +1813,16 @@ "resolved": "4.5.4", "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==" }, - "System.Threading.Thread": { + "System.Threading.Timer": { "type": "Transitive", "resolved": "4.3.0", - "contentHash": "OHmbT+Zz065NKII/ZHcH9XO1dEuLGI1L2k7uYss+9C1jLxTC9kTZZuzUOyXHayRk+dft9CiDf3I/QZ0t8JKyBQ==", + "contentHash": "Z6YfyYTCg7lOZjJzBjONJTFKGN9/NIYKSxhU5GRd+DTwHSZyvWp1xuI5aR+dLg+ayyC5Xv57KiY4oJ0tMO89fQ==", "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", "System.Runtime": "4.3.0" } }, - "System.Threading.ThreadPool": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "k/+g4b7vjdd4aix83sTgC9VG6oXYKAktSfNIJUNGxPEj7ryEOfzHHhfnmsZvjxawwcD9HyWXKCXmPjX8U4zeSw==", - "dependencies": { - "System.Runtime": "4.3.0", - "System.Runtime.Handles": "4.3.0" - } - }, "System.Xml.ReaderWriter": { "type": "Transitive", "resolved": "4.3.0", @@ -2184,47 +1864,6 @@ "System.Xml.ReaderWriter": "4.3.0" } }, - "System.Xml.XmlDocument": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "lJ8AxvkX7GQxpC6GFCeBj8ThYVyQczx2+f/cWHJU8tjS7YfI6Cv6bon70jVEgs2CiFbmmM8b9j1oZVx0dSI2Ww==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Threading": "4.3.0", - "System.Xml.ReaderWriter": "4.3.0" - } - }, - "System.Xml.XmlSerializer": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "MYoTCP7EZ98RrANESW05J5ZwskKDoN0AuZ06ZflnowE50LTpbR5yRg3tHckTVm5j/m47stuGgCrCHWePyHS70Q==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Linq": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Emit": "4.3.0", - "System.Reflection.Emit.ILGeneration": "4.3.0", - "System.Reflection.Extensions": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Text.RegularExpressions": "4.3.0", - "System.Threading": "4.3.0", - "System.Xml.ReaderWriter": "4.3.0", - "System.Xml.XmlDocument": "4.3.0" - } - }, "Tavis.UriTemplates": { "type": "Transitive", "resolved": "1.1.1", @@ -2245,7 +1884,6 @@ "marain.tenancy.hosting.aspnetcore": { "type": "Project", "dependencies": { - "Corvus.Tenancy.Storage.Azure.Blob": "2.0.13", "Marain.Tenancy.OpenApi.Service": "1.0.0", "Menes.Hosting.AspNetCore": "3.0.0-preview.5" } @@ -2253,7 +1891,7 @@ "marain.tenancy.openapi.service": { "type": "Project", "dependencies": { - "Corvus.Azure.Storage.Tenancy": "2.0.13", + "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", "Menes.Abstractions": "2.0.1", "Microsoft.ApplicationInsights": "2.18.0", "Microsoft.AspNetCore.JsonPatch": "2.2.0", @@ -2261,6 +1899,13 @@ "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.0", "Newtonsoft.Json": "11.0.2" } + }, + "marain.tenancy.storage.azure.blobstorage": { + "type": "Project", + "dependencies": { + "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-make-v2config-legacy-public.3", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0" + } } } } diff --git a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj index 8c055bb0..31cc51d8 100644 --- a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj +++ b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj @@ -13,7 +13,6 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyStorageServiceCollectionExtensions.cs b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyStorageServiceCollectionExtensions.cs deleted file mode 100644 index 5296e265..00000000 --- a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyStorageServiceCollectionExtensions.cs +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright (c) Endjin Limited. All rights reserved. -// - -namespace Microsoft.Extensions.DependencyInjection -{ - using System; - using Corvus.Azure.Storage.Tenancy; - using Menes; - - /// - /// Configuration of services for using the operations repository implemented on top of the - /// tenancy repository. - /// - public static class TenancyStorageServiceCollectionExtensions - { - /// - /// Enable the tenancy st. - /// - /// The service collection. - /// - /// A function that will retrieve storage configuration for the root tenant. - /// - /// The modified service collection. - public static IServiceCollection AddTenancyBlobContainer( - this IServiceCollection services, - Func getRootTenantStorageConfiguration) - { - services.AddTenantProviderBlobStore(getRootTenantStorageConfiguration); - services.AddTenantCloudBlobContainerFactory(sp => sp.GetRequiredService()); - return services; - } - - /// - /// Add the tenancy api. - /// - /// The service collection. - /// - /// A function that will retrieve storage configuration for the root tenant. - /// - /// The optional action to configure the host. - /// The modified service collection. - [Obsolete("Use AddTenancyApiOnBlobStorageWithOpenApiActionResultHosting, or consider changing to AddTenancyApiOnBlobStorageWithAspNetPipelineHosting")] - public static IServiceCollection AddTenancyApiOnBlobStorage( - this IServiceCollection services, - Func getRootTenantStorageConfiguration, - Action configureHost = null) - { - AddTenancyApiOnBlobStorageCore(services, getRootTenantStorageConfiguration); - services.AddTenancyApi(configureHost); - return services; - } - - /// - /// Add the tenancy api. - /// - /// The service collection. - /// - /// A function that will retrieve storage configuration for the root tenant. - /// - /// The optional action to configure the host. - /// The modified service collection. - public static IServiceCollection AddTenancyApiOnBlobStorageWithOpenApiActionResultHosting( - this IServiceCollection services, - Func getRootTenantStorageConfiguration, - Action configureHost = null) - { - AddTenancyApiOnBlobStorageCore(services, getRootTenantStorageConfiguration); - services.AddTenancyApiWithOpenApiActionResultHosting(configureHost); - return services; - } - - /// - /// Add the tenancy api. - /// - /// The service collection. - /// - /// A function that will retrieve storage configuration for the root tenant. - /// - /// The optional action to configure the host. - /// The modified service collection. - public static IServiceCollection AddTenancyApiOnBlobStorageWithAspNetPipelineHosting( - this IServiceCollection services, - Func getRootTenantStorageConfiguration, - Action configureHost = null) - { - AddTenancyApiOnBlobStorageCore(services, getRootTenantStorageConfiguration); - services.AddTenancyApiWithAspNetPipelineHosting(configureHost); - return services; - } - - private static void AddTenancyApiOnBlobStorageCore(IServiceCollection services, Func getRootTenantStorageConfiguration) - { - services.AddTenancyBlobContainer(getRootTenantStorageConfiguration); - } - } -} diff --git a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj index f92b6a61..b624a50a 100644 --- a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj +++ b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj @@ -25,7 +25,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Solutions/Marain.Tenancy.OpenApi.Service/Marain/Tenancy/OpenApi/TenancyService.cs b/Solutions/Marain.Tenancy.OpenApi.Service/Marain/Tenancy/OpenApi/TenancyService.cs index 7402006a..0c694222 100644 --- a/Solutions/Marain.Tenancy.OpenApi.Service/Marain/Tenancy/OpenApi/TenancyService.cs +++ b/Solutions/Marain.Tenancy.OpenApi.Service/Marain/Tenancy/OpenApi/TenancyService.cs @@ -8,22 +8,25 @@ namespace Marain.Tenancy.OpenApi using System.Collections.Generic; using System.Net; using System.Threading.Tasks; - using Corvus.Extensions.Json; + using Corvus.Json; using Corvus.Tenancy; using Corvus.Tenancy.Exceptions; + using Marain.Tenancy.OpenApi.Configuration; using Marain.Tenancy.OpenApi.Mappers; + using Menes; using Menes.Exceptions; using Menes.Hal; using Menes.Links; + using Microsoft.AspNetCore.JsonPatch; using Microsoft.AspNetCore.JsonPatch.Operations; using Microsoft.Extensions.Logging; /// - /// Handles claim permissions requests. + /// Implements the tenancy web API. /// [EmbeddedOpenApiDefinition("Marain.Tenancy.OpenApi.TenancyServices.yaml")] public class TenancyService : IOpenApiService diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/FunctionBindings.cs b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/FunctionBindings.cs index 21edfb1d..df876387 100644 --- a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/FunctionBindings.cs +++ b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/FunctionBindings.cs @@ -6,13 +6,14 @@ namespace Marain.Tenancy.Specs.Integration.Bindings { using System; using System.Threading.Tasks; + using Corvus.Testing.AzureFunctions; using Corvus.Testing.AzureFunctions.SpecFlow; using Corvus.Testing.SpecFlow; - using Microsoft.CodeAnalysis.CSharp.Syntax; + using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; - using NUnit.Framework; + using TechTalk.SpecFlow; /// diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyApiBindings.cs b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyApiBindings.cs deleted file mode 100644 index 00f6fa8b..00000000 --- a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyApiBindings.cs +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) Endjin Limited. All rights reserved. -// - -namespace Marain.Tenancy.Specs.Integration.Bindings -{ - using System.Collections.Generic; - using Corvus.Azure.Storage.Tenancy; - using Corvus.Testing.SpecFlow; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using TechTalk.SpecFlow; - - /// - /// Bindings for the integration tests for the TenancyService. - /// - [Binding] - public static class TenancyApiBindings - { - /// - /// Configures the DI container before tests start. - /// - /// The SpecFlow test context. - [BeforeFeature("@tenancyApi", Order = ContainerBeforeFeatureOrder.PopulateServiceCollection)] - public static void SetupFeature(FeatureContext featureContext) - { - ContainerBindings.ConfigureServices( - featureContext, - serviceCollection => - { - var configData = new Dictionary(); - - IConfigurationRoot config = new ConfigurationBuilder() - .AddInMemoryCollection(configData) - .AddEnvironmentVariables() - .AddJsonFile("local.settings.json", true, true) - .Build(); - - serviceCollection.AddTenancyApiOnBlobStorageWithOpenApiActionResultHosting( - _ => config.GetSection("RootTenantBlobStorageConfigurationOptions").Get()); - }); - } - } -} diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TestTenantCleanup.cs b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TestTenantCleanup.cs new file mode 100644 index 00000000..e534f281 --- /dev/null +++ b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TestTenantCleanup.cs @@ -0,0 +1,56 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Specs.Integration.Bindings +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net.Http; + using System.Threading.Tasks; + + using TechTalk.SpecFlow; + + [Binding] + public class TestTenantCleanup + { + private static readonly HttpClient HttpClient = new HttpClient(); + private readonly HashSet<(string ParentId, string TenantId)> tenantsToDelete = new(); + private readonly HashSet<(string ParentId, string TenantId)> wellKnownTenantsToDelete = new(); + + public void AddTenantToDelete(string parentId, string id) + { + this.tenantsToDelete.Add((parentId, id)); + } + + public void AddWellKnownTenantToDelete(string parentId, string id) + { + this.tenantsToDelete.Add((parentId, id)); + } + + [AfterScenario("@useTenancyFunction")] + public async Task CleanUpTestTenants() + { + var errors = new List(); + foreach ((string parentId, string id) in this.tenantsToDelete.OrderByDescending(t => t.ParentId.Length + t.TenantId.Length)) + { + try + { + var deleteUri = new Uri(FunctionBindings.TenancyApiBaseUri, $"/{parentId}/marain/tenant/children/{id}"); + HttpResponseMessage response = await HttpClient.DeleteAsync(deleteUri) + .ConfigureAwait(false); + } + catch (Exception x) + { + errors.Add(x); + } + } + + if (errors.Count > 0) + { + throw new AggregateException(errors); + } + } + } +} diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyApi.feature.cs b/Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyApi.feature.cs deleted file mode 100644 index 32ea3e96..00000000 --- a/Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyApi.feature.cs +++ /dev/null @@ -1,366 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// This code was generated by SpecFlow (https://www.specflow.org/). -// SpecFlow Version:3.9.0.0 -// SpecFlow Generator Version:3.9.0.0 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -// ------------------------------------------------------------------------------ -#region Designer generated code -#pragma warning disable -namespace Marain.Tenancy.Specs.Integration.Features -{ - using TechTalk.SpecFlow; - using System; - using System.Linq; - - - [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.9.0.0")] - [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("Tenancy Api")] - [NUnit.Framework.CategoryAttribute("perFeatureContainer")] - [NUnit.Framework.CategoryAttribute("withTenancyClient")] - [NUnit.Framework.CategoryAttribute("useTenancyFunction")] - public partial class TenancyApiFeature - { - - private TechTalk.SpecFlow.ITestRunner testRunner; - - private string[] _featureTags = new string[] { - "perFeatureContainer", - "withTenancyClient", - "useTenancyFunction"}; - -#line 1 "TenancyApi.feature" -#line hidden - - [NUnit.Framework.OneTimeSetUpAttribute()] - public virtual void FeatureSetup() - { - testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(); - TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Integration/Features", "Tenancy Api", "\tIn order to use Marain Tenant services\r\n\tAs a developer\r\n\tI want to be able to a" + - "ccess the Tenancy Api.", ProgrammingLanguage.CSharp, new string[] { - "perFeatureContainer", - "withTenancyClient", - "useTenancyFunction"}); - testRunner.OnFeatureStart(featureInfo); - } - - [NUnit.Framework.OneTimeTearDownAttribute()] - public virtual void FeatureTearDown() - { - testRunner.OnFeatureEnd(); - testRunner = null; - } - - [NUnit.Framework.SetUpAttribute()] - public virtual void TestInitialize() - { - } - - [NUnit.Framework.TearDownAttribute()] - public virtual void TestTearDown() - { - testRunner.OnScenarioEnd(); - } - - public virtual void ScenarioInitialize(TechTalk.SpecFlow.ScenarioInfo scenarioInfo) - { - testRunner.OnScenarioInitialize(scenarioInfo); - testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); - } - - public virtual void ScenarioStart() - { - testRunner.OnScenarioStart(); - } - - public virtual void ScenarioCleanup() - { - testRunner.CollectScenarioErrors(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get the OpenApi definition for the Api")] - public virtual void GetTheOpenApiDefinitionForTheApi() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get the OpenApi definition for the Api", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 10 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 11 - testRunner.When("I request the tenancy service endpoint \'/swagger\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 12 - testRunner.Then("I receive a \'OK\' response", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get a tenant that does not exist")] - public virtual void GetATenantThatDoesNotExist() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get a tenant that does not exist", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 14 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 15 - testRunner.When("I request the tenant with Id \'thistenantdoesnotexist\' from the API", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 16 - testRunner.Then("I receive a \'NotFound\' response", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create a tenant")] - public virtual void CreateATenant() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Create a tenant", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 18 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); - TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] { - "ParentTenantId", - "Name"}); - table1.AddRow(new string[] { - "f26450ab1668784bb327951c8b08f347", - "Test"}); -#line 19 - testRunner.When("I use the API to create a new tenant", ((string)(null)), table1, "When "); -#line hidden -#line 22 - testRunner.Then("I receive a \'Created\' response", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden -#line 23 - testRunner.And("the response should contain a \'Location\' header", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get the root tenant")] - public virtual void GetTheRootTenant() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get the root tenant", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 25 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 26 - testRunner.When("I request the tenant with Id \'f26450ab1668784bb327951c8b08f347\' from the API", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 27 - testRunner.Then("I receive an \'OK\' response", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden -#line 28 - testRunner.And("the response content should have a string property called \'name\' with value \'Root" + - "\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 29 - testRunner.And("the response should not contain an \'Etag\' header", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 30 - testRunner.And("the response should contain a \'Cache-Control\' header with value \'max-age=300\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Retrieve a newly created tenant using the location header returned from the creat" + - "e request")] - public virtual void RetrieveANewlyCreatedTenantUsingTheLocationHeaderReturnedFromTheCreateRequest() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Retrieve a newly created tenant using the location header returned from the creat" + - "e request", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 32 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); - TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] { - "ParentTenantId", - "Name"}); - table2.AddRow(new string[] { - "f26450ab1668784bb327951c8b08f347", - "Test"}); -#line 33 - testRunner.Given("I have used the API to create a new tenant", ((string)(null)), table2, "Given "); -#line hidden -#line 36 - testRunner.When("I request the tenant using the Location from the previous response", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 37 - testRunner.Then("I receive an \'OK\' response", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden -#line 38 - testRunner.And("the response content should have a string property called \'name\' with value \'Test" + - "\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 39 - testRunner.And("the response should contain an \'Etag\' header", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 40 - testRunner.And("the response should contain a \'Cache-Control\' header with value \'max-age=300\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Request a tenant using the etag from a previous request")] - public virtual void RequestATenantUsingTheEtagFromAPreviousRequest() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Request a tenant using the etag from a previous request", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 42 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); - TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] { - "ParentTenantId", - "Name"}); - table3.AddRow(new string[] { - "f26450ab1668784bb327951c8b08f347", - "Test"}); -#line 43 - testRunner.Given("I have used the API to create a new tenant", ((string)(null)), table3, "Given "); -#line hidden -#line 46 - testRunner.And("I store the value of the response Location header as \'New tenant location\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 47 - testRunner.And("I have requested the tenant using the path called \'New tenant location\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 48 - testRunner.When("I request the tenant using the path called \'New tenant location\' and the Etag fro" + - "m the previous response", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 49 - testRunner.Then("I receive a \'NotModified\' response", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - } -} -#pragma warning restore -#endregion diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyClientWithCachingDisabled.feature.cs b/Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyClientWithCachingDisabled.feature.cs deleted file mode 100644 index b5cbeb0e..00000000 --- a/Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyClientWithCachingDisabled.feature.cs +++ /dev/null @@ -1,928 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// This code was generated by SpecFlow (https://www.specflow.org/). -// SpecFlow Version:3.9.0.0 -// SpecFlow Generator Version:3.9.0.0 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -// ------------------------------------------------------------------------------ -#region Designer generated code -#pragma warning disable -namespace Marain.Tenancy.Specs.Integration.Features -{ - using TechTalk.SpecFlow; - using System; - using System.Linq; - - - [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.9.0.0")] - [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("TenancyClient with caching disabled")] - [NUnit.Framework.CategoryAttribute("perFeatureContainer")] - [NUnit.Framework.CategoryAttribute("withTenancyClient")] - [NUnit.Framework.CategoryAttribute("useTenancyFunction")] - [NUnit.Framework.CategoryAttribute("disableTenantCaching")] - public partial class TenancyClientWithCachingDisabledFeature - { - - private TechTalk.SpecFlow.ITestRunner testRunner; - - private string[] _featureTags = new string[] { - "perFeatureContainer", - "withTenancyClient", - "useTenancyFunction", - "disableTenantCaching"}; - -#line 1 "TenancyClientWithCachingDisabled.feature" -#line hidden - - [NUnit.Framework.OneTimeSetUpAttribute()] - public virtual void FeatureSetup() - { - testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(); - TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Integration/Features", "TenancyClient with caching disabled", "\tIn order to use Marain Tenant services\r\n\tAs a developer\r\n\tI want to be able to a" + - "ccess the standard ITenantProvider via the client API.", ProgrammingLanguage.CSharp, new string[] { - "perFeatureContainer", - "withTenancyClient", - "useTenancyFunction", - "disableTenantCaching"}); - testRunner.OnFeatureStart(featureInfo); - } - - [NUnit.Framework.OneTimeTearDownAttribute()] - public virtual void FeatureTearDown() - { - testRunner.OnFeatureEnd(); - testRunner = null; - } - - [NUnit.Framework.SetUpAttribute()] - public virtual void TestInitialize() - { - } - - [NUnit.Framework.TearDownAttribute()] - public virtual void TestTearDown() - { - testRunner.OnScenarioEnd(); - } - - public virtual void ScenarioInitialize(TechTalk.SpecFlow.ScenarioInfo scenarioInfo) - { - testRunner.OnScenarioInitialize(scenarioInfo); - testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); - } - - public virtual void ScenarioStart() - { - testRunner.OnScenarioStart(); - } - - public virtual void ScenarioCleanup() - { - testRunner.CollectScenarioErrors(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get a tenant that does not exist")] - public virtual void GetATenantThatDoesNotExist() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get a tenant that does not exist", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 11 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 12 - testRunner.When("I get a tenant with id \"NotFound\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 13 - testRunner.Then("it should throw a TenantNotFoundException", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get a tenant with an etag retrieved from a created tenant")] - public virtual void GetATenantWithAnEtagRetrievedFromACreatedTenant() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get a tenant with an etag retrieved from a created tenant", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 15 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 16 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 17 - testRunner.And("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 18 - testRunner.And("I get the ETag of the tenant called \"ChildTenant1\" and call it \"ChildTenantETag\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 19 - testRunner.When("I get the tenant with the id called \"ChildTenantId\" and the ETag called \"ChildTen" + - "antETag\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 20 - testRunner.Then("it should throw a TenantNotModifiedException", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get a tenant with an etag retrieved from a tenant got from the repo")] - public virtual void GetATenantWithAnEtagRetrievedFromATenantGotFromTheRepo() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get a tenant with an etag retrieved from a tenant got from the repo", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 22 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 23 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 24 - testRunner.And("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 25 - testRunner.And("I get the tenant with the id called \"ChildTenantId\" and call it \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 26 - testRunner.And("I get the ETag of the tenant called \"Result\" and call it \"ResultETag\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 27 - testRunner.When("I get the tenant with the id called \"ChildTenantId\" and the ETag called \"ResultET" + - "ag\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 28 - testRunner.Then("it should throw a TenantNotModifiedException", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create a child tenant")] - public virtual void CreateAChildTenant() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Create a child tenant", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 30 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 31 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 32 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 33 - testRunner.And("I get the tenant with the id called \"ChildTenantId\" and call it \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 34 - testRunner.Then("the tenant called \"ChildTenant1\" should have the same ID as the tenant called \"Re" + - "sult\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Update a child tenant")] - public virtual void UpdateAChildTenant() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Update a child tenant", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 36 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 37 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden - TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] { - "Key", - "Value", - "Type"}); - table4.AddRow(new string[] { - "FirstKey", - "1", - "integer"}); - table4.AddRow(new string[] { - "SecondKey", - "This is a string", - "string"}); - table4.AddRow(new string[] { - "ThirdKey", - "1999-01-17", - "datetimeoffset"}); -#line 38 - testRunner.When("I update the properties of the tenant called \"ChildTenant1\"", ((string)(null)), table4, "When "); -#line hidden -#line 43 - testRunner.And("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 44 - testRunner.And("I get the tenant with the id called \"ChildTenantId\" and call it \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 45 - testRunner.Then("the tenant called \"ChildTenant1\" should have the same ID as the tenant called \"Re" + - "sult\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] { - "Key", - "Value", - "Type"}); - table5.AddRow(new string[] { - "FirstKey", - "1", - "integer"}); - table5.AddRow(new string[] { - "SecondKey", - "This is a string", - "string"}); - table5.AddRow(new string[] { - "ThirdKey", - "1999-01-17", - "datetimeoffset"}); -#line 46 - testRunner.And("the tenant called \"Result\" should have the properties", ((string)(null)), table5, "And "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Add, update, and remove properties of a child tenant")] - public virtual void AddUpdateAndRemovePropertiesOfAChildTenant() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Add, update, and remove properties of a child tenant", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 52 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 53 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden - TechTalk.SpecFlow.Table table6 = new TechTalk.SpecFlow.Table(new string[] { - "Key", - "Value", - "Type"}); - table6.AddRow(new string[] { - "FirstKey", - "1", - "integer"}); - table6.AddRow(new string[] { - "SecondKey", - "This is a string", - "string"}); - table6.AddRow(new string[] { - "ThirdKey", - "1999-01-17", - "datetimeoffset"}); -#line 54 - testRunner.And("I update the properties of the tenant called \"ChildTenant1\"", ((string)(null)), table6, "And "); -#line hidden - TechTalk.SpecFlow.Table table7 = new TechTalk.SpecFlow.Table(new string[] { - "Property", - "Value", - "Type", - "Action"}); - table7.AddRow(new string[] { - "FirstKey", - "2", - "integer", - "addOrSet"}); - table7.AddRow(new string[] { - "FourthKey", - "4", - "integer", - "addOrSet"}); - table7.AddRow(new string[] { - "FifthKey", - "This is a new string", - "string", - "addOrSet"}); - table7.AddRow(new string[] { - "ThirdKey", - "", - "", - "remove"}); -#line 59 - testRunner.When("I rename the tenant called \"ChildTenant1\" to \"RenamedChildTenant1\" and update its" + - " properties", ((string)(null)), table7, "When "); -#line hidden -#line 65 - testRunner.And("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 66 - testRunner.And("I get the tenant with the id called \"ChildTenantId\" and call it \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 67 - testRunner.Then("the tenant called \"ChildTenant1\" should have the same ID as the tenant called \"Re" + - "sult\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden -#line 68 - testRunner.And("the tenant called \"Result\" should now have the name \"RenamedChildTenant1\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - TechTalk.SpecFlow.Table table8 = new TechTalk.SpecFlow.Table(new string[] { - "Key", - "Value", - "Type"}); - table8.AddRow(new string[] { - "FirstKey", - "2", - "integer"}); - table8.AddRow(new string[] { - "SecondKey", - "This is a string", - "string"}); - table8.AddRow(new string[] { - "FourthKey", - "4", - "integer"}); - table8.AddRow(new string[] { - "FifthKey", - "This is a new string", - "string"}); -#line 69 - testRunner.And("the tenant called \"Result\" should have the properties", ((string)(null)), table8, "And "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create a child of a child")] - public virtual void CreateAChildOfAChild() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Create a child of a child", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 76 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 77 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 78 - testRunner.And("I create a child tenant called \"ChildTenant2\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 79 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant2\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 80 - testRunner.And("I get the tenant with the id called \"ChildTenantId\" and call it \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 81 - testRunner.Then("the tenant called \"ChildTenant2\" should have the same ID as the tenant called \"Re" + - "sult\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get children")] - public virtual void GetChildren() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get children", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 83 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 84 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 85 - testRunner.And("I create a child tenant called \"ChildTenant2\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 86 - testRunner.And("I create a child tenant called \"ChildTenant3\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 87 - testRunner.And("I create a child tenant called \"ChildTenant4\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 88 - testRunner.And("I create a child tenant called \"ChildTenant5\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 89 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 90 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 20 and call them \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - TechTalk.SpecFlow.Table table9 = new TechTalk.SpecFlow.Table(new string[] { - "TenantName"}); - table9.AddRow(new string[] { - "ChildTenant2"}); - table9.AddRow(new string[] { - "ChildTenant3"}); - table9.AddRow(new string[] { - "ChildTenant4"}); - table9.AddRow(new string[] { - "ChildTenant5"}); -#line 91 - testRunner.Then("the ids of the children called \"Result\" should match the ids of the tenants calle" + - "d", ((string)(null)), table9, "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get children when no child tenants exist")] - public virtual void GetChildrenWhenNoChildTenantsExist() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get children when no child tenants exist", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 98 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 99 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 100 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 101 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 20 and call them \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 102 - testRunner.Then("there should be no ids in the children called \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get children when there is a single child tenant")] - public virtual void GetChildrenWhenThereIsASingleChildTenant() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get children when there is a single child tenant", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 104 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 105 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 106 - testRunner.And("I create a child tenant called \"ChildTenant2\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 107 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 108 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 20 and call them \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - TechTalk.SpecFlow.Table table10 = new TechTalk.SpecFlow.Table(new string[] { - "TenantName"}); - table10.AddRow(new string[] { - "ChildTenant2"}); -#line 109 - testRunner.Then("the ids of the children called \"Result\" should match the ids of the tenants calle" + - "d", ((string)(null)), table10, "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get children with continuation token")] - public virtual void GetChildrenWithContinuationToken() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get children with continuation token", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 113 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 114 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 115 - testRunner.And("I create a child tenant called \"ChildTenant2\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 116 - testRunner.And("I create a child tenant called \"ChildTenant3\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 117 - testRunner.And("I create a child tenant called \"ChildTenant4\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 118 - testRunner.And("I create a child tenant called \"ChildTenant5\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 119 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 120 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 2 and call them \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 121 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 20 and continuation token \"Result\" and call them \"Result2\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 122 - testRunner.Then("there should be 2 tenants in \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden -#line 123 - testRunner.And("there should be 2 tenants in \"Result2\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - TechTalk.SpecFlow.Table table11 = new TechTalk.SpecFlow.Table(new string[] { - "TenantName"}); - table11.AddRow(new string[] { - "ChildTenant5"}); - table11.AddRow(new string[] { - "ChildTenant4"}); - table11.AddRow(new string[] { - "ChildTenant3"}); - table11.AddRow(new string[] { - "ChildTenant2"}); -#line 124 - testRunner.And("the ids of the children called \"Result\" and \"Result2\" should each match 2 of the " + - "ids of the tenants called", ((string)(null)), table11, "And "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Delete a child")] - public virtual void DeleteAChild() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Delete a child", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 131 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 132 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 133 - testRunner.And("I create a child tenant called \"ChildTenant2\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 134 - testRunner.And("I create a child tenant called \"ChildTenant3\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 135 - testRunner.And("I create a child tenant called \"ChildTenant4\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 136 - testRunner.And("I create a child tenant called \"ChildTenant5\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 137 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 138 - testRunner.And("I get the tenant id of the tenant called \"ChildTenant3\" and call it \"DeletedChild" + - "TenantId\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 139 - testRunner.And("I delete the tenant with the id called \"DeletedChildTenantId\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 140 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 20 and call them \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - TechTalk.SpecFlow.Table table12 = new TechTalk.SpecFlow.Table(new string[] { - "TenantName"}); - table12.AddRow(new string[] { - "ChildTenant2"}); - table12.AddRow(new string[] { - "ChildTenant4"}); - table12.AddRow(new string[] { - "ChildTenant5"}); -#line 141 - testRunner.Then("the ids of the children called \"Result\" should match the ids of the tenants calle" + - "d", ((string)(null)), table12, "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Root tenant has empty properties")] - public virtual void RootTenantHasEmptyProperties() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Root tenant has empty properties", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 147 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 148 - testRunner.When("I get the tenant with id \"f26450ab1668784bb327951c8b08f347\" and call it \"Root\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 149 - testRunner.Then("the tenant called \"Root\" should have no properties", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Updates to root tenant are prohibited")] - public virtual void UpdatesToRootTenantAreProhibited() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Updates to root tenant are prohibited", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 151 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 152 - testRunner.When("I try to update the properties of the tenant with id \"f26450ab1668784bb327951c8b0" + - "8f347\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 153 - testRunner.Then("it should throw a NotSupportedException", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - } -} -#pragma warning restore -#endregion diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyClientWithCachingEnabled.feature.cs b/Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyClientWithCachingEnabled.feature.cs deleted file mode 100644 index 63c53f22..00000000 --- a/Solutions/Marain.Tenancy.Specs/Integration/Features/TenancyClientWithCachingEnabled.feature.cs +++ /dev/null @@ -1,559 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// This code was generated by SpecFlow (https://www.specflow.org/). -// SpecFlow Version:3.9.0.0 -// SpecFlow Generator Version:3.9.0.0 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -// ------------------------------------------------------------------------------ -#region Designer generated code -#pragma warning disable -namespace Marain.Tenancy.Specs.Integration.Features -{ - using TechTalk.SpecFlow; - using System; - using System.Linq; - - - [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.9.0.0")] - [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("TenancyClient with caching enabled")] - [NUnit.Framework.CategoryAttribute("perFeatureContainer")] - [NUnit.Framework.CategoryAttribute("withTenancyClient")] - [NUnit.Framework.CategoryAttribute("useTenancyFunction")] - public partial class TenancyClientWithCachingEnabledFeature - { - - private TechTalk.SpecFlow.ITestRunner testRunner; - - private string[] _featureTags = new string[] { - "perFeatureContainer", - "withTenancyClient", - "useTenancyFunction"}; - -#line 1 "TenancyClientWithCachingEnabled.feature" -#line hidden - - [NUnit.Framework.OneTimeSetUpAttribute()] - public virtual void FeatureSetup() - { - testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(); - TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Integration/Features", "TenancyClient with caching enabled", "\tIn order to use Marain Tenant services\r\n\tAs a developer\r\n\tI want to be able to a" + - "ccess the standard ITenantProvider via the client API.", ProgrammingLanguage.CSharp, new string[] { - "perFeatureContainer", - "withTenancyClient", - "useTenancyFunction"}); - testRunner.OnFeatureStart(featureInfo); - } - - [NUnit.Framework.OneTimeTearDownAttribute()] - public virtual void FeatureTearDown() - { - testRunner.OnFeatureEnd(); - testRunner = null; - } - - [NUnit.Framework.SetUpAttribute()] - public virtual void TestInitialize() - { - } - - [NUnit.Framework.TearDownAttribute()] - public virtual void TestTearDown() - { - testRunner.OnScenarioEnd(); - } - - public virtual void ScenarioInitialize(TechTalk.SpecFlow.ScenarioInfo scenarioInfo) - { - testRunner.OnScenarioInitialize(scenarioInfo); - testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); - } - - public virtual void ScenarioStart() - { - testRunner.OnScenarioStart(); - } - - public virtual void ScenarioCleanup() - { - testRunner.CollectScenarioErrors(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get a tenant that does not exist")] - public virtual void GetATenantThatDoesNotExist() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get a tenant that does not exist", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 13 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 14 - testRunner.When("I get a tenant with id \"NotFound\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 15 - testRunner.Then("it should throw a TenantNotFoundException", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Getting a tenant that has already been retrieved uses the cache")] - public virtual void GettingATenantThatHasAlreadyBeenRetrievedUsesTheCache() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Getting a tenant that has already been retrieved uses the cache", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 17 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 18 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 19 - testRunner.And("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 20 - testRunner.When("I use the client to get the tenant with the id called \"ChildTenantId\" and call th" + - "e response \"Response1\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 21 - testRunner.Then("the tenant response called \"Response1\" was retrieved from the cache", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get a tenant with an etag retrieved from a created tenant")] - public virtual void GetATenantWithAnEtagRetrievedFromACreatedTenant() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get a tenant with an etag retrieved from a created tenant", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 23 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 24 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 25 - testRunner.And("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 26 - testRunner.And("I get the ETag of the tenant called \"ChildTenant1\" and call it \"ChildTenantETag\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 27 - testRunner.When("I get the tenant with the id called \"ChildTenantId\" and the ETag called \"ChildTen" + - "antETag\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 28 - testRunner.Then("it should throw a TenantNotModifiedException", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get a tenant with an etag retrieved from a tenant got from the repo")] - public virtual void GetATenantWithAnEtagRetrievedFromATenantGotFromTheRepo() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get a tenant with an etag retrieved from a tenant got from the repo", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 30 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 31 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 32 - testRunner.And("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 33 - testRunner.And("I get the tenant with the id called \"ChildTenantId\" and call it \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 34 - testRunner.And("I get the ETag of the tenant called \"Result\" and call it \"ResultETag\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 35 - testRunner.When("I get the tenant with the id called \"ChildTenantId\" and the ETag called \"ResultET" + - "ag\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 36 - testRunner.Then("it should throw a TenantNotModifiedException", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get children")] - public virtual void GetChildren() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get children", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 38 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 39 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 40 - testRunner.And("I create a child tenant called \"ChildTenant2\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 41 - testRunner.And("I create a child tenant called \"ChildTenant3\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 42 - testRunner.And("I create a child tenant called \"ChildTenant4\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 43 - testRunner.And("I create a child tenant called \"ChildTenant5\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 44 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 45 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 20 and call them \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - TechTalk.SpecFlow.Table table13 = new TechTalk.SpecFlow.Table(new string[] { - "TenantName"}); - table13.AddRow(new string[] { - "ChildTenant2"}); - table13.AddRow(new string[] { - "ChildTenant3"}); - table13.AddRow(new string[] { - "ChildTenant4"}); - table13.AddRow(new string[] { - "ChildTenant5"}); -#line 46 - testRunner.Then("the ids of the children called \"Result\" should match the ids of the tenants calle" + - "d", ((string)(null)), table13, "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get children when no child tenants exist")] - public virtual void GetChildrenWhenNoChildTenantsExist() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get children when no child tenants exist", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 53 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 54 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 55 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 56 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 20 and call them \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 57 - testRunner.Then("there should be no ids in the children called \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get children when there is a single child tenant")] - public virtual void GetChildrenWhenThereIsASingleChildTenant() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get children when there is a single child tenant", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 59 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 60 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 61 - testRunner.And("I create a child tenant called \"ChildTenant2\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 62 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 63 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 20 and call them \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - TechTalk.SpecFlow.Table table14 = new TechTalk.SpecFlow.Table(new string[] { - "TenantName"}); - table14.AddRow(new string[] { - "ChildTenant2"}); -#line 64 - testRunner.Then("the ids of the children called \"Result\" should match the ids of the tenants calle" + - "d", ((string)(null)), table14, "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Get children with continuation token")] - public virtual void GetChildrenWithContinuationToken() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get children with continuation token", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 68 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 69 - testRunner.Given("I create a child tenant called \"ChildTenant1\" for the root tenant", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line hidden -#line 70 - testRunner.And("I create a child tenant called \"ChildTenant2\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 71 - testRunner.And("I create a child tenant called \"ChildTenant3\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 72 - testRunner.And("I create a child tenant called \"ChildTenant4\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 73 - testRunner.And("I create a child tenant called \"ChildTenant5\" for the tenant called \"ChildTenant1" + - "\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 74 - testRunner.When("I get the tenant id of the tenant called \"ChildTenant1\" and call it \"ChildTenantI" + - "d\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 75 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 2 and call them \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 76 - testRunner.And("I get the children of the tenant with the id called \"ChildTenantId\" with maxItems" + - " 20 and continuation token \"Result\" and call them \"Result2\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden -#line 77 - testRunner.Then("there should be 2 tenants in \"Result\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden -#line 78 - testRunner.And("there should be 2 tenants in \"Result2\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line hidden - TechTalk.SpecFlow.Table table15 = new TechTalk.SpecFlow.Table(new string[] { - "TenantName"}); - table15.AddRow(new string[] { - "ChildTenant5"}); - table15.AddRow(new string[] { - "ChildTenant4"}); - table15.AddRow(new string[] { - "ChildTenant3"}); - table15.AddRow(new string[] { - "ChildTenant2"}); -#line 79 - testRunner.And("the ids of the children called \"Result\" and \"Result2\" should each match 2 of the " + - "ids of the tenants called", ((string)(null)), table15, "And "); -#line hidden - } - this.ScenarioCleanup(); - } - - [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Root tenant has empty properties")] - public virtual void RootTenantHasEmptyProperties() - { - string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Root tenant has empty properties", null, tagsOfScenario, argumentsOfScenario, this._featureTags); -#line 86 -this.ScenarioInitialize(scenarioInfo); -#line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) - { - testRunner.SkipScenario(); - } - else - { - this.ScenarioStart(); -#line 87 - testRunner.When("I get the tenant with id \"f26450ab1668784bb327951c8b08f347\" and call it \"Root\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); -#line hidden -#line 88 - testRunner.Then("the tenant called \"Root\" should have no properties", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); -#line hidden - } - this.ScenarioCleanup(); - } - } -} -#pragma warning restore -#endregion diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyApiSteps.cs b/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyApiSteps.cs index d756b052..c5233cee 100644 --- a/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyApiSteps.cs +++ b/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyApiSteps.cs @@ -10,21 +10,35 @@ namespace Marain.Tenancy.Specs.Integration.Steps using System.Net.Http; using System.Text; using System.Threading.Tasks; + using Corvus.Extensions.Json; using Corvus.Testing.SpecFlow; + using Marain.Tenancy.Specs.Integration.Bindings; + using Microsoft.Extensions.DependencyInjection; + using Newtonsoft.Json; using Newtonsoft.Json.Linq; + using NUnit.Framework; + using TechTalk.SpecFlow; [Binding] public class TenancyApiSteps : Steps - { - private const string ResponseContent = "ApiSteps:ResponseContent"; - + { private static readonly HttpClient HttpClient = new HttpClient(); + private readonly TestTenantCleanup testTenantCleanup; + private HttpResponseMessage? response; + private string? responseContent; + + public TenancyApiSteps(TestTenantCleanup testTenantCleanup) + { + this.testTenantCleanup = testTenantCleanup; + } + + private HttpResponseMessage Response => this.response ?? throw new InvalidOperationException("No response available"); [When("I request the tenancy service endpoint '(.*)'")] public Task WhenIRequestTheTenancyServiceEndpoint(string endpointPath) @@ -41,17 +55,13 @@ public Task WhenIRequestTheTenantWithIdFromTheAPI(string tenantId) [When("I request the tenant using the Location from the previous response")] public Task WhenIRequestTheTenantUsingTheLocationFromThePreviousResponse() { - HttpResponseMessage response = this.ScenarioContext.Get(); - - return this.SendGetRequest(FunctionBindings.TenancyApiBaseUri, response.Headers.Location.ToString()); + return this.SendGetRequest(FunctionBindings.TenancyApiBaseUri, this.Response.Headers.Location.ToString()); } [Given("I store the value of the response Location header as '(.*)'")] public void GivenIStoreTheValueOfTheResponseLocationHeaderAs(string name) { - HttpResponseMessage response = this.ScenarioContext.Get(); - - this.ScenarioContext.Set(response.Headers.Location.ToString(), name); + this.ScenarioContext.Set(this.Response.Headers.Location.ToString(), name); } [Given("I have requested the tenant using the path called '(.*)'")] @@ -64,58 +74,56 @@ public Task GivenIHaveRequestedTheTenantUsingThePathCalled(string name) [When("I request the tenant using the path called '(.*)' and the Etag from the previous response")] public Task WhenIRequestTheTenantUsingThePathCalledAndTheEtagFromThePreviousResponse(string name) { - HttpResponseMessage response = this.ScenarioContext.Get(); string path = this.ScenarioContext.Get(name); - return this.SendGetRequest(FunctionBindings.TenancyApiBaseUri, path, response.Headers.ETag.Tag); + return this.SendGetRequest(FunctionBindings.TenancyApiBaseUri, path, this.Response.Headers.ETag.Tag); } [Given("I have used the API to create a new tenant")] [When("I use the API to create a new tenant")] - public Task WhenIUseTheAPIToCreateANewTenant(Table table) + public async Task WhenIUseTheAPIToCreateANewTenant(Table table) { string parentId = table.Rows[0]["ParentTenantId"]; string name = table.Rows[0]["Name"]; - return this.SendPostRequest(FunctionBindings.TenancyApiBaseUri, $"/{parentId}/marain/tenant/children?tenantName={Uri.EscapeUriString(name)}", null); + await this.SendPostRequest(FunctionBindings.TenancyApiBaseUri, $"/{parentId}/marain/tenant/children?tenantName={Uri.EscapeUriString(name)}", null); + if (this.Response.IsSuccessStatusCode && this.Response.Headers.Location is not null) + { + string location = this.Response.Headers.Location.ToString(); + string id = location[1..location.IndexOf('/', 1)]; + this.testTenantCleanup.AddTenantToDelete(parentId, id); + } } [Then("I receive a '(.*)' response")] [Then("I receive an '(.*)' response")] public void ThenIReceiveAResponse(HttpStatusCode expectedStatusCode) { - HttpResponseMessage response = this.ScenarioContext.Get(); - // If present, we'll use the response content as a message in case of failure - this.ScenarioContext.TryGetValue(ResponseContent, out string responseContent); - - Assert.AreEqual(expectedStatusCode, response.StatusCode, responseContent); + Assert.AreEqual(expectedStatusCode, this.Response.StatusCode, this.responseContent); } [Then("the response should contain a '(.*)' header")] [Then("the response should contain an '(.*)' header")] public void ThenTheResponseShouldContainAHeader(string headerName) { - HttpResponseMessage response = this.ScenarioContext.Get(); - Assert.IsTrue(response.Headers.Contains(headerName)); + Assert.IsTrue(this.Response.Headers.Contains(headerName)); } [Then("the response should not contain a '(.*)' header")] [Then("the response should not contain an '(.*)' header")] public void ThenTheResponseShouldNotContainAHeader(string headerName) { - HttpResponseMessage response = this.ScenarioContext.Get(); - Assert.IsFalse(response.Headers.Contains(headerName)); + Assert.IsFalse(this.Response.Headers.Contains(headerName)); } [Then("the response should contain a '(.*)' header with value '(.*)'")] [Then("the response should contain an '(.*)' header with value '(.*)'")] public void ThenTheResponseShouldContainAHeaderWithValue(string headerName, string expectedValue) { - HttpResponseMessage response = this.ScenarioContext.Get(); - Assert.IsTrue(response.Headers.Contains(headerName)); + Assert.IsTrue(this.Response.Headers.Contains(headerName)); - string value = response.Headers.GetValues(headerName).First(); + string value = this.Response.Headers.GetValues(headerName).First(); Assert.AreEqual(expectedValue, value); } @@ -128,17 +136,12 @@ private async Task SendGetRequest(Uri baseUri, string path, string? etag = null) request.Headers.Add("If-None-Match", etag); } - HttpResponseMessage response = await HttpClient.SendAsync(request).ConfigureAwait(false); - - this.ScenarioContext.Set(response); - - string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + this.response = await HttpClient.SendAsync(request).ConfigureAwait(false); + this.responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - this.ScenarioContext.Set(content, ResponseContent); - - if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(content)) + if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(this.responseContent)) { - var parsedResponse = JObject.Parse(content); + var parsedResponse = JObject.Parse(this.responseContent); this.ScenarioContext.Set(parsedResponse); } } @@ -155,16 +158,8 @@ private async Task SendPostRequest(Uri baseUri, string path, object? data) content = new StringContent(requestJson, Encoding.UTF8, "application/json"); } - HttpResponseMessage response = await HttpClient.PostAsync(new Uri(baseUri, path), content).ConfigureAwait(false); - - this.ScenarioContext.Set(response); - - string responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - if (!string.IsNullOrEmpty(ResponseContent)) - { - this.ScenarioContext.Set(responseContent, ResponseContent); - } + this.response = await HttpClient.PostAsync(new Uri(baseUri, path), content).ConfigureAwait(false); + this.responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); } } } diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyClientSteps.cs b/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyClientSteps.cs index 4070333e..82e56acd 100644 --- a/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyClientSteps.cs +++ b/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyClientSteps.cs @@ -11,6 +11,8 @@ using Corvus.Testing.SpecFlow; using Marain.Tenancy.Client; using Marain.Tenancy.Client.Models; + using Marain.Tenancy.Specs.Integration.Bindings; + using Microsoft.Extensions.DependencyInjection; using Microsoft.Rest; using Newtonsoft.Json.Linq; @@ -21,14 +23,18 @@ public class TenancyClientSteps { private readonly ScenarioContext scenarioContext; + private readonly TestTenantCleanup testTenantCleanup; private readonly ITenantStore store; private readonly ITenancyService client; private readonly IJsonNetPropertyBagFactory propertyBagFactory; - public TenancyClientSteps(FeatureContext featureContext, ScenarioContext scenarioContext) + public TenancyClientSteps( + FeatureContext featureContext, + ScenarioContext scenarioContext, + TestTenantCleanup testTenantCleanup) { this.scenarioContext = scenarioContext; - + this.testTenantCleanup = testTenantCleanup; this.store = ContainerBindings.GetServiceProvider(featureContext).GetRequiredService(); this.client = ContainerBindings.GetServiceProvider(featureContext).GetRequiredService(); this.propertyBagFactory = ContainerBindings.GetServiceProvider(featureContext).GetRequiredService(); @@ -125,6 +131,7 @@ public void ThenTheTenantCalledShouldHaveTheProperties(string tenantName, Table public async Task GivenICreateAChildTenantCalledForTheRootTenant(string tenantName) { ITenant tenant = await this.store.CreateChildTenantAsync(RootTenant.RootTenantId, tenantName).ConfigureAwait(false); + this.testTenantCleanup.AddTenantToDelete(RootTenant.RootTenantId, tenant.Id); this.scenarioContext.Set(tenant, tenantName); } @@ -133,6 +140,7 @@ public async Task GivenICreateAChildTenantCalledForTheTenantCalled(string childN { ITenant parentTenant = this.scenarioContext.Get(parentName); ITenant tenant = await this.store.CreateChildTenantAsync(parentTenant.Id, childName).ConfigureAwait(false); + this.testTenantCleanup.AddTenantToDelete(parentTenant.Id, tenant.Id); this.scenarioContext.Set(tenant, childName); } diff --git a/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.v3.ncrunchproject b/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.v3.ncrunchproject new file mode 100644 index 00000000..eacd1901 --- /dev/null +++ b/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.v3.ncrunchproject @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Specs/packages.lock.json index 70d2c676..aa8a57b4 100644 --- a/Solutions/Marain.Tenancy.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Specs/packages.lock.json @@ -85,20 +85,6 @@ "System.Xml.XmlDocument": "4.3.0" } }, - "Corvus.Azure.Storage.Tenancy": { - "type": "Transitive", - "resolved": "2.0.13", - "contentHash": "naqlx/mpp9OXw0DWQCUMZ93mmyLiLDdk+SSxR9iBMdZXgy/76iO331C5L1Ee24pKizqIq8tmibN35sUr9KN8KA==", - "dependencies": { - "Corvus.Tenancy.Abstractions": "2.0.13", - "Microsoft.Azure.Cosmos.Table": "1.0.8", - "Microsoft.Azure.KeyVault": "3.0.5", - "Microsoft.Azure.Services.AppAuthentication": "1.6.2", - "Microsoft.Azure.Storage.Blob": "11.2.3", - "Microsoft.Extensions.Logging.Abstractions": "3.1.20", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.20" - } - }, "Corvus.ContentHandling": { "type": "Transitive", "resolved": "2.0.11", @@ -162,21 +148,12 @@ }, "Corvus.Tenancy.Abstractions": { "type": "Transitive", - "resolved": "2.0.13", - "contentHash": "uZxeWtTHYmjI580a+MnrwvgW5KLjhXbDA6o0A5Xo1xPRC3cn2xPXXvfO+ClHtJuyh2bzL8gaWjXyj85N4q5oVg==", + "resolved": "3.0.0-v3-blob.11", + "contentHash": "bRhFGCHioBAMbGxPLmfIXKYWq9Tx18gMPZ5aISVgVoRErxt9TNIOkLhQG3WkjayX22bA9zWSm9vg4qG3DIsRPg==", "dependencies": { "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Microsoft.Extensions.Primitives": "3.1.20" - } - }, - "Corvus.Tenancy.Storage.Azure.Blob": { - "type": "Transitive", - "resolved": "2.0.13", - "contentHash": "dOiRROsPh90WZsejYWSQlIspeC9sGbpzuVFrc+GbfbFoUNvxSpxsFdD2ZNsdOWWE+gBYOIRHMMek1hL2welMTw==", - "dependencies": { - "Corvus.Azure.Storage.Tenancy": "2.0.13", - "Corvus.Tenancy.Abstractions": "2.0.13" + "Microsoft.Extensions.Primitives": "3.1.21" } }, "Corvus.Testing.AzureFunctions": { @@ -307,105 +284,15 @@ "System.Text.Encodings.Web": "4.5.0" } }, - "Microsoft.Azure.Cosmos.Table": { - "type": "Transitive", - "resolved": "1.0.8", - "contentHash": "ToeEd1yijM7nQfLYvdFLG//RjKPmfqm45eOm86UAKrxtyGI/CXqP8iL74mzBp6mZ9A/K/ZYA2fVdpH0xHR5Keg==", - "dependencies": { - "Microsoft.Azure.DocumentDB.Core": "2.11.2", - "Microsoft.OData.Core": "7.6.4", - "Newtonsoft.Json": "10.0.2" - } - }, - "Microsoft.Azure.DocumentDB.Core": { - "type": "Transitive", - "resolved": "2.11.2", - "contentHash": "cA8eWrTFbYrkHrz095x4CUGb7wqQgA1slzFZCYexhNwz6Zcn3v+S1yvWMGwGRmRjT0MKU9tYdFWgLfT0OjSycw==", - "dependencies": { - "NETStandard.Library": "1.6.0", - "Newtonsoft.Json": "9.0.1", - "System.Collections.Immutable": "1.3.0", - "System.Collections.NonGeneric": "4.0.1", - "System.Collections.Specialized": "4.0.1", - "System.Diagnostics.TraceSource": "4.0.0", - "System.Dynamic.Runtime": "4.0.11", - "System.Linq.Queryable": "4.0.1", - "System.Net.Http": "4.3.4", - "System.Net.NameResolution": "4.0.0", - "System.Net.NetworkInformation": "4.1.0", - "System.Net.Requests": "4.0.11", - "System.Net.Security": "4.3.2", - "System.Net.WebHeaderCollection": "4.0.1", - "System.Runtime.Serialization.Primitives": "4.1.1", - "System.Security.SecureString": "4.0.0" - } - }, - "Microsoft.Azure.KeyVault": { - "type": "Transitive", - "resolved": "3.0.5", - "contentHash": "hbWw44JCJhk7e+CFeqSD1iQ2k4MP6bVVahEd9Cd1OP6JNyy0Y/S+9almtadH3vUoeDQsBAoQmzGImNoK3gxpog==", - "dependencies": { - "Microsoft.Azure.KeyVault.WebKey": "3.0.5", - "Microsoft.Rest.ClientRuntime": "[2.3.20, 3.0.0)", - "Microsoft.Rest.ClientRuntime.Azure": "[3.3.18, 4.0.0)", - "Newtonsoft.Json": "10.0.3", - "System.Net.Http": "4.3.4" - } - }, - "Microsoft.Azure.KeyVault.Core": { - "type": "Transitive", - "resolved": "2.0.4", - "contentHash": "BSdPbmZ1BvptdfgECniezEwfQLAyT11MsOm4btXdswjIm8BkLK9eX//yO8ExlafErJg1tAKpCxfNyLTHSlXJvA==", - "dependencies": { - "System.Runtime": "4.1.0", - "System.Threading.Tasks": "4.0.11" - } - }, - "Microsoft.Azure.KeyVault.WebKey": { - "type": "Transitive", - "resolved": "3.0.5", - "contentHash": "LmvQxr3qaK1rEMcsQCIz88T4LT6Mskd3mS425iXGFargt/FHS/p4lT++gBlsB3IZyU/opM7v8Yruzp13xu/I8g==", - "dependencies": { - "Microsoft.Rest.ClientRuntime": "[2.3.20, 3.0.0)", - "Microsoft.Rest.ClientRuntime.Azure": "[3.3.18, 4.0.0)", - "Newtonsoft.Json": "10.0.3", - "System.Collections": "4.3.0", - "System.Collections.Concurrent": "4.3.0", - "System.Linq": "4.3.0", - "System.Net.Http": "4.3.4", - "System.Runtime": "4.3.0", - "System.Security.Cryptography.Algorithms": "4.3.0", - "System.Security.Cryptography.Cng": "4.3.0" - } - }, "Microsoft.Azure.Services.AppAuthentication": { "type": "Transitive", - "resolved": "1.6.2", - "contentHash": "rSQhTv43ionr9rWvE4vxIe/i73XR5hoBYfh7UUgdaVOGW1MZeikR9RmgaJhonTylimCcCuJvrU0zXsSIFOsTGw==", + "resolved": "1.6.1", + "contentHash": "78AcjpxnhJDov7HJa4kPpZxpI0coZhS0tdA9ZLUSPExKz5KTgfozayBTLAXDuTuq0gLRzFyf85SvIkrtbB8KpA==", "dependencies": { - "Microsoft.IdentityModel.Clients.ActiveDirectory": "5.2.9", + "Microsoft.IdentityModel.Clients.ActiveDirectory": "5.2.0", "System.Diagnostics.Process": "4.3.0" } }, - "Microsoft.Azure.Storage.Blob": { - "type": "Transitive", - "resolved": "11.2.3", - "contentHash": "gM48FyiinUQq+fiUFHf0hGwQaTug4b+zYcYjbZ1KpxC3RkSgOd3twL9Yv9MqpvTkMcexGLwtELYIBhaTQ3zd9A==", - "dependencies": { - "Microsoft.Azure.Storage.Common": "11.2.3", - "NETStandard.Library": "2.0.1" - } - }, - "Microsoft.Azure.Storage.Common": { - "type": "Transitive", - "resolved": "11.2.3", - "contentHash": "WqX0ckhXQSUIBEq6wd2xgFz3KPjIONfDdgNg1ClQYxYTvuXQv3g3cnL9DGXCvuxEFZNPk0BJdQeW+uZwGqdDjw==", - "dependencies": { - "Microsoft.Azure.KeyVault.Core": "2.0.4", - "NETStandard.Library": "2.0.1", - "Newtonsoft.Json": "10.0.2" - } - }, "Microsoft.CodeAnalysis.Analyzers": { "type": "Transitive", "resolved": "3.3.2", @@ -625,15 +512,14 @@ }, "Microsoft.IdentityModel.Clients.ActiveDirectory": { "type": "Transitive", - "resolved": "5.2.9", - "contentHash": "WhBAG/9hWiMHIXve4ZgwXP3spRwf7kFFfejf76QA5BvumgnPp8iDkDCiJugzAcpW1YaHB526z1UVxHhVT1E5qw==", + "resolved": "5.2.0", + "contentHash": "5zCom0plcWSAuPp2B/Fo7XFKdrPUOaE+1dhVW5Ui2Gny7YYv1fDJ1Z8GeZEJuCd3rKN4UBO834wPEhU5gIPQMw==", "dependencies": { "Microsoft.CSharp": "4.3.0", "NETStandard.Library": "1.6.1", "System.ComponentModel.TypeConverter": "4.3.0", "System.Dynamic.Runtime": "4.3.0", "System.Net.Http": "4.3.4", - "System.Private.Uri": "4.3.2", "System.Runtime.Serialization.Formatters": "4.3.0", "System.Runtime.Serialization.Json": "4.3.0", "System.Runtime.Serialization.Primitives": "4.3.0", @@ -668,22 +554,8 @@ }, "Microsoft.NETCore.Targets": { "type": "Transitive", - "resolved": "1.1.3", - "contentHash": "3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==" - }, - "Microsoft.OData.Core": { - "type": "Transitive", - "resolved": "7.6.4", - "contentHash": "/EjnJezMBjXf8OjcShhGzPY7pOO0CopgoZGhS6xsP3t2uhC+O72IBHgtQ7F3v1rRXWVtJwLGhzE1GfJUlx3c4Q==", - "dependencies": { - "Microsoft.OData.Edm": "[7.6.4]", - "Microsoft.Spatial": "[7.6.4]" - } - }, - "Microsoft.OData.Edm": { - "type": "Transitive", - "resolved": "7.6.4", - "contentHash": "MSSmA6kIfpgFTtNpOnnayoSj/6KSzHC1U9KOjF7cTA1PG4tZ7rIMi1pvjFc8CmYEvP4cxGl/+vrCn+HpK26HTQ==" + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" }, "Microsoft.OpenApi": { "type": "Transitive", @@ -707,21 +579,6 @@ "Newtonsoft.Json": "10.0.3" } }, - "Microsoft.Rest.ClientRuntime.Azure": { - "type": "Transitive", - "resolved": "3.3.18", - "contentHash": "pCtem10PRQYvzRiwJVInsccsqB0NrTjW83NF3zWk1LpN3IS0AneZKq89RyogDT7mRMT1Li/mLY8N8kU6RAiK0g==", - "dependencies": { - "Microsoft.Rest.ClientRuntime": "[2.3.17, 3.0.0)", - "NETStandard.Library": "1.6.1", - "Newtonsoft.Json": "10.0.3" - } - }, - "Microsoft.Spatial": { - "type": "Transitive", - "resolved": "7.6.4", - "contentHash": "3mB+Frn4LU4yb5ie9R752QiRn0Hvp9PITkSRofV/Lzm9EyLM87Fy9ziqgz75O/c712dh6GxuypMSBUGmNFwMeA==" - }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", "resolved": "16.10.0", @@ -770,8 +627,8 @@ }, "NETStandard.Library": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "oA6nwv9MhEKYvLpjZ0ggSpb1g4CQViDVQjLUcDWg598jtvJbpfeP2reqwI1GLW2TbxC/Ml7xL6BBR1HmKPXlTg==", + "resolved": "2.0.0", + "contentHash": "7jnbRU+L08FXKMxqUflxEXtVymWvNOrS8yHgu9s6EM8Anr6T/wIX4nZ08j/u3Asz+tCufp3YVwFSEvFTPYmBPA==", "dependencies": { "Microsoft.NETCore.Platforms": "1.1.0" } @@ -895,15 +752,6 @@ "Microsoft.NETCore.Targets": "1.1.0" } }, - "runtime.native.System.Net.Security": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "M2nN92ePS8BgQ2oi6Jj3PlTUzadYSIWLdZrHY1n1ZcW9o4wAQQ6W+aQ2lfq1ysZQfVCgDwY58alUdowrzezztg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.NETCore.Targets": "1.1.0" - } - }, "runtime.native.System.Security.Cryptography.Apple": { "type": "Transitive", "resolved": "4.3.0", @@ -1372,21 +1220,6 @@ "System.Threading": "4.3.0" } }, - "System.Linq.Queryable": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "Yn/WfYe9RoRfmSLvUt2JerP0BTGGykCZkQPgojaxgzF2N0oPo+/AhB8TXOpdCcNlrG3VRtsamtK2uzsp3cqRVw==", - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Linq": "4.1.0", - "System.Linq.Expressions": "4.1.0", - "System.Reflection": "4.1.0", - "System.Reflection.Extensions": "4.0.1", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0" - } - }, "System.Management": { "type": "Transitive", "resolved": "4.7.0", @@ -1435,57 +1268,6 @@ "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2" } }, - "System.Net.NameResolution": { - "type": "Transitive", - "resolved": "4.0.0", - "contentHash": "JdqRdM1Qym3YehqdKIi5LHrpypP4JMfxKQSNCJ2z4WawkG0il+N3XfNeJOxll2XrTnG7WgYYPoeiu/KOwg0DQw==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "System.Collections": "4.0.11", - "System.Diagnostics.Tracing": "4.1.0", - "System.Globalization": "4.0.11", - "System.Net.Primitives": "4.0.11", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.Handles": "4.0.1", - "System.Runtime.InteropServices": "4.1.0", - "System.Security.Principal.Windows": "4.0.0", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "runtime.native.System": "4.0.0" - } - }, - "System.Net.NetworkInformation": { - "type": "Transitive", - "resolved": "4.1.0", - "contentHash": "Q0rfeiW6QsiZuicGjrFA7cRr2+kXex0JIljTTxzI09GIftB8k+aNL31VsQD1sI2g31cw7UGDTgozA/FgeNSzsQ==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "Microsoft.Win32.Primitives": "4.0.1", - "System.Collections": "4.0.11", - "System.Diagnostics.Tracing": "4.1.0", - "System.Globalization": "4.0.11", - "System.IO": "4.1.0", - "System.IO.FileSystem": "4.0.1", - "System.IO.FileSystem.Primitives": "4.0.1", - "System.Linq": "4.1.0", - "System.Net.Primitives": "4.0.11", - "System.Net.Sockets": "4.1.0", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.Handles": "4.0.1", - "System.Runtime.InteropServices": "4.1.0", - "System.Security.Principal.Windows": "4.0.0", - "System.Threading": "4.0.11", - "System.Threading.Overlapped": "4.0.1", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Thread": "4.0.0", - "System.Threading.ThreadPool": "4.0.10", - "runtime.native.System": "4.0.0" - } - }, "System.Net.Primitives": { "type": "Transitive", "resolved": "4.3.0", @@ -1497,85 +1279,6 @@ "System.Runtime.Handles": "4.3.0" } }, - "System.Net.Requests": { - "type": "Transitive", - "resolved": "4.0.11", - "contentHash": "vxGt7C0cZixN+VqoSW4Yakc1Y9WknmxauDqzxgpw/FnBdz4kQNN51l4wxdXX5VY1xjqy//+G+4CvJWp1+f+y6Q==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tracing": "4.1.0", - "System.Globalization": "4.0.11", - "System.IO": "4.1.0", - "System.Net.Http": "4.1.0", - "System.Net.Primitives": "4.0.11", - "System.Net.WebHeaderCollection": "4.0.1", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11" - } - }, - "System.Net.Security": { - "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "xT2jbYpbBo3ha87rViHoTA6WdvqOAW37drmqyx/6LD8p7HEPT2qgdxoimRzWtPg8Jh4X5G9BV2seeTv4x6FYlA==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.Win32.Primitives": "4.3.0", - "System.Collections": "4.3.0", - "System.Collections.Concurrent": "4.3.0", - "System.Diagnostics.Tracing": "4.3.0", - "System.Globalization": "4.3.0", - "System.Globalization.Extensions": "4.3.0", - "System.IO": "4.3.0", - "System.Net.Primitives": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Runtime.Handles": "4.3.0", - "System.Runtime.InteropServices": "4.3.0", - "System.Security.Claims": "4.3.0", - "System.Security.Cryptography.Algorithms": "4.3.0", - "System.Security.Cryptography.Encoding": "4.3.0", - "System.Security.Cryptography.OpenSsl": "4.3.0", - "System.Security.Cryptography.Primitives": "4.3.0", - "System.Security.Cryptography.X509Certificates": "4.3.0", - "System.Security.Principal": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Threading": "4.3.0", - "System.Threading.Tasks": "4.3.0", - "System.Threading.ThreadPool": "4.3.0", - "runtime.native.System": "4.3.0", - "runtime.native.System.Net.Security": "4.3.0", - "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2" - } - }, - "System.Net.Sockets": { - "type": "Transitive", - "resolved": "4.1.0", - "contentHash": "xAz0N3dAV/aR/9g8r0Y5oEqU1JRsz29F5EGb/WVHmX3jVSLqi2/92M5hTad2aNWovruXrJpJtgZ9fccPMG9uSw==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "Microsoft.NETCore.Targets": "1.0.1", - "System.IO": "4.1.0", - "System.Net.Primitives": "4.0.11", - "System.Runtime": "4.1.0", - "System.Threading.Tasks": "4.0.11" - } - }, - "System.Net.WebHeaderCollection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "XX2TIAN+wBSAIV51BU2FvvXMdstUa8b0FBSZmDWjZdwUMmggQSifpTOZ5fNH20z9ZCg2fkV1L5SsZnpO2RQDRQ==", - "dependencies": { - "System.Collections": "4.0.11", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.Extensions": "4.1.0" - } - }, "System.ObjectModel": { "type": "Transitive", "resolved": "4.3.0", @@ -1620,15 +1323,6 @@ "System.Xml.XmlSerializer": "4.3.0" } }, - "System.Private.Uri": { - "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "o1+7RJnu3Ik3PazR7Z7tJhjPdE000Eq2KGLLWhqJJKXj04wrS8lwb1OFtDF9jzXXADhUuZNJZlPc98uwwqmpFA==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.1", - "Microsoft.NETCore.Targets": "1.1.3" - } - }, "System.Reflection": { "type": "Transitive", "resolved": "4.3.0", @@ -1846,20 +1540,6 @@ "System.Security.Principal.Windows": "4.7.0" } }, - "System.Security.Claims": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "P/+BR/2lnc4PNDHt/TPBAWHVMLMRHsyYZbU1NphW4HIWzCggz8mJbTQQ3MKljFE7LS3WagmVFuBgoLcFzYXlkA==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Security.Principal": "4.3.0" - } - }, "System.Security.Cryptography.Algorithms": { "type": "Transitive", "resolved": "4.3.0", @@ -2017,14 +1697,6 @@ "System.Security.AccessControl": "4.5.0" } }, - "System.Security.Principal": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "I1tkfQlAoMM2URscUtpcRo/hX0jinXx6a/KUtEQoz3owaYwl3qwsO8cbzYVVnjxrzxjHo3nJC+62uolgeGIS9A==", - "dependencies": { - "System.Runtime": "4.3.0" - } - }, "System.Security.Principal.Windows": { "type": "Transitive", "resolved": "4.7.0", @@ -2097,17 +1769,6 @@ "System.Threading.Tasks": "4.3.0" } }, - "System.Threading.Overlapped": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "f7aLuLkBoCQM2kng7zqLFBXz9Gk48gDK8lk1ih9rH/1arJJzZK9gJwNvPDhL6Ps/l6rwOr8jw+4FCHL0KKWiEg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime": "4.1.0", - "System.Runtime.Handles": "4.0.1" - } - }, "System.Threading.Tasks": { "type": "Transitive", "resolved": "4.3.0", @@ -2277,7 +1938,7 @@ "marain.tenancy.clienttenantprovider": { "type": "Project", "dependencies": { - "Corvus.Tenancy.Abstractions": "2.0.13", + "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", "Marain.Tenancy.Client": "1.0.0", "Microsoft.AspNetCore.WebUtilities": "2.2.0" } @@ -2285,7 +1946,6 @@ "marain.tenancy.hosting.aspnetcore": { "type": "Project", "dependencies": { - "Corvus.Tenancy.Storage.Azure.Blob": "2.0.13", "Marain.Tenancy.OpenApi.Service": "1.0.0", "Menes.Hosting.AspNetCore": "3.0.0-preview.5" } @@ -2293,7 +1953,7 @@ "marain.tenancy.openapi.service": { "type": "Project", "dependencies": { - "Corvus.Azure.Storage.Tenancy": "2.0.13", + "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", "Menes.Abstractions": "2.0.1", "Microsoft.ApplicationInsights": "2.18.0", "Microsoft.AspNetCore.JsonPatch": "2.2.0", diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/ITenancyContainerSetup.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/ITenancyContainerSetup.cs new file mode 100644 index 00000000..166189fc --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/ITenancyContainerSetup.cs @@ -0,0 +1,31 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings +{ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + using Corvus.Tenancy; + + internal interface ITenancyContainerSetup + { + Task EnsureWellKnownChildTenantExistsAsync( + string parentId, + Guid id, + string name, + bool useV2Style, + IEnumerable>? properties = null); + + Task EnsureChildTenantExistsAsync( + string parentId, + string name, + bool useV2Style, + IEnumerable>? properties = null) + => this.EnsureWellKnownChildTenantExistsAsync(parentId, Guid.NewGuid(), name, useV2Style, properties); + + Task DeleteTenantAsync(string tenantId, bool leaveContainer); + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/ScenarioDiContainer.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/ScenarioDiContainer.cs new file mode 100644 index 00000000..6a6a8f6c --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/ScenarioDiContainer.cs @@ -0,0 +1,114 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings +{ + using System; + + using Corvus.Storage.Azure.BlobStorage; + using Corvus.Tenancy; + using Corvus.Testing.SpecFlow; + + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + + using NUnit.Framework.Internal; + + using TechTalk.SpecFlow; + + /// + /// Sets up the DI container used by tests with the @withBlobStorageTenantProvider tag. + /// + [Binding] + public class ScenarioDiContainer + { + private readonly ScenarioContext scenarioContext; + private ITenantStore? tenantStore; + private IServiceProvider? serviceProvider; + private BlobContainerConfiguration? rootBlobStorageConfiguration; + + /// + /// Creates a . + /// + /// The scenario context from SpecFlow. + public ScenarioDiContainer(ScenarioContext scenarioContext) + { + this.scenarioContext = scenarioContext; + + this.SetupMode = TestExecutionContext.CurrentContext.TestObject switch + { + IMultiModeTest multiModeTest => multiModeTest.TestType, + _ => SetupModes.ViaApiPropagateRootConfigAsV3, + }; + + this.PropagateRootTenancyStorageConfigAsV2 = this.SetupMode is + SetupModes.ViaApiPropagateRootConfigAsV2 or SetupModes.DirectToStoragePropagateRootConfigAsV2; + + this.Configuration = new ConfigurationBuilder() + .AddEnvironmentVariables() + .AddJsonFile("local.settings.json", true, true) + .Build(); + } + + /// + /// Gets the configuration root. + /// + public IConfiguration Configuration { get; } + + public IServiceProvider ServiceProvider => this.serviceProvider + ?? throw new InvalidOperationException("Not available until DI initialization complete"); + + /// + /// Gets the blob storage configuration to use for the root tenant. + /// + public BlobContainerConfiguration RootBlobStorageConfiguration => this.rootBlobStorageConfiguration + ?? throw new InvalidOperationException("Not available until DI initialization complete"); + + /// + /// Gets the mode to use when setting up the containers in tests. + /// + public SetupModes SetupMode { get; } + + /// + /// Gets the ITenantStore implementation to test. + /// + public ITenantStore TenantStore => this.tenantStore + ?? throw new InvalidOperationException("Not available until DI initialization complete"); + + /// + /// Gets a value indicating whether the root tenancy configuration is propagated in V2 or + /// V3 style. + /// + public bool PropagateRootTenancyStorageConfigAsV2 { get; } + + /// + /// Configure the DI container. Called by SpecFlow. + /// + [BeforeScenario("@withBlobStorageTenantProvider", Order = ContainerBeforeScenarioOrder.PopulateServiceCollection)] + public void ConfigureServices() + { + ContainerBindings.ConfigureServices(this.scenarioContext, services => + { + this.rootBlobStorageConfiguration = this.Configuration + .GetSection("RootBlobStorageConfiguration") + .Get(); + services.AddTenantStoreOnAzureBlobStorage( + this.rootBlobStorageConfiguration, + this.PropagateRootTenancyStorageConfigAsV2); + }); + } + + /// + /// Retrieve initialization services to the DI container. Called by SpecFlow. + /// + [BeforeScenario("@withBlobStorageTenantProvider", Order = ContainerBeforeScenarioOrder.ServiceProviderAvailable)] + public void InitializeServiceProperties() + { + this.serviceProvider = ContainerBindings.GetServiceProvider(this.scenarioContext); + this.tenantStore = this.serviceProvider.GetRequiredService(); + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs new file mode 100644 index 00000000..5c4d0bfe --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs @@ -0,0 +1,148 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Security.Cryptography; + using System.Text; + using System.Threading.Tasks; + + using Corvus.Extensions.Json; + using Corvus.Json; + using Corvus.Storage.Azure.BlobStorage; + using Corvus.Storage.Azure.BlobStorage.Tenancy; + using Corvus.Tenancy; + + using global::Azure; + using global::Azure.Storage.Blobs; + using global::Azure.Storage.Blobs.Models; + using global::Azure.Storage.Blobs.Specialized; + + using Newtonsoft.Json; + + using NUnit.Framework.Constraints; + + internal class TenancyContainerSetupDirectToStorage : ITenancyContainerSetup + { + private readonly BlobContainerConfiguration configuration; + private readonly IBlobContainerSourceByConfiguration blobContainerSource; + private readonly IPropertyBagFactory propertyBagFactory; + private readonly JsonSerializer jsonSerializer; + + public TenancyContainerSetupDirectToStorage( + BlobContainerConfiguration configuration, + IBlobContainerSourceByConfiguration blobContainerSource, + IJsonSerializerSettingsProvider serializerSettingsProvider, + IPropertyBagFactory propertyBagFactory) + { + this.configuration = configuration; + this.blobContainerSource = blobContainerSource; + this.propertyBagFactory = propertyBagFactory; + + this.jsonSerializer = JsonSerializer.Create(serializerSettingsProvider.Instance); + } + + public async Task EnsureWellKnownChildTenantExistsAsync( + string parentId, + Guid id, + string name, + bool useV2Style, + IEnumerable>? properties = null) + { + BlobServiceClient serviceClient = await this.GetBlobServiceClientAsync().ConfigureAwait(false); + + // Note that we're not creating containers all the way down. This requires all + // tenants from the root down to the parent of the new one to exist. We only + // create the last one. + // For test purposes, we set the root config into all child tenants instead of + // propagating from the parent (because currently, no tests require anything more + // complex than that). + string newTenantId = parentId.CreateChildId(id); + BlobContainerClient parentContainer = GetBlobContainerForTenant(parentId, serviceClient); + await parentContainer.CreateIfNotExistsAsync().ConfigureAwait(false); + BlobContainerClient newTenantContainer = GetBlobContainerForTenant(newTenantId, serviceClient); + await newTenantContainer.CreateIfNotExistsAsync().ConfigureAwait(false); + BlockBlobClient tenantBlobInParentContainer = parentContainer.GetBlockBlobClient(@"live\" + newTenantId); + + KeyValuePair storageConfig = useV2Style + ? new KeyValuePair( + "StorageConfiguration__corvustenancy", + new LegacyV2BlobStorageConfiguration + { + AccountName = this.configuration.ConnectionStringPlainText != null + ? this.configuration.ConnectionStringPlainText + : this.configuration.AccountName, + KeyVaultName = this.configuration.AccessKeyInKeyVault?.VaultName, + AccountKeySecretName = this.configuration.AccessKeyInKeyVault?.SecretName, + }) + : new KeyValuePair("StorageConfigurationV3__corvustenancy", this.configuration); + + IPropertyBag tenantProperties = this.propertyBagFactory.Create(PropertyBagValues.Build(values => + values + .Concat(properties ?? Enumerable.Empty>()) + .Append(storageConfig))); + Tenant newTenant = new (newTenantId, name, tenantProperties); + var content = new MemoryStream(); + using (var sw = new StreamWriter(content, new UTF8Encoding(false), leaveOpen: true)) + using (JsonWriter writer = new JsonTextWriter(sw)) + { + this.jsonSerializer.Serialize(writer, newTenant); + } + + content.Position = 0; + Response blobUploadResponse = await tenantBlobInParentContainer.UploadAsync(content).ConfigureAwait(false); + newTenant.ETag = blobUploadResponse.Value.ETag.ToString("H"); + + return newTenant; + } + + public async Task DeleteTenantAsync(string tenantId, bool leaveContainer) + { + BlobServiceClient serviceClient = await this.GetBlobServiceClientAsync().ConfigureAwait(false); + + string parentId = TenantExtensions.GetRequiredParentId(tenantId); + BlobContainerClient parentContainer = GetBlobContainerForTenant(parentId, serviceClient); + BlobContainerClient tenantContainer = GetBlobContainerForTenant(tenantId, serviceClient); + BlockBlobClient tenantBlobInParentContainer = parentContainer.GetBlockBlobClient(@"live\" + tenantId); + await tenantBlobInParentContainer.DeleteAsync().ConfigureAwait(false); + + if (!leaveContainer) + { + await tenantContainer.DeleteAsync().ConfigureAwait(false); + } + } + + private static string HashAndEncodeBlobContainerName(string containerName) + { + byte[] byteContents = Encoding.UTF8.GetBytes(containerName); + using SHA1CryptoServiceProvider hash = new (); + byte[] hashedBytes = hash.ComputeHash(byteContents); + return TenantExtensions.ByteArrayToHexViaLookup32(hashedBytes); + } + + private static BlobContainerClient GetBlobContainerForTenant(string tenantId, BlobServiceClient serviceClient) + { + string tenantedContainerName = $"{tenantId.ToLowerInvariant()}-corvustenancy"; + string containerName = HashAndEncodeBlobContainerName(tenantedContainerName); + + BlobContainerClient container = serviceClient.GetBlobContainerClient(containerName); + return container; + } + + private async Task GetBlobServiceClientAsync() + { + // We're using Corvus.Storage to process the configuration, but all we actually need + // from it is a BlobServiceClient, because for this test mode, we want to work + // directly with the storage API to validate that it works when the storage account + // wasn't previously populated by the current Corvus and Marain APIs. + BlobContainerClient rootTenantContainerFromConfig = await this.blobContainerSource.GetStorageContextAsync( + this.configuration.ForContainer("dummy")); + return rootTenantContainerFromConfig.GetParentBlobServiceClient(); + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs new file mode 100644 index 00000000..de92ef05 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs @@ -0,0 +1,145 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings +{ + using System; + using System.Collections.Generic; + using System.Security.Cryptography; + using System.Text; + using System.Threading.Tasks; + + using Corvus.Storage.Azure.BlobStorage; + using Corvus.Storage.Azure.BlobStorage.Tenancy; + using Corvus.Tenancy; + + using global::Azure.Storage.Blobs; + using global::Azure.Storage.Blobs.Specialized; + + internal class TenancyContainerSetupViaApi : ITenancyContainerSetup + { + private readonly BlobContainerConfiguration configuration; + + // Deferred tenant store fetching - it's important we don't try to use this before + // we need it because it's not available until after the DI container has been built. + private readonly Func getTenantStore; + private readonly IBlobContainerSourceByConfiguration blobContainerSource; + + public TenancyContainerSetupViaApi( + BlobContainerConfiguration configuration, + Func getTenantStore, + IBlobContainerSourceByConfiguration blobContainerSource) + { + this.configuration = configuration; + this.getTenantStore = getTenantStore; + this.blobContainerSource = blobContainerSource; + } + + private ITenantStore Store => this.getTenantStore(); + + public async Task EnsureWellKnownChildTenantExistsAsync( + string parentId, + Guid id, + string name, + bool useV2Style, + IEnumerable>? properties = null) + { + ITenant newTenant = await this.Store.CreateWellKnownChildTenantAsync(parentId, id, name); + + if (properties is not null) + { + newTenant = await this.Store.UpdateTenantAsync(newTenant.Id, propertiesToSetOrAdd: properties); + } + + KeyValuePair? storageConfig = null; + if (useV2Style) + { + if (newTenant.Properties.TryGet("StorageConfigurationV3__corvustenancy", out BlobContainerConfiguration v3Config)) + { + var v2Config = new LegacyV2BlobStorageConfiguration + { + AccountName = v3Config.ConnectionStringPlainText != null + ? v3Config.ConnectionStringPlainText + : v3Config.AccountName, + KeyVaultName = v3Config.AccessKeyInKeyVault?.VaultName, + AccountKeySecretName = v3Config.AccessKeyInKeyVault?.SecretName, + }; + + storageConfig = new ("StorageConfiguration__corvustenancy", v2Config); + } + } + else + { + if (newTenant.Properties.TryGet("StorageConfigurationV__corvustenancy", out LegacyV2BlobStorageConfiguration v2Config)) + { + BlobContainerConfiguration v3Config = LegacyConfigurationConverter.FromV2ToV3(v2Config); + + storageConfig = new ("StorageConfigurationV3__corvustenancy", v3Config); + } + } + + if (storageConfig is KeyValuePair nnsc) + { + newTenant = await this.Store.UpdateTenantAsync( + newTenant.Id, + propertiesToSetOrAdd: new[] { nnsc }); + } + + return newTenant; + } + + public async Task EnsureChildTenantExistsAsync(string parentId, string name) + { + return await this.Store.CreateChildTenantAsync(parentId, name); + } + + public async Task DeleteTenantAsync(string tenantId, bool leaveContainer) + { + // We talk directly to the storage service here because for well-known tenants + // we need to leave container in place to avoid tests failure with + // Status: 409 (The specified container is being deleted. Try operation later.) + // when we try to create a container with the same name as one we just deleted. + BlobServiceClient serviceClient = await this.GetBlobServiceClientAsync().ConfigureAwait(false); + + string parentId = TenantExtensions.GetRequiredParentId(tenantId); + BlobContainerClient parentContainer = GetBlobContainerForTenant(parentId, serviceClient); + BlobContainerClient tenantContainer = GetBlobContainerForTenant(tenantId, serviceClient); + BlockBlobClient tenantBlobInParentContainer = parentContainer.GetBlockBlobClient(@"live\" + tenantId); + await tenantBlobInParentContainer.DeleteAsync().ConfigureAwait(false); + + if (!leaveContainer) + { + await tenantContainer.DeleteAsync().ConfigureAwait(false); + } + } + + private static string HashAndEncodeBlobContainerName(string containerName) + { + byte[] byteContents = Encoding.UTF8.GetBytes(containerName); + using SHA1CryptoServiceProvider hash = new (); + byte[] hashedBytes = hash.ComputeHash(byteContents); + return TenantExtensions.ByteArrayToHexViaLookup32(hashedBytes); + } + + private static BlobContainerClient GetBlobContainerForTenant(string tenantId, BlobServiceClient serviceClient) + { + string tenantedContainerName = $"{tenantId.ToLowerInvariant()}-corvustenancy"; + string containerName = HashAndEncodeBlobContainerName(tenantedContainerName); + + BlobContainerClient container = serviceClient.GetBlobContainerClient(containerName); + return container; + } + + private async Task GetBlobServiceClientAsync() + { + // We're using Corvus.Storage to process the configuration, but all we actually need + // from it is a BlobServiceClient, because for this test mode, we want to work + // directly with the storage API to validate that it works when the storage account + // wasn't previously populated by the current Corvus and Marain APIs. + BlobContainerClient rootTenantContainerFromConfig = await this.blobContainerSource.GetStorageContextAsync( + this.configuration.ForContainer("dummy")); + return rootTenantContainerFromConfig.GetParentBlobServiceClient(); + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantProperties.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantProperties.cs new file mode 100644 index 00000000..c8071655 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantProperties.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings +{ + using System.Collections.Generic; + + using Corvus.Tenancy; + + public class TenantProperties + { + public TenantProperties(ScenarioDiContainer diContainer) + { + this.DiContainer = diContainer; + } + + public Dictionary Tenants { get; } = new Dictionary(); + + public HashSet TenantsToDelete { get; } = new HashSet(); + + public HashSet WellKnownTenantsToDelete { get; } = new HashSet(); + + public ScenarioDiContainer DiContainer { get; } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs new file mode 100644 index 00000000..61cba2a5 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs @@ -0,0 +1,128 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings +{ + using System; + using System.Linq; + using System.Threading.Tasks; + + using Corvus.Extensions.Json; + using Corvus.Json; + using Corvus.Storage.Azure.BlobStorage; + using Corvus.Tenancy; + + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + using Microsoft.Extensions.DependencyInjection; + + using TechTalk.SpecFlow; + + [Binding] + public class TenantSetupSteps : TenantStepsBase + { + private readonly ITenancyContainerSetup containerSetup; + + public TenantSetupSteps(TenantProperties tenantProperties) + : base(tenantProperties) + { + this.containerSetup = this.SetupMode switch + { + SetupModes.ViaApiPropagateRootConfigAsV2 or SetupModes.ViaApiPropagateRootConfigAsV3 => new TenancyContainerSetupViaApi( + this.DiContainer.RootBlobStorageConfiguration, + () => this.TenantStore, + this.DiContainer.ServiceProvider.GetRequiredService()), + SetupModes.DirectToStoragePropagateRootConfigAsV2 or SetupModes.DirectToStoragePropagateRootConfigAsV3 => new TenancyContainerSetupDirectToStorage( + this.DiContainer.RootBlobStorageConfiguration, + this.DiContainer.ServiceProvider.GetRequiredService(), + this.DiContainer.ServiceProvider.GetRequiredService(), + this.DiContainer.ServiceProvider.GetRequiredService()), + _ => throw new InvalidOperationException($"Unknown setup mode: {this.SetupMode}"), + }; + } + + [Given("the root tenant has a child tenant called '([^']*)' labelled '([^']*)'")] + public async Task GivenTheRootTenantHasAChildTenantCalled( + string tenantName, string tenantLabel) + { + ITenant newTenant = await this.containerSetup.EnsureChildTenantExistsAsync( + RootTenant.RootTenantId, tenantName, this.PropagateRootTenancyStorageConfigAsV2); + this.Tenants.Add(tenantLabel, newTenant); + this.AddTenantToDelete(newTenant.Id); + } + + [Given("the root tenant has v2 a child tenant called '([^']*)' labelled '([^']*)'")] + public async Task GivenTheRootTenantHasAv2stylChildTenantCalled( + string tenantName, string tenantLabel) + { + ITenant newTenant = await this.containerSetup.EnsureChildTenantExistsAsync( + RootTenant.RootTenantId, tenantName, true); + this.Tenants.Add(tenantLabel, newTenant); + this.AddTenantToDelete(newTenant.Id); + } + + [Given("the root tenant has a child tenant called '([^']*)' labelled '([^']*)' with these properties")] + public async Task GivenTheRootTenantHasAChildTenantWithPropertiesCalled( + string tenantName, string tenantLabel, Table propertyTable) + { + ITenant newTenant = await this.containerSetup.EnsureChildTenantExistsAsync( + RootTenant.RootTenantId, tenantName, this.PropagateRootTenancyStorageConfigAsV2, ReadPropertiesTable(propertyTable)); + this.Tenants.Add(tenantLabel, newTenant); + this.AddTenantToDelete(newTenant.Id); + } + + [Given("the root tenant has a well-known child tenant called '([^']*)' with a Guid of '([^']*)' labelled '([^']*)'")] + public async Task GivenTheRootTenantHasAWellKnownChildTenantCalled( + string tenantName, Guid wellKnownId, string tenantLabel) + { + ITenant newTenant = await this.containerSetup.EnsureWellKnownChildTenantExistsAsync( + RootTenant.RootTenantId, wellKnownId, tenantName, this.PropagateRootTenancyStorageConfigAsV2); + this.Tenants.Add(tenantLabel, newTenant); + + this.AddWellKnownTenantToDelete(newTenant.Id); + } + + [Given("the tenant labelled '([^']*)' has a child tenant called '([^']*)' labelled '([^']*)'")] + public async Task GivenTheRootTenantHasAChildTenantCalled( + string parentTenantLabel, string tenantName, string newTenantLabel) + { + ITenant parent = this.Tenants[parentTenantLabel]; + ITenant newTenant = await this.containerSetup.EnsureChildTenantExistsAsync( + parent.Id, tenantName, this.PropagateRootTenancyStorageConfigAsV2); + this.Tenants.Add(newTenantLabel, newTenant); + this.AddTenantToDelete(newTenant.Id); + } + + [Given("the tenant labelled '([^']*)' has a well-known child tenant called '([^']*)' with a Guid of '([^']*)' labelled '([^']*)'")] + public async Task GivenTheRootTenantHasAChildTenantCalled( + string parentTenantLabel, string tenantName, Guid wellKnownId, string newTenantLabel) + { + ITenant parent = this.Tenants[parentTenantLabel]; + ITenant newTenant = await this.containerSetup.EnsureWellKnownChildTenantExistsAsync( + parent.Id, wellKnownId, tenantName, this.PropagateRootTenancyStorageConfigAsV2); + this.Tenants.Add(newTenantLabel, newTenant); + this.AddWellKnownTenantToDelete(newTenant.Id); + } + + [AfterScenario("@withBlobStorageTenantProvider")] + public async Task DeleteTenantsCreatedByTests() + { + // We delete tenants with longer names first to ensure that we delete child tenants before their + // parents, as otherwise, things go wrong. + foreach (string tenantId in this.TenantsToDelete.OrderByDescending(id => id.Length)) + { + await this.containerSetup.DeleteTenantAsync(tenantId, leaveContainer: false).ConfigureAwait(false); + } + + foreach (string tenantId in this.WellKnownTenantsToDelete.OrderByDescending(id => id.Length)) + { + // We don't delete the container when it's a well-known tenant, because otherwise + // we get problems with being unable to recreate a new container with the same name + // as one we just deleted when running tests against real storage accounts. + // So we just delete the blob. + await this.containerSetup.DeleteTenantAsync(tenantId, leaveContainer: true).ConfigureAwait(false); + } + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantStepsBase.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantStepsBase.cs new file mode 100644 index 00000000..f5644e17 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantStepsBase.cs @@ -0,0 +1,78 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings +{ + using System; + using System.Collections.Generic; + using System.Linq; + + using Corvus.Tenancy; + + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + using TechTalk.SpecFlow; + + public abstract class TenantStepsBase + { + private readonly TenantProperties tenantProperties; + + public TenantStepsBase(TenantProperties tenantProperties) + { + this.tenantProperties = tenantProperties; + } + + public ScenarioDiContainer DiContainer => this.tenantProperties.DiContainer; + + public Dictionary Tenants => this.tenantProperties.Tenants; + + public HashSet TenantsToDelete => this.tenantProperties.TenantsToDelete; + + public HashSet WellKnownTenantsToDelete => this.tenantProperties.WellKnownTenantsToDelete; + + public ITenantStore TenantStore => this.DiContainer.TenantStore; + + /// + /// Gets the mode to use when setting up the containers in tests. + /// + public SetupModes SetupMode => this.DiContainer.SetupMode; + + /// + /// Gets a value indicating whether the root tenancy configuration is propagated in V2 or + /// V3 style. + /// + public bool PropagateRootTenancyStorageConfigAsV2 => this.DiContainer.PropagateRootTenancyStorageConfigAsV2; + + public void AddTenantToDelete(string id) + { + this.TenantsToDelete.Add(id); + } + + public void AddWellKnownTenantToDelete(string id) + { + this.WellKnownTenantsToDelete.Add(id); + } + + public void TenantNoLongerRequiresDeletion(string id) + { + this.TenantsToDelete.Remove(id); + } + + protected static IEnumerable> ReadPropertiesTable(Table propertyTable) + { + return propertyTable.Rows.Select(row => + { + string value = row["Value"]; + object interprettedValue = row["Type"] switch + { + "string" => value, + "integer" => int.Parse(value), + "datetimeoffset" => DateTimeOffset.Parse(value), + string t => throw new InvalidOperationException($"Unknown type {t} in test table") + }; + return new KeyValuePair(row["Key"], interprettedValue); + }); + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature new file mode 100644 index 00000000..956dcd7e --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature @@ -0,0 +1,55 @@ +@perScenarioContainer +@withBlobStorageTenantProvider + +Feature: CreateTenant + In order to manage tenants and their configuration + As a tenant owner + I want to be able to create new tenants as children of tenants I control + + +Scenario: Create a child of the root tenant + When I create a child tenant of the root tenant called 'ChildTenant1' labelled 'ChildTenant' + And I get the tenant with the id from label 'ChildTenant' labelled 'Result' + Then the tenant details labelled 'ChildTenant' should match the tenant details labelled 'Result' + And the tenant labelled 'ChildTenant' should have storage configuration equivalent to the root + +Scenario: Create a child of the root tenant with a well known Id + When I create a well known child tenant of the root tenant called 'ChildTenant1' with a Guid of 'F446F305-993B-49A4-B5FA-010EE2AF0FA2' labelled 'ChildTenant' + And I get the tenant with the id from label 'ChildTenant' labelled 'Result' + Then the tenant details labelled 'ChildTenant' should match the tenant details labelled 'Result' + And the tenant details labelled 'ChildTenant' should have tenant Id '05f346f43b99a449b5fa010ee2af0fa2' + And the tenant labelled 'ChildTenant' should have storage configuration equivalent to the root + +Scenario: Create a child of a child of the root tenant + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'Tenant1' + When I create a child of the tenant labelled 'Tenant1' named 'ChildTenant2' labelled 'Tenant2' + And I get the tenant with the id from label 'Tenant2' labelled 'Result' + Then the tenant details labelled 'Tenant2' should match the tenant details labelled 'Result' + And the tenant labelled 'Tenant2' should have storage configuration equivalent to the root + +Scenario: Create a child of a child with well known Ids + Given the root tenant has a well-known child tenant called 'ChildTenant1' with a Guid of 'EE17B20B-B372-4493-8145-9DD95516B9AF' labelled 'Tenant1' + When I create a well known child of the tenant labelled 'Tenant1' named 'ChildTenant2' with a Guid of 'DD045C05-E7FB-4214-8878-F9E7CA9B0F5F' labelled 'Tenant2' + And I get the tenant with the id from label 'Tenant2' labelled 'Result' + Then the tenant details labelled 'Tenant2' should match the tenant details labelled 'Result' + And the tenant details labelled 'Tenant1' should have tenant Id '0bb217ee72b3934481459dd95516b9af' + And the tenant details labelled 'Tenant2' should have tenant Id '0bb217ee72b3934481459dd95516b9af055c04ddfbe714428878f9e7ca9b0f5f' + And the tenant labelled 'Tenant2' should have storage configuration equivalent to the root + +Scenario: Creating a child of a child with a well known Id that is already in use by a child of the same parent throws an ArgumentException + Given the root tenant has a well-known child tenant called 'ChildTenant1' with a Guid of 'ABE7C6C9-8494-4797-B52E-5C7B3EF1CE56' labelled 'Tenant1' + And the tenant labelled 'Tenant1' has a well-known child tenant called 'ChildTenant2' with a Guid of 'DD045C05-E7FB-4214-8878-F9E7CA9B0F5F' labelled 'Tenant2' + When I try to create a well known child of the tenant labelled 'Tenant1' named 'ChildTenant3' with a Guid of 'DD045C05-E7FB-4214-8878-F9E7CA9B0F5F' + Then CreateWellKnownChildTenantAsync thould throw an ArgumentException + +Scenario: Creating children that have the same well known Ids under different parents succeeds + Given the root tenant has a well-known child tenant called 'ChildTenant1' with a Guid of '2A182D6E-FF13-4A73-87AF-0B58D8243603' labelled 'Parent1' + And the root tenant has a well-known child tenant called 'ChildTenant2' with a Guid of '086D75A1-DA07-4C90-BEA7-857A6C126280' labelled 'Parent2' + And the tenant labelled 'Parent1' has a well-known child tenant called 'ChildTenant3' with a Guid of '2A182D6E-FF13-4A73-87AF-0B58D8243603' labelled 'ChildOfParent1' + When I create a well known child of the tenant labelled 'Parent2' named 'ChildTenant4' with a Guid of '2A182D6E-FF13-4A73-87AF-0B58D8243603' labelled 'ChildOfParent2' + And I get the tenant with the id from label 'ChildOfParent1' labelled 'Result1' + And I get the tenant with the id from label 'ChildOfParent2' labelled 'Result2' + Then the tenant details labelled 'Result1' should have tenant Id '6e2d182a13ff734a87af0b58d82436036e2d182a13ff734a87af0b58d8243603' + And the tenant details labelled 'Result2' should have tenant Id 'a1756d0807da904cbea7857a6c1262806e2d182a13ff734a87af0b58d8243603' + And the tenant labelled 'Result1' should have storage configuration equivalent to the root + And the tenant labelled 'Result2' should have storage configuration equivalent to the root diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature.multi.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature.multi.cs new file mode 100644 index 00000000..42d0f01d --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature.multi.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Features +{ + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + /// + /// Adds in multi-host-mode execution. + /// + [MultiSetupTest] + public partial class CreateTenantFeature : MultiSetupTestBase + { + /// + /// Creates a . + /// + /// + /// Hosting style to test for. + /// + public CreateTenantFeature(SetupModes hostMode) + : base(hostMode) + { + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature new file mode 100644 index 00000000..15e0c505 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature @@ -0,0 +1,28 @@ +@perScenarioContainer +@withBlobStorageTenantProvider + +Feature: DeleteTenant + In order to manage tenants and their configuration + As a tenant owner + I want to be able to delete existing tenants + +Scenario: Delete a child + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ParentTenant' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant2' labelled 'ChildTenant2' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant3' labelled 'ChildTenant3' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant4' labelled 'ChildTenant4' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant5' labelled 'ChildTenant5' + When I delete the tenant with the id from label 'ChildTenant3' + And I get the children of the tenant with the label 'ParentTenant' with maxItems 20 + Then the ids of all the children across all pages should match these tenant ids + | TenantName | + | ChildTenant2 | + | ChildTenant4 | + | ChildTenant5 | + +# TODO: +# Attempt to delete non-existent tenant +# Attempt to delete child for which parent is non-existent +# Attempt to delete a non-empty parent +# Delete child of a child? +# What happens if we try to delete the root? \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature.multi.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature.multi.cs new file mode 100644 index 00000000..50195d56 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature.multi.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Features +{ + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + /// + /// Adds in multi-host-mode execution. + /// + [MultiSetupTest] + public partial class DeleteTenantFeature : MultiSetupTestBase + { + /// + /// Creates a . + /// + /// + /// Hosting style to test for. + /// + public DeleteTenantFeature(SetupModes hostMode) + : base(hostMode) + { + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/EnumerateChildTenants.feature b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/EnumerateChildTenants.feature new file mode 100644 index 00000000..d9068e06 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/EnumerateChildTenants.feature @@ -0,0 +1,38 @@ +@perScenarioContainer +@withBlobStorageTenantProvider + +Feature: EnumerateChildTenants + In order to manage tenants and their configuration + As a tenant owner + I want to be able to retrieve stored tenant information + +Background: + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ParentTenant' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant2' labelled 'ChildTenant2' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant3' labelled 'ChildTenant3' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant4' labelled 'ChildTenant4' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant5' labelled 'ChildTenant5' + +Scenario: Get children + When I get the children of the tenant with the label 'ParentTenant' with maxItems 20 + Then the ids of the children for page 0 should match these tenant ids + | TenantName | + | ChildTenant2 | + | ChildTenant3 | + | ChildTenant4 | + | ChildTenant5 | + And the continuation token for page 0 should be null + +Scenario: Get children paginated + When I get the children of the tenant with the label 'ParentTenant' with maxItems 2 + And I continue getting the children of the tenant with the label 'ParentTenant' with maxItems 20 + Then page 0 returned by GetChildrenAsync should contain 2 items + And the continuation token for page 0 should not be null + And page 1 returned by GetChildrenAsync should contain 2 items + And the continuation token for page 1 should be null + And the ids of all the children across all pages should match these tenant ids + | TenantName | + | ChildTenant2 | + | ChildTenant3 | + | ChildTenant4 | + | ChildTenant5 | diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/EnumerateChildTenants.feature.multi.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/EnumerateChildTenants.feature.multi.cs new file mode 100644 index 00000000..c22e23d7 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/EnumerateChildTenants.feature.multi.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Features +{ + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + /// + /// Adds in multi-host-mode execution. + /// + [MultiSetupTest] + public partial class EnumerateChildTenantsFeature : MultiSetupTestBase + { + /// + /// Creates a . + /// + /// + /// Hosting style to test for. + /// + public EnumerateChildTenantsFeature(SetupModes hostMode) + : base(hostMode) + { + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/GetTenant.feature b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/GetTenant.feature new file mode 100644 index 00000000..d00bb0ee --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/GetTenant.feature @@ -0,0 +1,57 @@ +@perScenarioContainer +@withBlobStorageTenantProvider + +Feature: GetTenant + In order to manage tenants and their configuration + As a tenant owner + I want to be able to retrieve stored tenant information + +Scenario: Get the root tenant when the root container does not exist yet + When I get a tenant with the root id labelled 'RootTenant' + Then the tenant details labelled 'RootTenant' should have the root tenant id + And the tenant details labelled 'RootTenant' should have the root tenant name + # TODO: should we report an ETag for the root tenant? + +Scenario Outline: Get a child tenant when the root container does not exist yet + When I try to get a tenant with id '' + Then GetTenantAsync should throw a TenantNotFoundException + + Examples: + | tenantId | + | 156cf35866d7594b9913e21bd23b90b0 | + | NotValidTenantName | + +Scenario Outline: Get a child tenant when the root container does exist + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'Tenant1' + When I try to get a tenant with id '' + Then GetTenantAsync should throw a TenantNotFoundException + + Examples: + | tenantId | + | 156cf35866d7594b9913e21bd23b90b0 | + | NotValidTenantName | + +Scenario: Get a tenant that does not exist + When I try to get a tenant with id 'NotFound' + Then GetTenantAsync should throw a TenantNotFoundException + +Scenario: Get a tenant that does exist without using an ETag + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ChildTenantId' + When I get the tenant with the details called 'ChildTenantId' labelled 'Result' + Then the tenant details labelled 'Result' should match the tenant details labelled 'ChildTenantId' + +Scenario: Get a v2-style tenant that does exist without using an ETag + Given the root tenant has v2 a child tenant called 'ChildTenant1' labelled 'ChildTenantId' + When I get the tenant with the details called 'ChildTenantId' labelled 'Result' + Then the tenant details labelled 'Result' should match the tenant details labelled 'ChildTenantId' + +Scenario: Get a tenant that does exist using an ETag + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ChildTenantId' + When I try to get the tenant using the details called 'ChildTenantId' passing the ETag + Then GetTenantAsync should throw a TenantNotModifiedException + +Scenario: Get a tenant with an etag retrieved from a tenant got from the repo + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ChildTenantId' + And I get the tenant with the id from label 'ChildTenantId' labelled 'Result' + When I try to get the tenant using the details called 'Result' passing the ETag + Then GetTenantAsync should throw a TenantNotModifiedException diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/GetTenant.feature.multi.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/GetTenant.feature.multi.cs new file mode 100644 index 00000000..5c42c9fb --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/GetTenant.feature.multi.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Features +{ + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + /// + /// Adds in multi-host-mode execution. + /// + [MultiSetupTest] + public partial class GetTenantFeature : MultiSetupTestBase + { + /// + /// Creates a . + /// + /// + /// Hosting style to test for. + /// + public GetTenantFeature(SetupModes hostMode) + : base(hostMode) + { + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/ModifyTenantProperties.feature b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/ModifyTenantProperties.feature new file mode 100644 index 00000000..e47336f8 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/ModifyTenantProperties.feature @@ -0,0 +1,116 @@ +@perScenarioContainer +@withBlobStorageTenantProvider + +Feature: ModifyTenantProperties + In order to manage tenants and their configuration + As a tenant owner + I want to be able to modify the properties stored in tenants + +Scenario: Add properties to a child tenant that has no properties + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ChildTenant1' + When I update the properties of the tenant labelled 'ChildTenant1' and label the returned tenant 'Updated' + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + And I get the tenant with the id from label 'ChildTenant1' labelled 'Result' + Then the tenant labelled 'ChildTenant1' should have the same ID as the tenant labelled 'Result' + And the tenant labelled 'Result' should have the properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + +Scenario: Modify properties of a child tenant + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ChildTenant1' with these properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + When I update the properties of the tenant labelled 'ChildTenant1' and label the returned tenant 'UpdateResult' + | Key | Value | Type | + | FirstKey | 2 | integer | + | SecondKey | This is a different string | string | + And I get the tenant with the id from label 'ChildTenant1' labelled 'Result' + Then the tenant labelled 'ChildTenant1' should have the same ID as the tenant labelled 'Result' + And the tenant labelled 'UpdateResult' should have the properties + | Key | Value | Type | + | FirstKey | 2 | integer | + | SecondKey | This is a different string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + And the tenant labelled 'Result' should have the properties + | Key | Value | Type | + | FirstKey | 2 | integer | + | SecondKey | This is a different string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + +Scenario: Add properties to a child tenant that already has properties + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ChildTenant1' with these properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + When I update the properties of the tenant labelled 'ChildTenant1' and label the returned tenant 'UpdateResult' + | Key | Value | Type | + | FourthKey | 2 | integer | + | FifthKey | This is a different string | string | + And I get the tenant with the id from label 'ChildTenant1' labelled 'Result' + Then the tenant labelled 'ChildTenant1' should have the same ID as the tenant labelled 'Result' + And the tenant labelled 'UpdateResult' should have the properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + | FourthKey | 2 | integer | + | FifthKey | This is a different string | string | + And the tenant labelled 'Result' should have the properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + | FourthKey | 2 | integer | + | FifthKey | This is a different string | string | + +Scenario: Remove properties from a child tenant + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ChildTenant1' with these properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + When I remove the 'SecondKey' property of the tenant labelled 'ChildTenant1' and label the returned tenant 'UpdateResult' + And I get the tenant with the id from label 'ChildTenant1' labelled 'Result' + Then the tenant labelled 'ChildTenant1' should have the same ID as the tenant labelled 'Result' + And the tenant labelled 'Result' should have the properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | ThirdKey | 1999-01-17 | datetimeoffset | + And the tenant labelled 'UpdateResult' should have the properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | ThirdKey | 1999-01-17 | datetimeoffset | + +Scenario: Add, modify, and remove properties of a child tenant that already has properties + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ChildTenant1' with these properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a string | string | + | ThirdKey | 1999-01-17 | datetimeoffset | + When I update the properties of the tenant labelled 'ChildTenant1' and remove the 'ThirdKey' property and call the returned tenant 'UpdateResult' + | Key | Value | Type | + | SecondKey | This is a different string | string | + | FourthKey | 2 | integer | + | FifthKey | This is a new string | string | + And I get the tenant with the id from label 'ChildTenant1' labelled 'Result' + Then the tenant labelled 'ChildTenant1' should have the same ID as the tenant labelled 'Result' + And the tenant labelled 'UpdateResult' should have the properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a different string | string | + | FourthKey | 2 | integer | + | FifthKey | This is a new string | string | + And the tenant labelled 'Result' should have the properties + | Key | Value | Type | + | FirstKey | 1 | integer | + | SecondKey | This is a different string | string | + | FourthKey | 2 | integer | + | FifthKey | This is a new string | string | diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/ModifyTenantProperties.feature.multi.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/ModifyTenantProperties.feature.multi.cs new file mode 100644 index 00000000..fb9e2782 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/ModifyTenantProperties.feature.multi.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Features +{ + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + /// + /// Adds in multi-host-mode execution. + /// + [MultiSetupTest] + public partial class ModifyTenantPropertiesFeature : MultiSetupTestBase + { + /// + /// Creates a . + /// + /// + /// Hosting style to test for. + /// + public ModifyTenantPropertiesFeature(SetupModes hostMode) + : base(hostMode) + { + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature new file mode 100644 index 00000000..2a17757d --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature @@ -0,0 +1,22 @@ +@perScenarioContainer +@withBlobStorageTenantProvider + +Feature: RenameTenant + In order to manage tenants and their configuration + As a tenant owner + I want to be able to change the name of an existing tenant + +Scenario: Rename a child tenant + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ChildTenant1' + When I change the name of the tenant labelled 'ChildTenant1' to 'NewName' and label the returned tenant 'UpdateResult' + And I get the tenant with the id from label 'ChildTenant1' labelled 'GetResult' + Then the tenant labelled 'UpdateResult' should have the same ID as the tenant labelled 'ChildTenant1' + And the tenant labelled 'GetResult' should have the same ID as the tenant labelled 'ChildTenant1' + And the tenant labelled 'UpdateResult' should have the name 'NewName' + And the tenant labelled 'GetResult' should have the name 'NewName' + +# TODO: +# Try to rename a non-existent tenant +# Try to rename a child for which parent is non-existent +# Rename child of child? +# What if we try to rename the root? \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature.multi.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature.multi.cs new file mode 100644 index 00000000..73e35b6d --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature.multi.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Features +{ + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + /// + /// Adds in multi-host-mode execution. + /// + [MultiSetupTest] + public partial class RenameTenantFeature : MultiSetupTestBase + { + /// + /// Creates a . + /// + /// + /// Hosting style to test for. + /// + public RenameTenantFeature(SetupModes hostMode) + : base(hostMode) + { + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj new file mode 100644 index 00000000..6932ecfe --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj @@ -0,0 +1,72 @@ + + + + + + netcoreapp3.1 + enable + + Marain.Tenancy.Storage.Azure.BlobStorage.Specs + + + $(NoWarn);CS1591;SA1600 + + + + + true + + + true + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + Always + + + PreserveNewest + + + + \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/IMultiModeTest.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/IMultiModeTest.cs new file mode 100644 index 00000000..046faa22 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/IMultiModeTest.cs @@ -0,0 +1,18 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode +{ + /// + /// Supports executing the same test fixture multiple times in different modes. + /// + /// The type used to indicate the mode. + internal interface IMultiModeTest + { + /// + /// Gets the mode in which the test is executing. + /// + T TestType { get; } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/MultiSetupTestBase.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/MultiSetupTestBase.cs new file mode 100644 index 00000000..9d46d6cf --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/MultiSetupTestBase.cs @@ -0,0 +1,123 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode +{ + using System; + using System.Collections.Generic; + using System.Reflection; + + using NUnit.Framework.Interfaces; + using NUnit.Framework.Internal; + using NUnit.Framework.Internal.Builders; + + /// + /// Base class for tests that need to perform setup both by using the subject under test (to + /// prove that it can be done) and also by writing data directly into blob storage (to prove + /// that the code works when the data in storage was created with a previous version of the + /// library). + /// + /// + /// + /// Tests can derive from this and must set the following class-level attribute: + /// + /// + /// + /// This needs to be specified on each deriving class, because NUnit does not walk up the + /// inheritance chain when looking for test fixture sources. + /// + /// + /// Deriving classes should also define a constructor that has the same signature as this + /// class's constructor, forwarding the argument on. This, in conjunction with the test + /// fixture source attribute, will cause NUnit to run the fixture for this class multiple + /// times, once for each of the host types specified in . + /// + /// + /// When using SpecFlow, bindings can detect the mode by casting the reference in + /// TestExecutionContext.CurrentContext.TestObject to + /// and then inspecting the property. + /// + /// + public class MultiSetupTestBase : IMultiModeTest + { + private static readonly object[] FixtureArgs = + { + new object[] { SetupModes.ViaApiPropagateRootConfigAsV2 }, + new object[] { SetupModes.ViaApiPropagateRootConfigAsV3 }, + new object[] { SetupModes.DirectToStoragePropagateRootConfigAsV2 }, + new object[] { SetupModes.DirectToStoragePropagateRootConfigAsV3 }, + }; + + /// + /// Creates a . + /// + /// + /// Setup style to test with. + /// + private protected MultiSetupTestBase(SetupModes testType) + { + this.TestType = testType; + } + + /// + public SetupModes TestType { get; } + + /// + /// Attribute to be applied to tests deriving from to + /// create multiple instances of the test, one for each test mode. + /// + /// + /// Annoyingly, applying this to the base type doesn't work. NUnit appears not to support + /// inheritance of fixture-building test attributes, which is why we can't just slap this + /// on once and for all. + /// + [AttributeUsage(AttributeTargets.Class)] + public class MultiSetupTestAttribute : Attribute, IFixtureBuilder2 + { + private readonly NUnitTestFixtureBuilder builder = new NUnitTestFixtureBuilder(); + + /// + public IEnumerable BuildFrom(ITypeInfo typeInfo, IPreFilter filter) + { + // This whole method does more or less the same thing as NUnit's own + // TestFixtureSourceAttribute, but with one difference: it is hard-coded to use + // the list of test modes as its input. + var fixtureSuite = new ParameterizedFixtureSuite(typeInfo); + fixtureSuite.ApplyAttributesToTest(typeInfo.Type.GetTypeInfo()); + ICustomAttributeProvider assemblyLifeCycleAttributeProvider = typeInfo.Type.GetTypeInfo().Assembly; + ICustomAttributeProvider typeLifeCycleAttributeProvider = typeInfo.Type.GetTypeInfo(); + + foreach (object[] args in FixtureArgs) + { + var arg = (SetupModes)args[0]; + ITestFixtureData parms = new TestFixtureParameters(new object[] { arg }); + TestSuite fixture = this.builder.BuildFrom(typeInfo, filter, parms); + + fixture.ApplyAttributesToTest(assemblyLifeCycleAttributeProvider); + fixture.ApplyAttributesToTest(typeLifeCycleAttributeProvider); + fixtureSuite.Add(fixture); + } + + yield return fixtureSuite; + } + + /// + public IEnumerable BuildFrom(ITypeInfo typeInfo) + { + return this.BuildFrom(typeInfo, NullPrefilter.Instance); + } + + private class NullPrefilter : IPreFilter + { + public static readonly NullPrefilter Instance = new NullPrefilter(); + + public bool IsMatch(Type type) => true; + + public bool IsMatch(Type type, MethodInfo method) => true; + } + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/SetupModes.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/SetupModes.cs new file mode 100644 index 00000000..16b291ed --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/SetupModes.cs @@ -0,0 +1,41 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode +{ + /// + /// Determines how tests set up pre-existing tenants. + /// + /// + /// This enables us to run tests in two different ways: 1) verifying that the code works + /// against stores originally populated with an earlier version; 2) verifying that the + /// code works entirely in its own right. + /// + public enum SetupModes + { + /// + /// All setup will be done through the code under test. The store is configured to write + /// V2-style config when propagating settings from the root. + /// + ViaApiPropagateRootConfigAsV2, + + /// + /// All setup will be done through the code under test. The store is configured to write + /// V3-style config when propagating settings from the root. + /// + ViaApiPropagateRootConfigAsV3, + + /// + /// Setup will be done by writing data directly into Azure Storage. The store is configured + /// to write V3-style config when propagating settings from the root. + /// + DirectToStoragePropagateRootConfigAsV2, + + /// + /// Setup will be done by writing data directly into Azure Storage. The store is configured + /// to write V3-style config when propagating settings from the root. + /// + DirectToStoragePropagateRootConfigAsV3, + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/CreateTenantSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/CreateTenantSteps.cs new file mode 100644 index 00000000..03f95435 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/CreateTenantSteps.cs @@ -0,0 +1,130 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.StepDefinitions +{ + using System; + using System.Threading.Tasks; + + using Corvus.Storage.Azure.BlobStorage; + using Corvus.Storage.Azure.BlobStorage.Tenancy; + using Corvus.Tenancy; + + using FluentAssertions; + + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings; + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.MultiMode; + + using TechTalk.SpecFlow; + + [Binding] + public class CreateTenantSteps : TenantStepsBase + { + private Exception? createWellKnownChildTenantException; + + public CreateTenantSteps(TenantProperties tenantProperties) + : base(tenantProperties) + { + } + + [When(@"I create a child tenant of the root tenant called '([^']*)' labelled '([^']*)'")] + public async Task GivenICreateAChildOfTheRootTenantCalledWithTheDetailsAvailableAsAsync( + string tenantName, string newTenantLabel) + { + // This is called in scenarios where we want the tenant creation to go through the + // tenant store under test even when the setup mode is direct-to-store, because we're + // validating that the information returned from the store works when we use it again + // in a fetch. (E.g., one of the tests we do for ETag-based gets is to check that if + // we create via the store, and then get with the id and ETag returned by the store, + // we get a TenantNotModifiedException.) + ITenant newTenant = await this.TenantStore.CreateChildTenantAsync(RootTenant.RootTenantId, tenantName); + this.Tenants.Add(newTenantLabel, newTenant); + this.AddTenantToDelete(newTenant.Id); + } + + [When(@"I create a well known child tenant of the root tenant called '([^']*)' with a Guid of '([^']*)' labelled '([^']*)'")] + public async Task GivenICreateAWellKnownChildOfTheRootTenantCalledWithTheDetailsAvailableAsAsync( + string tenantName, Guid wellKnownGuid, string newTenantLabel) + { + // This is called in scenarios where we want the tenant creation to go through the + // tenant store under test even when the setup mode is direct-to-store, because we're + // validating that the information returned from the store works when we use it again + // in a fetch. (E.g., one of the tests we do for ETag-based gets is to check that if + // we create via the store, and then get with the id and ETag returned by the store, + // we get a TenantNotModifiedException.) + ITenant newTenant = await this.TenantStore.CreateWellKnownChildTenantAsync( + RootTenant.RootTenantId, wellKnownGuid, tenantName); + this.Tenants.Add(newTenantLabel, newTenant); + this.AddWellKnownTenantToDelete(newTenant.Id); + } + + [When(@"I create a child of the tenant labelled '([^']*)' named '([^']*)' labelled '([^']*)'")] + public async Task GivenICreateAChildOfAChildOfTheRootTenantAsync( + string parentTenantLabel, string newTenantName, string newTenantLabel) + { + ITenant parent = this.Tenants[parentTenantLabel]; + ITenant newTenant = await this.TenantStore.CreateChildTenantAsync( + parent.Id, newTenantName); + this.Tenants.Add(newTenantLabel, newTenant); + this.AddTenantToDelete(newTenant.Id); + } + + [When(@"I create a well known child of the tenant labelled '([^']*)' named '([^']*)' with a Guid of '([^']*)' labelled '([^']*)'")] + public async Task GivenICreateAWellKnownChildOfAChildOfATenantAsync( + string parentTenantLabel, string newTenantName, Guid wellKnownId, string newTenantLabel) + { + ITenant parent = this.Tenants[parentTenantLabel]; + ITenant newTenant = await this.TenantStore.CreateWellKnownChildTenantAsync( + parent.Id, wellKnownId, newTenantName); + this.Tenants.Add(newTenantLabel, newTenant); + this.AddWellKnownTenantToDelete(newTenant.Id); + } + + [When(@"I try to create a well known child of the tenant labelled '([^']*)' named '([^']*)' with a Guid of '([^']*)'")] + public async Task GivenITryToCreateAWellKnownChildOfAChildOfATenantAsync( + string parentTenantLabel, string newTenantName, Guid wellKnownId) + { + ITenant parent = this.Tenants[parentTenantLabel]; + try + { + ITenant newTenant = await this.TenantStore.CreateWellKnownChildTenantAsync( + parent.Id, wellKnownId, newTenantName); + } + catch (Exception x) + { + this.createWellKnownChildTenantException = x; + } + } + + [Then("the tenant labelled '([^']*)' should have storage configuration equivalent to the root")] + public void TenantShouldHaveStorageConfigEquivalentToRoot(string tenantLabel) + { + ITenant tenant = this.Tenants[tenantLabel]; + bool propagateRootAsV2 = this.SetupMode is + SetupModes.ViaApiPropagateRootConfigAsV2 or MultiMode.SetupModes.DirectToStoragePropagateRootConfigAsV2; + + BlobContainerConfiguration v3Config; + if (propagateRootAsV2) + { + tenant.Properties.TryGet("StorageConfiguration__corvustenancy", out LegacyV2BlobStorageConfiguration v2Config) + .Should().BeTrue("Failed to read StorageConfiguration__corvustenancy from tenant properties"); + + v3Config = LegacyConfigurationConverter.FromV2ToV3(v2Config); + } + else + { + tenant.Properties.TryGet("StorageConfigurationV3__corvustenancy", out v3Config) + .Should().BeTrue("Failed to read StorageConfiguration__corvustenancy from tenant properties"); + } + + v3Config.Should().BeEquivalentTo(this.DiContainer.RootBlobStorageConfiguration); + } + + [Then("CreateWellKnownChildTenantAsync thould throw an ArgumentException")] + public void ThenItShouldThrowAnInvalidOperationException() + { + this.createWellKnownChildTenantException.Should().BeOfType(); + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/DeleteTenantSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/DeleteTenantSteps.cs new file mode 100644 index 00000000..79b66bc4 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/DeleteTenantSteps.cs @@ -0,0 +1,31 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.StepDefinitions +{ + using System.Threading.Tasks; + + using Corvus.Tenancy; + + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings; + + using TechTalk.SpecFlow; + + [Binding] + public class DeleteTenantSteps : TenantStepsBase + { + public DeleteTenantSteps(TenantProperties tenantProperties) + : base(tenantProperties) + { + } + + [When(@"I delete the tenant with the id from label '([^']*)'")] + public async Task GivenIDeleteATenant(string tenantLabel) + { + ITenant existingTenant = this.Tenants[tenantLabel]; + await this.TenantStore.DeleteTenantAsync(existingTenant.Id); + this.TenantNoLongerRequiresDeletion(existingTenant.Id); + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/EnumerateChildTenantsSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/EnumerateChildTenantsSteps.cs new file mode 100644 index 00000000..470856e4 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/EnumerateChildTenantsSteps.cs @@ -0,0 +1,78 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.StepDefinitions +{ + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + + using Corvus.Tenancy; + + using FluentAssertions; + + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings; + + using TechTalk.SpecFlow; + using TechTalk.SpecFlow.Assist; + + [Binding] + public class EnumerateChildTenantsSteps : TenantStepsBase + { + private List getChildrenResults = new (); + + public EnumerateChildTenantsSteps(TenantProperties tenantProperties) + : base(tenantProperties) + { + } + + [When(@"I get the children of the tenant with the label '([^']*)' with maxItems (\d+)")] + public async Task GivenIGetChildTenants(string tenantLabel, int maxItems) + { + ITenant existingTenant = this.Tenants[tenantLabel]; + this.getChildrenResults.Add(await this.TenantStore.GetChildrenAsync(existingTenant.Id, maxItems)); + } + + [When(@"I continue getting the children of the tenant with the label '([^']*)' with maxItems (\d+)")] + public async Task GivenIContinueGettingChildTenants(string tenantLabel, int maxItems) + { + ITenant existingTenant = this.Tenants[tenantLabel]; + string? continuation = this.getChildrenResults.Last().ContinuationToken; + this.getChildrenResults.Add(await this.TenantStore.GetChildrenAsync(existingTenant.Id, maxItems, continuation)); + } + + [Then(@"the ids of the children for page (\d+) should match these tenant ids")] + public void IdsFromGetChildTenantsMatch(int pageIndex, Table idTable) + { + IEnumerable ids = idTable.CreateSet(row => this.Tenants[row["TenantName"]].Id); + this.getChildrenResults[pageIndex].Tenants.Should().BeEquivalentTo(ids); + } + + [Then(@"the ids of all the children across all pages should match these tenant ids")] + public void IdsFromAllGetChildTenantsMatch(Table idTable) + { + IEnumerable expectedIds = idTable.CreateSet(row => this.Tenants[row["TenantName"]].Id); + IEnumerable actualIds = this.getChildrenResults.SelectMany(page => page.Tenants); + actualIds.Should().BeEquivalentTo(expectedIds); + } + + [Then(@"the continuation token for page (\d+) should be null")] + public void ContinuationTokenForPageShouldBeNull(int pageIndex) + { + this.getChildrenResults[pageIndex].ContinuationToken.Should().BeNull(); + } + + [Then(@"page (\d+) returned by GetChildrenAsync should contain (\d+) items")] + public void ContinuationTokenForPageShouldBeNull(int pageIndex, int expectedItemCount) + { + this.getChildrenResults[pageIndex].Tenants.Should().HaveCount(expectedItemCount); + } + + [Then(@"the continuation token for page (\d+) should not be null")] + public void ContinuationTokenForPageShouldNotBeNull(int pageIndex) + { + this.getChildrenResults[pageIndex].ContinuationToken.Should().NotBeNull(); + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/GetTenantSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/GetTenantSteps.cs new file mode 100644 index 00000000..6f5e0635 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/GetTenantSteps.cs @@ -0,0 +1,151 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.StepDefinitions +{ + using System; + using System.Threading.Tasks; + + using Corvus.Tenancy; + using Corvus.Tenancy.Exceptions; + using FluentAssertions; + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings; + using TechTalk.SpecFlow; + + [Binding] + public sealed class GetTenantSteps : TenantStepsBase + { + private Exception? getTenantException; + + public GetTenantSteps(TenantProperties tenantProperties) + : base(tenantProperties) + { + } + + [Given(@"I get the tenant with the id from label '([^']*)' labelled '([^']*)'")] + [When(@"I get the tenant with the id from label '([^']*)' labelled '([^']*)'")] + public async Task GivenIGetTheTenantUsingTheDetailsCalledAndCallItAsync(string existingLabel, string fetchedLabel) + { + // This is used in tests for GetTenantAsync. But it is also used in scenarios where we + // want an initial tenant fetch to go through the tenant store so we can then pass + // information from the results of that into further calls. + ITenant existingTenant = this.Tenants[existingLabel]; + ITenant fetchedTenant = await this.TenantStore.GetTenantAsync(existingTenant.Id); + this.Tenants[fetchedLabel] = fetchedTenant; + } + + [When("I get a tenant with id '([^']*)' labelled '([^']*)'")] + public async Task WhenIGetATenantWithId(string tenantId, string label) + { + this.Tenants[label] = await this.TenantStore.GetTenantAsync(tenantId); + } + + [When("I try to get a tenant with id '([^']*)'")] + public async Task WhenITryToGetATenantWithId(string tenantId) + { + try + { + await this.WhenIGetATenantWithId(tenantId, "WontBeUsed"); + } + catch (Exception x) + { + this.getTenantException = x; + } + } + + [When("I get a tenant with the root id labelled '([^']*)'")] + public async Task WhenIGetATenantWithTheRootId(string label) + { + await this.WhenIGetATenantWithId(RootTenant.RootTenantId, label); + } + + [When(@"I get the tenant with the details called '([^']*)' labelled '([^']*)'")] + public async Task WhenIGetTheTenantWithTheDetailsCalledAsync(string existingLabel, string label) + { + ITenant tenant = this.Tenants[existingLabel]; + await this.WhenIGetATenantWithId(tenant.Id, label); + } + + [When(@"I try to get the tenant using the details called '([^']*)' passing the ETag")] + public async Task WhenITryToGetTheTenantWithTheDetailsCalledPassingTheETagAsync( + string existingLabel) + { + ITenant tenant = this.Tenants[existingLabel]; + tenant.ETag.Should().NotBeNull("This test depends on knowing the tenant's ETag"); + try + { + await this.TenantStore.GetTenantAsync(tenant.Id, tenant.ETag); + } + catch (Exception x) + { + this.getTenantException = x; + } + } + + [Then("the tenant details labelled '([^']*)' should have the root tenant id")] + public void ThenTenantShouldHaveTheRootTenantId(string detailsToInspect) + { + ITenant tenantToInspect = this.Tenants[detailsToInspect]; + tenantToInspect.Id.Should().Be(RootTenant.RootTenantId); + } + + [Then(@"the tenant details labelled '([^']*)' should have the root tenant name")] + public void ThenTenantShouldHaveTheRootTenantName(string detailsToInspect) + { + ITenant tenantToInspect = this.Tenants[detailsToInspect]; + tenantToInspect.Name.Should().Be(RootTenant.RootTenantName); + } + + [Then(@"the tenant details labelled '([^']*)' should match the tenant details labelled '([^']*)'")] + public void ThenTenantShouldMatchingTheDetails(string detailsToInspect, string detailsToCompareWith) + { + ITenant tenantToInspect = this.Tenants[detailsToInspect]; + ITenant tenantToCompareWith = this.Tenants[detailsToCompareWith]; + tenantToInspect.Should().NotBeNull(); + tenantToInspect.Id.Should().Be(tenantToCompareWith.Id); + tenantToInspect.Name.Should().Be(tenantToCompareWith.Name); + tenantToInspect.ETag.Should().Be(tenantToCompareWith.ETag); + } + + [Then(@"the tenant details labelled '([^']*)' should have tenant Id '([^']*)'")] + public void ThenGetTenantShouldHaveTheTenantId(string detailsToInspect, string expectedId) + { + ITenant tenantToInspect = this.Tenants[detailsToInspect]; + tenantToInspect.Id.Should().Be(expectedId); + } + + [Then(@"the tenant labelled '([^']*)' should have the same ID as the tenant labelled '([^']*)'")] + public void ThenGetTenantShouldHaveTheSameTenantIdAs(string detailsToInspect, string detailsToCompareWith) + { + ITenant tenantToInspect = this.Tenants[detailsToInspect]; + ITenant tenantToCompareWith = this.Tenants[detailsToCompareWith]; + tenantToInspect.Id.Should().Be(tenantToCompareWith.Id); + } + + [Then(@"the tenant labelled '([^']*)' should have the name '([^']*)'")] + public void ThenGetTenantShouldHaveTheName(string detailsToInspect, string expectedName) + { + ITenant tenantToInspect = this.Tenants[detailsToInspect]; + tenantToInspect.Name.Should().Be(expectedName); + } + + [Then("GetTenantAsync should throw an InvalidOperationException")] + public void ThenItShouldThrowAnInvalidOperationException() + { + this.getTenantException.Should().BeOfType(); + } + + [Then("GetTenantAsync should throw a TenantNotFoundException")] + public void ThenItShouldThrowATenantNotFoundException() + { + this.getTenantException.Should().BeOfType(); + } + + [Then("GetTenantAsync should throw a TenantNotModifiedException")] + public void ThenItShouldThrowATenantNotModifiedException() + { + this.getTenantException.Should().BeOfType(); + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/ModifyTenantPropertiesSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/ModifyTenantPropertiesSteps.cs new file mode 100644 index 00000000..a1bc51c8 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/ModifyTenantPropertiesSteps.cs @@ -0,0 +1,89 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.StepDefinitions +{ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + using Corvus.Tenancy; + + using FluentAssertions; + + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings; + + using TechTalk.SpecFlow; + + [Binding] + public class ModifyTenantPropertiesSteps : TenantStepsBase + { + public ModifyTenantPropertiesSteps(TenantProperties tenantProperties) + : base(tenantProperties) + { + } + + [When(@"I update the properties of the tenant labelled '([^']*)' and label the returned tenant '([^']*)'")] + public async Task GivenIUpdateTenantProperties( + string tenantLabel, string updatedTenantLabel, Table propertyTable) + { + IEnumerable> properties = ReadPropertiesTable(propertyTable); + ITenant existingTenant = this.Tenants[tenantLabel]; + ITenant updatedTenant = await this.TenantStore.UpdateTenantAsync(existingTenant.Id, propertiesToSetOrAdd: properties); + this.Tenants.Add(updatedTenantLabel, updatedTenant); + } + + [When(@"I remove the '(.*)' property of the tenant labelled '(.*)' and label the returned tenant '(.*)'")] + public async Task WhenIRemoveThePropertyOfTheTenantLabelledAndLabelTheReturnedTenantAsync( + string propertykey, string existingTenantLabel, string updatedTenantLabel) + { + ITenant existingTenant = this.Tenants[existingTenantLabel]; + ITenant updatedTenant = await this.TenantStore.UpdateTenantAsync( + existingTenant.Id, + propertiesToRemove: new[] { propertykey }); + this.Tenants.Add(updatedTenantLabel, updatedTenant); + } + + [When(@"I update the properties of the tenant labelled '(.*)' and remove the '(.*)' property and call the returned tenant '(.*)'")] + public async Task WhenIUpdateThePropertiesOfTheTenantLabelledAndRemoveThePropertyAndCallTheReturnedTenantAsync( + string existingTenantLabel, string propertykey, string updatedTenantLabel, Table propertyTable) + { + IEnumerable> properties = ReadPropertiesTable(propertyTable); + ITenant existingTenant = this.Tenants[existingTenantLabel]; + ITenant updatedTenant = await this.TenantStore.UpdateTenantAsync( + existingTenant.Id, + propertiesToSetOrAdd: properties, + propertiesToRemove: new[] { propertykey }); + this.Tenants.Add(updatedTenantLabel, updatedTenant); + } + + [Then(@"the tenant labelled '([^']*)' should have the properties")] + public void ThenTheTenantCalledShouldHaveTheProperties(string tenantLabel, Table propertyTable) + { + ITenant tenant = this.Tenants[tenantLabel]; + foreach ((string key, object expectedValue) in ReadPropertiesTable(propertyTable)) + { + // We need to get the properties from the tenant specifying the type required because + // it may need to do specific serialization work. + switch (expectedValue) + { + case string s: + tenant.Properties.TryGet(key, out string? stringValue).Should().BeTrue(); + stringValue.Should().Be(s); + break; + + case int i: + tenant.Properties.TryGet(key, out int intValue).Should().BeTrue(); + intValue.Should().Be(i); + break; + + case DateTimeOffset dto: + tenant.Properties.TryGet(key, out DateTimeOffset dateTimeOffsetValue).Should().BeTrue(); + dateTimeOffsetValue.Should().Be(dto); + break; + } + } + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/RenameTenantSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/RenameTenantSteps.cs new file mode 100644 index 00000000..110d89d4 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/RenameTenantSteps.cs @@ -0,0 +1,34 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.StepDefinitions +{ + using System.Threading.Tasks; + + using Corvus.Tenancy; + + using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings; + + using TechTalk.SpecFlow; + + [Binding] + public class RenameTenantSteps : TenantStepsBase + { + public RenameTenantSteps(TenantProperties tenantProperties) + : base(tenantProperties) + { + } + + [When(@"I change the name of the tenant labelled '([^']*)' to '([^']*)' and label the returned tenant '([^']*)'")] + public async Task GivenIChangeATenantNameAsync( + string existingTenantLabel, string tenantNewName, string returnedTenantLabel) + { + ITenant existingTenant = this.Tenants[existingTenantLabel]; + ITenant updatedTenant = await this.TenantStore.UpdateTenantAsync( + existingTenant.Id, + name: tenantNewName); + this.Tenants.Add(returnedTenantLabel, updatedTenant); + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/local.settings.template.json b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/local.settings.template.json new file mode 100644 index 00000000..08ed9c69 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/local.settings.template.json @@ -0,0 +1,16 @@ +{ + "AzureServicesAuthConnectionString": "RunAs=Developer; DeveloperTool=AzureCLI", + "AzureWebJobsStorage": "UseDevelopmentStorage=true", + "FUNCTIONS_WORKER_RUNTIME": "dotnet", + "FUNCTIONS_EXTENSION_VERSION": "~2", + "APPINSIGHTS_INSTRUMENTATIONKEY": "", + + "TenantCacheConfiguration:GetTenantResponseCacheControlHeaderValue": "max-age=300", + + // This... + //"RootBlobStorageConfiguration:ConnectionStringPlainText": "UseDevelopmentStorage=true", + // or this: + "RootBlobStorageConfiguration:AccountName": "", + "RootBlobStorageConfiguration:AccessKeyInKeyVault:VaultName": "", + "RootBlobStorageConfiguration:AccessKeyInKeyVault:SecretName": "" +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json new file mode 100644 index 00000000..96d91d63 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json @@ -0,0 +1,1776 @@ +{ + "version": 1, + "dependencies": { + ".NETCoreApp,Version=v3.1": { + "Corvus.Testing.AzureFunctions.SpecFlow.NUnit": { + "type": "Direct", + "requested": "[1.4.6, )", + "resolved": "1.4.6", + "contentHash": "/8bUlkeVbPRcdtPCdvPfa00HtJbcZtXj89dk6biXK1s2shCntbQQWW9N3t31hARMFOen6F/ViHVWW4Ok+Yh6Pw==", + "dependencies": { + "Corvus.Testing.AzureFunctions.SpecFlow": "1.4.6", + "Microsoft.NET.Test.Sdk": "[16.10.0, 17.0.0)", + "Moq": "4.16.1", + "SpecFlow.NUnit.Runners": "3.9.22", + "coverlet.msbuild": "3.1.0" + } + }, + "Endjin.RecommendedPractices": { + "type": "Direct", + "requested": "[1.2.0, )", + "resolved": "1.2.0", + "contentHash": "dHWQHXPhxbdS5hajOuHQhpv4sZgEtSncbIn4CUeCNMBKO/f89pbqyeYyQ19dSVlWVsl2Z5UqKa04MMsc9bAQmA==", + "dependencies": { + "Microsoft.SourceLink.GitHub": "1.0.0" + } + }, + "FluentAssertions": { + "type": "Direct", + "requested": "[6.1.0, )", + "resolved": "6.1.0", + "contentHash": "JbLis99YvgAuA3Khr9m5WvngBWGEmfYq3u2GxV7ksbOK9x7BCeQUCTjn5LHxrG/qu5XmlfDs4O60xTMvARiKYA==", + "dependencies": { + "System.Configuration.ConfigurationManager": "4.4.0" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Direct", + "requested": "[3.1.*, )", + "resolved": "3.1.21", + "contentHash": "iFO6wyyv/mBr6v9wBJXG+i4baN1GOUf2ClwJilWSSE8CnWgEV2T7w4sTRmE73iS3tdHBiMMnQ2Ynyw8X78ayVw==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Direct", + "requested": "[3.1.*, )", + "resolved": "3.1.21", + "contentHash": "gMI0aMhlJzOvqhREbENDufDaSwnxBs6COgEz+owrfFcb1J2yvBZqhN9YIayHn03JMvm8xtSmNzNL/ZCm7TWjsw==", + "dependencies": { + "Microsoft.Extensions.Configuration": "3.1.21" + } + }, + "Microsoft.Extensions.Configuration.EnvironmentVariables": { + "type": "Direct", + "requested": "[3.1.*, )", + "resolved": "3.1.21", + "contentHash": "4nMwSpAIANpzegZxT05jO2IM30kdRtHSfJOBXI3V8fVXlhxsXBj5EEQGSOnSzzEaeBzHkjQFF4dxDHIgMuYwmQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "3.1.21" + } + }, + "Microsoft.Extensions.Configuration.Json": { + "type": "Direct", + "requested": "[3.1.*, )", + "resolved": "3.1.21", + "contentHash": "JATr/lcsjJM8R9hyylxWzR+fxteAf0xv2SBD5tpLj1qPVauuuwcgKe3swfMK/TyfP/tVHNeuLVlfBlcl6ZIhjQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "3.1.21", + "Microsoft.Extensions.Configuration.FileExtensions": "3.1.21" + } + }, + "StyleCop.Analyzers": { + "type": "Direct", + "requested": "[1.1.118, )", + "resolved": "1.1.118", + "contentHash": "Onx6ovGSqXSK07n/0eM3ZusiNdB6cIlJdabQhWGgJp3Vooy9AaLS/tigeybOJAobqbtggTamoWndz72JscZBvw==" + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.19.0", + "contentHash": "lcDjG635DPE4fU5tqSueVMmzrx0QrIfPuY0+y6evHN5GanQ0GB+/4nuMHMmoNPwEow6OUPkJu4cZQxfHJQXPdA==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.0.0", + "System.Buffers": "4.5.1", + "System.Diagnostics.DiagnosticSource": "4.6.0", + "System.Memory": "4.5.4", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.4.1", + "contentHash": "yuxWej20CUtK2HUU4jm9Vft1wPw2NWKpwS9Zr0hJyph0dp7vgihlzlujR26UdhmvgdMdswsFRZL+k0HcaS07tw==", + "dependencies": { + "Azure.Core": "1.17.0", + "Microsoft.Identity.Client": "4.30.1", + "Microsoft.Identity.Client.Extensions.Msal": "2.18.4", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.5.0", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Security.KeyVault.Secrets": { + "type": "Transitive", + "resolved": "4.2.0", + "contentHash": "ujVMKVzEtVNQom5A0iEXSDovNGoSidV0RO5QlOBFfcIZlXwFnBmO5OhOfS4D/F1gbMNCCFS3re39qd/Bgh6+QQ==", + "dependencies": { + "Azure.Core": "1.15.0", + "System.Memory": "4.5.4", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Storage.Blobs": { + "type": "Transitive", + "resolved": "12.10.0", + "contentHash": "yaijs9DPfn34C/X4TX+0TAxANEhuKSrFE650gkF9g1pz/nQljv86zOOtDwNwD5UsAY5LyrOiCASGo2dhuIxvdg==", + "dependencies": { + "Azure.Storage.Common": "12.9.0", + "System.Text.Json": "4.6.0" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.9.0", + "contentHash": "GuoigTmzz9HrCGdcdu7LyjD4pDr2XPt72LlWWTDyno+nYrjyuNwpwRFBvK/brxJvQFRHofQcBskf8vOxVxnI8g==", + "dependencies": { + "Azure.Core": "1.19.0" + } + }, + "BoDi": { + "type": "Transitive", + "resolved": "1.5.0", + "contentHash": "CzIPzdIAFSd2zuLxI+0K9s48Qv3HQDbWiApn9h96j284rHs2bSPrn/PMca3mi4q3xLSEqOp+GUJ6+mXDD9prKg==" + }, + "Castle.Core": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "b5rRL5zeaau1y/5hIbI+6mGw3cwun16YjkHZnV9RRT5UyUIFsgLmNXJ0YnIN9p8Hw7K7AbG1q1UclQVU3DinAQ==", + "dependencies": { + "NETStandard.Library": "1.6.1", + "System.Collections.Specialized": "4.3.0", + "System.ComponentModel": "4.3.0", + "System.ComponentModel.TypeConverter": "4.3.0", + "System.Diagnostics.TraceSource": "4.3.0", + "System.Dynamic.Runtime": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Emit": "4.3.0", + "System.Reflection.TypeExtensions": "4.3.0", + "System.Xml.XmlDocument": "4.3.0" + } + }, + "Corvus.ContentHandling": { + "type": "Transitive", + "resolved": "2.0.11", + "contentHash": "W4yuYfITGgwPg8KRFlLurwUp9aAsOggedBbtbLPPSmJTJzDK3BMiJnEJh/j0Rc2P37oqv3j8jhf3aOfvn7s5XQ==", + "dependencies": { + "Microsoft.CodeAnalysis.CSharp": "3.11.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", + "System.Runtime.Loader": "4.3.0" + } + }, + "Corvus.ContentHandling.Json": { + "type": "Transitive", + "resolved": "2.0.11", + "contentHash": "aYnqiQB7nCe+Pq4szhsdBYRpaXcdZX0u77JL57YAKg/Jfty9p5xVB+9cwi+O7z6boD/xOyYjkr44qMvt06i/ng==", + "dependencies": { + "Corvus.ContentHandling": "2.0.11", + "Corvus.Extensions.Newtonsoft.Json": "2.0.5", + "Newtonsoft.Json": "11.0.2" + } + }, + "Corvus.Extensions": { + "type": "Transitive", + "resolved": "1.1.4", + "contentHash": "WGwNzQDNrlxfH82iRSSXcG92yKhE8xlBMWoSC4dycp0MnH2Mle0TF+Y4keRgDAdDwXg8VC+3paZx64jVG1Jazg==", + "dependencies": { + "System.Interactive": "3.2.0" + } + }, + "Corvus.Extensions.Newtonsoft.Json": { + "type": "Transitive", + "resolved": "2.0.5", + "contentHash": "d9g6XjfyU5z2gffGNuOD4veWzCEUibioxvYyQkiwOmt+0SL5M0j4C6TNE6015LzEVYtnjLHXM+3op3NUqLtK7g==", + "dependencies": { + "Corvus.Json.Abstractions": "2.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.18", + "Newtonsoft.Json": "11.0.2" + } + }, + "Corvus.Identity.Abstractions": { + "type": "Transitive", + "resolved": "3.0.0-identity-configuration.3", + "contentHash": "wLZih7d7jz6WoDjVHMrLzxM72GqF88g3n7JOGLpPbTbu+Q7Qekc9sSSM8PBFjVyURaQwuk/Xq/cyj3hKIFDRkQ==" + }, + "Corvus.Identity.Azure": { + "type": "Transitive", + "resolved": "3.0.0-identity-configuration.3", + "contentHash": "r3d24icyK7g07cvaiIymJxwL5S6te77sHFBFZb5XRGRqUzsLePBbccmW4G2x3zb1efvduObR0Uh32tqmiDZy8A==", + "dependencies": { + "Azure.Identity": "1.4.1", + "Azure.Security.KeyVault.Secrets": "4.2.0", + "Corvus.Identity.Abstractions": "3.0.0-identity-configuration.3", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" + } + }, + "Corvus.Json.Abstractions": { + "type": "Transitive", + "resolved": "2.0.5", + "contentHash": "fUuuUwktUoCQNwR2+bvi2AcOPzJkU51o8Js37vCTdXBg4aDLQZaFIuyO9Dg9Sm9NW1hVhK5nBFkBaqbmF5rutg==" + }, + "Corvus.Storage.Azure.BlobStorage": { + "type": "Transitive", + "resolved": "3.0.0-1-refactor-from-tenancy.10", + "contentHash": "xzy+Z5ZzpJ4GEh2MxQ4IlufXtosjwcY1Tk0Xg8SyQ2ktVHLWbly2emkEqiESFjVLUoM3sNVqd46eqflP6eXkqw==", + "dependencies": { + "Azure.Storage.Blobs": "12.10.0", + "Corvus.Storage.Common": "3.0.0-1-refactor-from-tenancy.10" + } + }, + "Corvus.Storage.Azure.BlobStorage.Tenancy": { + "type": "Transitive", + "resolved": "3.0.0-make-v2config-legacy-public.3", + "contentHash": "6m+s8Ki5m7xl0tXtjUdE/1SsFlkip5/rNh3REy3tQKg8oHUO4VHbj3CjjMFBrAtQQ/wb95aHiL1az3R8pJBceA==", + "dependencies": { + "Corvus.Storage.Azure.BlobStorage": "3.0.0-1-refactor-from-tenancy.10", + "Corvus.Tenancy.Abstractions": "3.0.0-make-v2config-legacy-public.3" + } + }, + "Corvus.Storage.Common": { + "type": "Transitive", + "resolved": "3.0.0-1-refactor-from-tenancy.10", + "contentHash": "bDirPOYtbvitnSB9efYfiwfJsc/mI9ObP6qa5zAQvwzWHxUPGqY5o82AWKRk/7ADmWw26B1kzmyZGFWF4eY8jw==", + "dependencies": { + "Azure.Security.KeyVault.Secrets": "4.2.0", + "Corvus.Identity.Azure": "3.0.0-identity-configuration.3", + "Microsoft.Extensions.Configuration.Binder": "3.1.21" + } + }, + "Corvus.Tenancy.Abstractions": { + "type": "Transitive", + "resolved": "3.0.0-make-v2config-legacy-public.3", + "contentHash": "MD+0aq9+HSjfxZ1qNc0KOBN/kZ5paT5mrc12/bPYDokuF+Cvml+BkkbQo1ydsDwxgZNrKnOGIYc5AlEf/BYANg==", + "dependencies": { + "Corvus.ContentHandling.Json": "2.0.11", + "Corvus.Extensions": "1.1.4", + "Microsoft.Extensions.Primitives": "3.1.21" + } + }, + "Corvus.Testing.AzureFunctions": { + "type": "Transitive", + "resolved": "1.4.6", + "contentHash": "dOoUYwj72I23Egq+FVd5kq+hP2zgw1VdJX1FHoz0ls5n7eBTt9YXHe4rsjNvEZzmQMN1cDv7zoBXX1jGiIB1dg==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "3.1.20", + "System.Management": "4.7.0" + } + }, + "Corvus.Testing.AzureFunctions.SpecFlow": { + "type": "Transitive", + "resolved": "1.4.6", + "contentHash": "kNwjluoe+fTid58d2YOGCgYbw3eWRqItC8HQ5N4rGsl4ZjuG1IOeFP/zjCG96NllRRVDRYoNguEQIregT04bnQ==", + "dependencies": { + "Corvus.Testing.AzureFunctions": "1.4.6", + "Corvus.Testing.SpecFlow": "1.4.6", + "Microsoft.Extensions.Logging.Console": "3.1.20", + "NUnit": "3.13.2", + "SpecFlow": "3.9.22" + } + }, + "Corvus.Testing.SpecFlow": { + "type": "Transitive", + "resolved": "1.4.6", + "contentHash": "EmakRYEWtLqOXJXV8vOq4bOikivszKcclnRClM65IULefSCY1Cm+pP5wvJusetZWRQ7xXjvI9Hzp25T1MJmVBQ==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", + "Microsoft.Extensions.DependencyInjection": "3.1.20", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", + "NUnit": "3.13.2", + "SpecFlow": "3.9.22", + "System.Management": "4.7.0" + } + }, + "coverlet.msbuild": { + "type": "Transitive", + "resolved": "3.1.0", + "contentHash": "xOv5HZagq0I6uF4vt8NVVpwcA2W/uGmNcbLStao2eMk98RQH5NFPQuouh2nWWPSZrNIhGG/iYbBn2pO4s5i+ig==" + }, + "Cucumber.Messages": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "R/2XAU6Zwdnlgga/YLYxwbKf4ai0JYyeX25l85t0nNgagR2aP8hnqrLtJjgswuXVa2WlQdjXUfJqUX8YTjzlXw==", + "dependencies": { + "Google.Protobuf": "3.7.0" + } + }, + "Gherkin": { + "type": "Transitive", + "resolved": "19.0.3", + "contentHash": "kq9feqMojMj9aABrHb/ABEPaH2Y4dSclseSahAru6qxCeqVQNLLTgw/6vZMauzI1yBUL2fz03ub5yEd5btLfvg==" + }, + "Google.Protobuf": { + "type": "Transitive", + "resolved": "3.7.0", + "contentHash": "OvssyqQTrpJgdH4fjztsCV9AhUo9jgGpDbZ5XAAqC+X6MIUsifHk8Woeom1HXlHdqo/XebiEMpYySE9AxybJ9g==", + "dependencies": { + "NETStandard.Library": "1.6.1" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "K63Y4hORbBcKLWH5wnKgzyn7TOfYzevIEwIedQHBIkmkEBA9SCqgvom+XTuE+fAFGvINGkhFItaZ2dvMGdT5iw==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "z2fpmmt+1Jfl+ZnBki9nSP08S1/tbEOxFdsK1rSR+LBehIJz1Xv9/6qOOoGNqlwnAGGVGis1Oj6S8Kt9COEYlQ==" + }, + "Microsoft.CodeAnalysis.Analyzers": { + "type": "Transitive", + "resolved": "3.3.2", + "contentHash": "7xt6zTlIEizUgEsYAIgm37EbdkiMmr6fP6J9pDoKEpiGM4pi32BCPGr/IczmSJI9Zzp0a6HOzpr9OvpMP+2veA==" + }, + "Microsoft.CodeAnalysis.Common": { + "type": "Transitive", + "resolved": "3.11.0", + "contentHash": "FDKSkRRXnaEWMa2ONkLMo0ZAt/uiV1XIXyodwKIgP1AMIKA7JJKXx/OwFVsvkkUT4BeobLwokoxFw70fICahNg==", + "dependencies": { + "Microsoft.CodeAnalysis.Analyzers": "3.3.2", + "System.Collections.Immutable": "5.0.0", + "System.Memory": "4.5.4", + "System.Reflection.Metadata": "5.0.0", + "System.Runtime.CompilerServices.Unsafe": "5.0.0", + "System.Text.Encoding.CodePages": "4.5.1", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.CodeAnalysis.CSharp": { + "type": "Transitive", + "resolved": "3.11.0", + "contentHash": "aDRRb7y/sXoJyDqFEQ3Il9jZxyUMHkShzZeCRjQf3SS84n2J0cTEi3TbwVZE9XJvAeMJhGfVVxwOdjYBg6ljmw==", + "dependencies": { + "Microsoft.CodeAnalysis.Common": "[3.11.0]" + } + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "16.10.0", + "contentHash": "7g0UjAwhEi2OBBv8SDV3wZ6J103cQyZbKVgDy59fnNdlbv0XpUCfdBZiSW5yVK/d2jp6faCdGh7VnI/F2JZO+Q==" + }, + "Microsoft.DotNet.InternalAbstractions": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "AAguUq7YyKk3yDWPoWA8DrLZvURxB/LrDdTn1h5lmPeznkFUpfC3p459w5mQYQE0qpquf/CkSQZ0etiV5vRHFA==", + "dependencies": { + "System.AppContext": "4.1.0", + "System.Collections": "4.0.11", + "System.IO": "4.1.0", + "System.IO.FileSystem": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.InteropServices": "4.1.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.0.0" + } + }, + "Microsoft.DotNet.PlatformAbstractions": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "rF92Gp5L2asYrFNf0cKNBxzzGLh1krHuj6TRDk9wdjN2qdvJLaNYOn1s9oYkMlptYX436KiEFqxhLB+I5veXvQ==", + "dependencies": { + "System.AppContext": "4.1.0", + "System.Collections": "4.0.11", + "System.IO": "4.1.0", + "System.IO.FileSystem": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.InteropServices": "4.1.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.0.0" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "3.1.21", + "contentHash": "3Ef65E9wCkGJVPQZ7S7GtDJ8JXpCQ3c2b83XLIOINoVV7GSEjKyW/vycc3jQfdc5BIf/lnjodkDiKnjdTzXAZA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "3.1.21" + } + }, + "Microsoft.Extensions.Configuration.FileExtensions": { + "type": "Transitive", + "resolved": "3.1.21", + "contentHash": "uAucC/Vq3/2duacja/sLbMKU9y2RJT9uloFT1xrl3MufDKFRAkSbIakw2Rv61XNqHCcEIHgsUiW/L7Tuz7Uomw==", + "dependencies": { + "Microsoft.Extensions.Configuration": "3.1.21", + "Microsoft.Extensions.FileProviders.Physical": "3.1.21" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "Transitive", + "resolved": "3.1.20", + "contentHash": "JAV97hx4y7qJ5mnjnUOSd+xDnMj2+51c8KVirhuU+rOW1LUnsmjhin86Tep6Q5tOHmNPOmmo6OHEFCdbZj5+zw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "3.1.21", + "contentHash": "PWfBWk54+UcMYA/DqD0l/HSOlbnclR4kp6rYgI28s5zPZ8tIMetKa9+jk+cialrSbvz/+xs/JrXqy7VDiy/0dQ==" + }, + "Microsoft.Extensions.DependencyModel": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "Z3o19EnheuegmvgpCzwoSlnCWxYA6qIUhvKJ7ifKHHvU7U+oYR/gliLiL3LVYOOeGMEEzkpJ5W67sOcXizGtlw==", + "dependencies": { + "Microsoft.DotNet.PlatformAbstractions": "1.0.3", + "Newtonsoft.Json": "9.0.1", + "System.Diagnostics.Debug": "4.0.11", + "System.Dynamic.Runtime": "4.0.11", + "System.Linq": "4.1.0" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "3.1.21", + "contentHash": "52amnz03Px8X7Pw7uI6qrQPUx++Qq7MB5rhjJh+4YRq3NgUls4KqJDvOuGnnS4pRt2T8IbIrgYxRn2wMrW8Xwg==", + "dependencies": { + "Microsoft.Extensions.Primitives": "3.1.21" + } + }, + "Microsoft.Extensions.FileProviders.Physical": { + "type": "Transitive", + "resolved": "3.1.21", + "contentHash": "w8vwWXVdFPX/hJptNybW6Nv21j3I6vOrztt3gwp0IPts+v56X9tNjR36ivx6CbEpDs2jP2kx8w8YOTYVwIuwgg==", + "dependencies": { + "Microsoft.Extensions.FileProviders.Abstractions": "3.1.21", + "Microsoft.Extensions.FileSystemGlobbing": "3.1.21" + } + }, + "Microsoft.Extensions.FileSystemGlobbing": { + "type": "Transitive", + "resolved": "3.1.21", + "contentHash": "Vao4dtipoDQf6jkfYql9MZWJm1U2gv5Ro4a0sMuE0K8Ze3+yRmSyNTtmZer8GLb99xAGyYa2JhfQlFobt269aA==" + }, + "Microsoft.Extensions.Logging": { + "type": "Transitive", + "resolved": "3.1.20", + "contentHash": "/CuUfjdPd0X6upL/783pzJTSGLm1XTHlonKcRYi5oGVHuN0ESHRjWwmBvrAPf8TXXL901K9oyxJ9mtG9pTmF8Q==", + "dependencies": { + "Microsoft.Extensions.Configuration.Binder": "3.1.20", + "Microsoft.Extensions.DependencyInjection": "3.1.20", + "Microsoft.Extensions.Logging.Abstractions": "3.1.20", + "Microsoft.Extensions.Options": "3.1.20" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "3.1.20", + "contentHash": "pejtJ+FM3tRm9Ssy9VO1PMkxlpkwbO+iQmK/Ot9DqgW3zjeLSQg3bEPI6klU70yoRSDwpiI8E71RdzU+vn/bTQ==" + }, + "Microsoft.Extensions.Logging.Configuration": { + "type": "Transitive", + "resolved": "3.1.20", + "contentHash": "+k33hBevAq2hZi4tHnsQwtZDXAkD79MTntOvX5ID6kMgU6piqthMLMoK5uMJAh7vec8ORMhwSIkhjYaQ7wx4gw==", + "dependencies": { + "Microsoft.Extensions.Logging": "3.1.20", + "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.20" + } + }, + "Microsoft.Extensions.Logging.Console": { + "type": "Transitive", + "resolved": "3.1.20", + "contentHash": "v9GpjBR3YBNSnbNj1C4hQmRofUDpya1CgQwZo3IuXbun2JbSmHs1sVxuMyEh8sdU7Bo8gGyA3zdtEwE+16oiVA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", + "Microsoft.Extensions.Logging": "3.1.20", + "Microsoft.Extensions.Logging.Configuration": "3.1.20" + } + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "3.1.20", + "contentHash": "K5h3xUrYP8mbGZeGAm/vcWjol2wBh2V1vV+Vz02DCKlZ/99Y8ecKJwdpH+elfdqcEFXy76jk+I1nBsmhPKeCgw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", + "Microsoft.Extensions.Primitives": "3.1.20" + } + }, + "Microsoft.Extensions.Options.ConfigurationExtensions": { + "type": "Transitive", + "resolved": "3.1.20", + "contentHash": "vmh27AY00NDg6+4P5NbLnhKsrNMBtfcFAoE0Pim7yNAB46ev44vu2O5a3AINUoRl9Kovik72Wgn8qA4IpQu+vg==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", + "Microsoft.Extensions.Configuration.Binder": "3.1.20", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", + "Microsoft.Extensions.Options": "3.1.20" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "3.1.21", + "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.30.1", + "contentHash": "xk8tJeGfB2yD3+d7a0DXyV7/HYyEG10IofUHYHoPYKmDbroi/j9t1BqSHgbq1nARDjg7m8Ki6e21AyNU7e/R4Q==" + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "2.18.4", + "contentHash": "HpG4oLwhQsy0ce7OWq9iDdLtJKOvKRStIKoSEOeBMKuohfuOWNDyhg8fMAJkpG/kFeoe4J329fiMHcJmmB+FPw==", + "dependencies": { + "Microsoft.Identity.Client": "4.30.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.NET.Test.Sdk": { + "type": "Transitive", + "resolved": "16.10.0", + "contentHash": "/9x6TV1SUi+rtKi8UYa7ml7SEWhb0A5FuyeF0nwwUKVjdk5WaWuLPjntHVWoDuYP25KBruoxWxs7WdhDMjWxXw==", + "dependencies": { + "Microsoft.CodeCoverage": "16.10.0", + "Microsoft.TestPlatform.TestHost": "16.10.0" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "3.1.0", + "contentHash": "z7aeg8oHln2CuNulfhiLYxCVMPEwBl3rzicjvIX+4sUuCwvXw5oXQEtbiU2c0z4qYL5L3Kmx0mMA/+t/SbY67w==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "G8DuQY8/DK5NN+3jm5wcMcd9QYD90UV7MiLmdljSJixi3U/vNaeBKmmXUqI4DJCOeWizIUEh4ALhSt58mR+5eg==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "aZyGyGg2nFSxix+xMkPmlmZSsnGQ3w+mIG23LTxJZHN+GPwTQ5FpPgDo7RMOq+Kcf5D4hFWfXkGhoGstawX13Q==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "1.0.0", + "Microsoft.SourceLink.Common": "1.0.0" + } + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "16.10.0", + "contentHash": "DYp9eKg3zffZuePhgdUrh5tHkt1YOaSraVH87r4WXDOjag1/n08aFl1vRhWP8y2RoBLTHdcZRTDOhQyYMxAYNg==", + "dependencies": { + "NuGet.Frameworks": "5.0.0", + "System.Reflection.Metadata": "1.6.0" + } + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "16.10.0", + "contentHash": "KAlB2QQRwznIH02WNl9eAuUP6/tn4IbAw4EXrvV1POTUjxuv4Dqg0u3Nn5lC9T3WIHupCHfsTcJMgsJYdi31Ig==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "16.10.0", + "Newtonsoft.Json": "9.0.1" + } + }, + "Microsoft.Win32.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "9ZQKCWxH7Ijp9BfahvL2Zyf1cJIk8XYLF6Yjzr2yi0b2cOut/HQ31qf1ThHAgCc3WiZMdnWcfJCgN82/0UunxA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "KSrRMb5vNi0CWSGG1++id2ZOs/1QhRqROt+qgbEAdQuGjGrFcl4AOl4/exGPUYz2wUnU42nvJqon1T3U0kPXLA==", + "dependencies": { + "System.Security.AccessControl": "4.7.0", + "System.Security.Principal.Windows": "4.7.0" + } + }, + "Moq": { + "type": "Transitive", + "resolved": "4.16.1", + "contentHash": "bw3R9q8cVNhWXNpnvWb0OGP4HadS4zvClq+T1zf7AF+tLY1haZ2AvbHidQekf4PDv1T40c6brZeT/V0IBq7cEQ==", + "dependencies": { + "Castle.Core": "4.4.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "NETStandard.Library": { + "type": "Transitive", + "resolved": "2.0.0", + "contentHash": "7jnbRU+L08FXKMxqUflxEXtVymWvNOrS8yHgu9s6EM8Anr6T/wIX4nZ08j/u3Asz+tCufp3YVwFSEvFTPYmBPA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "11.0.2", + "contentHash": "IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==" + }, + "NuGet.Frameworks": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "c5JVjuVAm4f7E9Vj+v09Z9s2ZsqFDjBpcsyS3M9xRo0bEdm/LVZSzLxxNvfvAwRiiE8nwe1h2G4OwiwlzFKXlA==" + }, + "NUnit": { + "type": "Transitive", + "resolved": "3.13.2", + "contentHash": "u+fz/lXyR4vlamySNAEMrXvh+GhAQiB6/aVZtU5WjivR5zF26Ui0tfteDtWqT90k9D8y6g8rFKYQC97Z7d195w==", + "dependencies": { + "NETStandard.Library": "2.0.0" + } + }, + "NUnit.Console": { + "type": "Transitive", + "resolved": "3.12.0", + "contentHash": "9KXFnViEIKQjz4vqiYFpLV9sntfHxixQomLCJzDMXC6WDo9DP2GhDQiBND6we6MRStMSNzoAWgourbLKwo7utQ==", + "dependencies": { + "NUnit.ConsoleRunner": "3.12.0", + "NUnit.Extension.NUnitProjectLoader": "3.6.0", + "NUnit.Extension.NUnitV2Driver": "3.8.0", + "NUnit.Extension.NUnitV2ResultWriter": "3.6.0", + "NUnit.Extension.TeamCityEventListener": "1.0.7", + "NUnit.Extension.VSProjectLoader": "3.8.0" + } + }, + "NUnit.ConsoleRunner": { + "type": "Transitive", + "resolved": "3.12.0", + "contentHash": "ZUtI8leU9ozCjLy4ZZ2X6ClU0hxfQtb95VOdmMA4SxIUvf62rIPxoHXS+jghvo5QxgRihGGcEp8xT3vCfgDdsA==" + }, + "NUnit.Extension.NUnitProjectLoader": { + "type": "Transitive", + "resolved": "3.6.0", + "contentHash": "ev2+dCJShMNIATkYNm/vHEuieBfbismr9DcUfBvafJZf5vNyugXPuMXO/MaOFcJaoW9j6/zjMmXKG7R5umWzXA==" + }, + "NUnit.Extension.NUnitV2Driver": { + "type": "Transitive", + "resolved": "3.8.0", + "contentHash": "l6MgFJPTnrlDaMXWfbUZ82h1uvtj0C1ExPpqm6HrYOBa5Z4MBwmFLqj85rnv9JMhu/Ju7jQB/FIaMbfoXInI2A==" + }, + "NUnit.Extension.NUnitV2ResultWriter": { + "type": "Transitive", + "resolved": "3.6.0", + "contentHash": "P/Nc+wgFRe3dT59/VjhiIT0SWfLMbb/Vc9AtBU3L71VOCs8zQnuNjCOEFLQL/Mq6XSaZeB2Sug9tUgTfCnQk9w==" + }, + "NUnit.Extension.TeamCityEventListener": { + "type": "Transitive", + "resolved": "1.0.7", + "contentHash": "bw+ZwHsUmxqb9leo91qLEF7ggtdpawY2V6wNqHI6+ATa2SHxHxoxiV5UV07ZWDRpf/qlQJELNlZu7wIB3+w2qQ==" + }, + "NUnit.Extension.VSProjectLoader": { + "type": "Transitive", + "resolved": "3.8.0", + "contentHash": "CIScV9a7+wUu6Ylb+WO0q/WGWQVoB05TUj3XZHa1CO+2BInDdfIVkqtlrSguhy6D/AGIMaLVrCZpQkQ2m0bbzQ==" + }, + "NUnit3TestAdapter": { + "type": "Transitive", + "resolved": "3.17.0", + "contentHash": "I9MNvK+GM2yXrHPitwZkAZKU9sYI2OO/8wKC+VuBD7V3z+ySQ1pSopX/urr0ooedI8/TIcajYPRO4vGRr7AM8A==", + "dependencies": { + "Microsoft.DotNet.InternalAbstractions": "1.0.0", + "System.ComponentModel.EventBasedAsync": "4.3.0", + "System.ComponentModel.TypeConverter": "4.3.0", + "System.Diagnostics.Process": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Threading.Thread": "4.3.0", + "System.Xml.XPath.XmlDocument": "4.3.0", + "System.Xml.XmlDocument": "4.3.0" + } + }, + "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "7VSGO0URRKoMEAq0Sc9cRz8mb6zbyx/BZDEWhgPdzzpmFhkam3fJ1DAGWFXBI4nGlma+uPKpfuMQP5LXRnOH5g==" + }, + "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "0oAaTAm6e2oVH+/Zttt0cuhGaePQYKII1dY8iaqP7CvOpVKgLybKRFvQjXR2LtxXOXTVPNv14j0ot8uV+HrUmw==" + }, + "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "G24ibsCNi5Kbz0oXWynBoRgtGvsw5ZSVEWjv13/KiCAM8C6wz9zzcCniMeQFIkJ2tasjo2kXlvlBZhplL51kGg==" + }, + "runtime.native.System": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "runtime.native.System.Net.Http": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "runtime.native.System.Security.Cryptography.Apple": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==", + "dependencies": { + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0" + } + }, + "runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "QR1OwtwehHxSeQvZKXe+iSd+d3XZNkEcuWMFYa2i0aG1l+lR739HPicKMlTbJst3spmeekDVBUS7SeS26s4U/g==", + "dependencies": { + "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", + "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", + "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", + "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", + "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", + "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", + "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", + "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", + "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2" + } + }, + "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "I+GNKGg2xCHueRd1m9PzeEW7WLbNNLznmTuEi8/vZX71HudUbx1UTwlGkiwMri7JLl8hGaIAWnA/GONhu+LOyQ==" + }, + "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "1Z3TAq1ytS1IBRtPXJvEUZdVsfWfeNEhBkbiOCGEl9wwAfsjP2lz3ZFDx5tq8p60/EqbS0HItG5piHuB71RjoA==" + }, + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ==" + }, + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "6mU/cVmmHtQiDXhnzUImxIcDL48GbTk+TsptXyJA+MIOG9LRjPoAQC/qBFB7X+UNyK86bmvGwC8t+M66wsYC8w==" + }, + "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "vjwG0GGcTW/PPg6KVud8F9GLWYuAV1rrw1BKAqY0oh4jcUqg15oYF1+qkGR2x2ZHM4DQnWKQ7cJgYbfncz/lYg==" + }, + "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "7KMFpTkHC/zoExs+PwP8jDCWcrK9H6L7soowT80CUx3e+nxP/AFnq0AQAW5W76z2WYbLAYCRyPfwYFG6zkvQRw==" + }, + "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "xrlmRCnKZJLHxyyLIqkZjNXqgxnKdZxfItrPkjI+6pkRo5lHX8YvSZlWrSI5AVwLMi4HbNWP7064hcAWeZKp5w==" + }, + "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.2", + "contentHash": "leXiwfiIkW7Gmn7cgnNcdtNAU70SjmKW3jxGj1iKHOvdn0zRWsgv/l2OJUO5zdGdiv2VRFnAsxxhDgMzofPdWg==" + }, + "SpecFlow": { + "type": "Transitive", + "resolved": "3.9.22", + "contentHash": "A3wZUoJaJjkll/Qvun8SJo7W869kO+1hm/FNkidNdnfbmOJA4Q8f0J80pr5wqIkKaYMQTRVvt18Y6HisgEZbUw==", + "dependencies": { + "BoDi": "1.5.0", + "Cucumber.Messages": "[6.0.1, 7.0.0)", + "Gherkin": "19.0.3", + "Microsoft.Extensions.DependencyModel": "1.0.3", + "SpecFlow.Internal.Json": "1.0.8", + "System.Configuration.ConfigurationManager": "4.5.0", + "System.Net.Http": "4.3.4", + "System.Runtime.Loader": "4.3.0" + } + }, + "SpecFlow.Internal.Json": { + "type": "Transitive", + "resolved": "1.0.8", + "contentHash": "lVCC/Rie7N5rFoc7YxPS0nneLfsWSTIMMlkndwxhaD8MxBp3Bsv1HeiVjVwXCjWaQeoqZcvIy52fF5Xit00ZLw==" + }, + "SpecFlow.NUnit": { + "type": "Transitive", + "resolved": "3.9.22", + "contentHash": "o0d1zHMf9NcXLxXhG2NllWDnJCItKtDbpKyL5Kltf9AUYam7opvm3uFYG03WePnoPU9qgD+KLOM9IjNDZ4quaw==", + "dependencies": { + "NUnit": "3.13.1", + "SpecFlow": "[3.9.22]", + "SpecFlow.Tools.MsBuild.Generation": "[3.9.22]" + } + }, + "SpecFlow.NUnit.Runners": { + "type": "Transitive", + "resolved": "3.9.22", + "contentHash": "cVQ49DWTyEqDYhiZjZSItkH0ALEVUBWvh7BOK5DCMzzsooid0EqNXWyrlzHk8OkzOmMDHs5JRmwqwe0biHZ5AA==", + "dependencies": { + "NUnit.Console": "3.12.0", + "NUnit3TestAdapter": "3.17.0", + "SpecFlow.NUnit": "[3.9.22]" + } + }, + "SpecFlow.Tools.MsBuild.Generation": { + "type": "Transitive", + "resolved": "3.9.22", + "contentHash": "JrX8QY9mN+X5RUsjS2GY6l+eOAZ6S/sWiS6yi2+RxyyrvPmskQH7TYCm69dcNDefncXg/wZk3g/SE3VtjfdcVg==", + "dependencies": { + "SpecFlow": "[3.9.22]" + } + }, + "System.AppContext": { + "type": "Transitive", + "resolved": "4.1.0", + "contentHash": "3QjO4jNV7PdKkmQAVp9atA+usVnKRwI3Kx1nMwJ93T0LcQfx7pKAYk0nKz5wn1oP5iqlhZuy6RXOFdhr7rDwow==", + "dependencies": { + "System.Runtime": "4.1.0" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.CodeDom": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "Hs9pw/kmvH3lXaZ1LFKj3pLQsiGfj2xo3sxSzwiLlRL6UcMZUTeCfoJ9Udalvn3yq5dLlPEZzYegrTQ1/LhPOQ==" + }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Collections.Concurrent": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Globalization": "4.3.0", + "System.Reflection": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==" + }, + "System.Collections.NonGeneric": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "prtjIEMhGUnQq6RnPEYLpFt8AtLbp9yq2zxOSrY7KJJZrw25Fi97IzBqY7iqssbM61Ek5b8f3MG/sG1N2sN5KA==", + "dependencies": { + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Collections.Specialized": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "Epx8PoVZR0iuOnJJDzp7pWvdfMMOAvpUo95pC4ScH2mJuXkKA2Y4aR3cG9qt2klHgSons1WFh4kcGW7cSXvrxg==", + "dependencies": { + "System.Collections.NonGeneric": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Extensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.ComponentModel": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "VyGn1jGRZVfxnh8EdvDCi71v3bMXrsu8aYJOwoV7SNDLVhiEqwP86pPMyRGsDsxhXAm2b3o9OIqeETfN5qfezw==", + "dependencies": { + "System.Runtime": "4.3.0" + } + }, + "System.ComponentModel.EventBasedAsync": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "fCFl8f0XdwA/BuoNrVBB5D0Y48/hv2J+w4xSDdXQitXZsR6UCSOrDVE7TCUraY802ENwcHUnUCv4En8CupDU1g==", + "dependencies": { + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.ComponentModel.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "j8GUkCpM8V4d4vhLIIoBLGey2Z5bCkMVNjEZseyAlm4n5arcsJOeI3zkUP+zvZgzsbLTYh4lYeP/ZD/gdIAPrw==", + "dependencies": { + "System.ComponentModel": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.ComponentModel.TypeConverter": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "16pQ6P+EdhcXzPiEK4kbA953Fu0MNG2ovxTZU81/qsCd1zPRsKc3uif5NgvllCY598k6bI0KUyKW8fanlfaDQg==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Collections.NonGeneric": "4.3.0", + "System.Collections.Specialized": "4.3.0", + "System.ComponentModel": "4.3.0", + "System.ComponentModel.Primitives": "4.3.0", + "System.Globalization": "4.3.0", + "System.Linq": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Reflection.TypeExtensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "UIFvaFfuKhLr9u5tWMxmVoDPkFeD+Qv8gUuap4aZgVGYSYMdERck4OhLN/2gulAc0nYTEigWXSJNNWshrmxnng==", + "dependencies": { + "System.Security.Cryptography.ProtectedData": "4.5.0", + "System.Security.Permissions": "4.5.0" + } + }, + "System.Diagnostics.Debug": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "4.6.0", + "contentHash": "mbBgoR0rRfl2uimsZ2avZY8g7Xnh1Mza0rJZLPcxqiMWlkGukjmRkuMJ/er+AhQuiRIh80CR/Hpeztr80seV5g==" + }, + "System.Diagnostics.Process": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "J0wOX07+QASQblsfxmIMFc9Iq7KTXYL3zs2G/Xc704Ylv3NpuVdo6gij6V3PGiptTxqsK0K7CdXenRvKUnkA2g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.Win32.Primitives": "4.3.0", + "Microsoft.Win32.Registry": "4.3.0", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encoding.Extensions": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "System.Threading.Thread": "4.3.0", + "System.Threading.ThreadPool": "4.3.0", + "runtime.native.System": "4.3.0" + } + }, + "System.Diagnostics.TraceSource": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "VnYp1NxGx8Ww731y2LJ1vpfb/DKVNKEZ8Jsh5SgQTZREL/YpWRArgh9pI8CDLmgHspZmLL697CaLvH85qQpRiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0", + "runtime.native.System": "4.3.0" + } + }, + "System.Diagnostics.Tracing": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Dynamic.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "SNVi1E/vfWUAs/WYKhE9+qlS6KqK0YVhnlT0HQtr8pMIA8YX3lwy3uPMownDwdYISBdmAF/2holEIldVp85Wag==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Linq": "4.3.0", + "System.Linq.Expressions": "4.3.0", + "System.ObjectModel": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Emit": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Reflection.TypeExtensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Globalization": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Globalization.Calendars": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Globalization": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Globalization.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Globalization": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.InteropServices": "4.3.0" + } + }, + "System.Interactive": { + "type": "Transitive", + "resolved": "3.2.0", + "contentHash": "hoXiC7r+WvT/oQ/QcsCgIJMEcXKXyM26BvIcFVRgEMzXk9URu8oR2ADqrnHwIRiJmxQC/q8b3KTQSkdoFRO4TA==" + }, + "System.IO": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.FileSystem": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.FileSystem.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==", + "dependencies": { + "System.Runtime": "4.3.0" + } + }, + "System.Linq": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0" + } + }, + "System.Linq.Expressions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "PGKkrd2khG4CnlyJwxwwaWWiSiWFNBGlgXvJpeO0xCXrZ89ODrQ6tjEWS/kOqZ8GwEOUATtKtzp1eRgmYNfclg==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Linq": "4.3.0", + "System.ObjectModel": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Emit": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Emit.Lightweight": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Reflection.TypeExtensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Management": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "IY+uuGhgzWiCg21i8IvQeY/Z7m1tX8VuPF+ludfn7iTCaccTtJo5HkjZbBEL8kbBubKhAKKtNXr7uMtmAc28Pw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "3.1.0", + "Microsoft.Win32.Registry": "4.7.0", + "System.CodeDom": "4.7.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Net.Http": { + "type": "Transitive", + "resolved": "4.3.4", + "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.DiagnosticSource": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Extensions": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.Net.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.OpenSsl": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Security.Cryptography.X509Certificates": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "runtime.native.System": "4.3.0", + "runtime.native.System.Net.Http": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2" + } + }, + "System.Net.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Runtime.Handles": "4.3.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.ObjectModel": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Reflection": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Emit": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "228FG0jLcIwTVJyz8CLFKueVqQK36ANazUManGaJHkO0icjiIypKW7YLWLIWahyIkdh5M7mV2dJepllLyA1SKg==", + "dependencies": { + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Emit.ILGeneration": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==", + "dependencies": { + "System.Reflection": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Emit.Lightweight": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==", + "dependencies": { + "System.Reflection": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==", + "dependencies": { + "System.Collections.Immutable": "5.0.0" + } + }, + "System.Reflection.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.TypeExtensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "7u6ulLcZbyxB5Gq0nMkQttcdBTx57ibzw+4IOXEfR+sXYQoHvjW5LTLyNr8O22UIMrqYbchJQJnos4eooYzYJA==", + "dependencies": { + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Resources.ResourceManager": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Globalization": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==" + }, + "System.Runtime.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime.Handles": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime.InteropServices": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Reflection": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Handles": "4.3.0" + } + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==", + "dependencies": { + "System.Reflection": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Threading": "4.3.0", + "runtime.native.System": "4.3.0" + } + }, + "System.Runtime.Loader": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "DHMaRn8D8YCK2GG2pw+UzNxn/OHVfaWx7OTLBD/hPegHZZgcZh3H6seWegrC4BYwsfuGrywIuT+MQs+rPqRLTQ==", + "dependencies": { + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime.Numerics": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==", + "dependencies": { + "System.Globalization": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0" + } + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "JECvTt5aFF3WT3gHpfofL2MNNP6v84sxtXxpqhLBCcDRzqsPBmHhQ6shv4DwwN2tRlzsUxtb3G9M3763rbXKDg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "3.1.0", + "System.Security.Principal.Windows": "4.7.0" + } + }, + "System.Security.Cryptography.Algorithms": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Collections": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "runtime.native.System.Security.Cryptography.Apple": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Cryptography.Cng": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "03idZOqFlsKRL4W+LuCpJ6dBYDUWReug6lZjBa3uJWnk5sPCUXckocevTaUA8iT/MFSrY/2HXkOt753xQ/cf8g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0" + } + }, + "System.Security.Cryptography.Csp": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Security.Cryptography.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Collections": "4.3.0", + "System.Collections.Concurrent": "4.3.0", + "System.Linq": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==", + "dependencies": { + "System.Collections": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Cryptography.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==", + "dependencies": { + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "wLBKzFnDCxP12VL9ANydSYhk59fC4cvOr9ypYQLPnAj48NQIhqnjdD2yhP8yEKyBJEjERWS9DisKL7rX5eU25Q==" + }, + "System.Security.Cryptography.X509Certificates": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Calendars": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Cng": "4.3.0", + "System.Security.Cryptography.Csp": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.OpenSsl": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "runtime.native.System": "4.3.0", + "runtime.native.System.Net.Http": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "9gdyuARhUR7H+p5CjyUB/zPk7/Xut3wUSP8NJQB6iZr8L3XUXTMdoLeVAg9N4rqF8oIpE7MpdqHdDHQ7XgJe0g==", + "dependencies": { + "System.Security.AccessControl": "4.5.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "ojD0PX0XhneCsUbAZVKdb7h/70vyYMDYs85lwEI+LngEONe/17A0cFaRFqZU+sOEidcVswYWikYOQ9PPfjlbtQ==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "4J2JQXbftjPMppIHJ7IC+VXQ9XfEagN92vZZNoG12i+zReYlim5dMoXFC1Zzg7tsnKDM7JPo5bYfFK4Jheq44w==", + "dependencies": { + "Microsoft.NETCore.Platforms": "2.1.2", + "System.Runtime.CompilerServices.Unsafe": "4.5.2" + } + }, + "System.Text.Encoding.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.6.0", + "contentHash": "4F8Xe+JIkVoDJ8hDAZ7HqLkjctN/6WItJIzQaifBwClC7wmoLSda/Sv2i6i1kycqDb3hWF4JCVbpAweyOKHEUA==" + }, + "System.Text.RegularExpressions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==", + "dependencies": { + "System.Runtime": "4.3.0" + } + }, + "System.Threading": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==", + "dependencies": { + "System.Runtime": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Threading.Tasks": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==" + }, + "System.Threading.Thread": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "OHmbT+Zz065NKII/ZHcH9XO1dEuLGI1L2k7uYss+9C1jLxTC9kTZZuzUOyXHayRk+dft9CiDf3I/QZ0t8JKyBQ==", + "dependencies": { + "System.Runtime": "4.3.0" + } + }, + "System.Threading.ThreadPool": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "k/+g4b7vjdd4aix83sTgC9VG6oXYKAktSfNIJUNGxPEj7ryEOfzHHhfnmsZvjxawwcD9HyWXKCXmPjX8U4zeSw==", + "dependencies": { + "System.Runtime": "4.3.0", + "System.Runtime.Handles": "4.3.0" + } + }, + "System.Xml.ReaderWriter": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encoding.Extensions": "4.3.0", + "System.Text.RegularExpressions": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "System.Threading.Tasks.Extensions": "4.3.0" + } + }, + "System.Xml.XmlDocument": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "lJ8AxvkX7GQxpC6GFCeBj8ThYVyQczx2+f/cWHJU8tjS7YfI6Cv6bon70jVEgs2CiFbmmM8b9j1oZVx0dSI2Ww==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "System.Xml.ReaderWriter": "4.3.0" + } + }, + "System.Xml.XPath": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "v1JQ5SETnQusqmS3RwStF7vwQ3L02imIzl++sewmt23VGygix04pEH+FCj1yWb+z4GDzKiljr1W7Wfvrx0YwgA==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0", + "System.Xml.ReaderWriter": "4.3.0" + } + }, + "System.Xml.XPath.XmlDocument": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "A/uxsWi/Ifzkmd4ArTLISMbfFs6XpRPsXZonrIqyTY70xi8t+mDtvSM5Os0RqyRDobjMBwIDHDL4NOIbkDwf7A==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0", + "System.Xml.ReaderWriter": "4.3.0", + "System.Xml.XPath": "4.3.0", + "System.Xml.XmlDocument": "4.3.0" + } + }, + "marain.tenancy.storage.azure.blobstorage": { + "type": "Project", + "dependencies": { + "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-make-v2config-legacy-public.3", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0" + } + } + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/specflow.json b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/specflow.json new file mode 100644 index 00000000..0261c528 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/specflow.json @@ -0,0 +1,5 @@ +{ + "stepAssemblies": [ + { "assembly": "Corvus.Testing.SpecFlow" } + ] +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/AssemblyAttributes.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/AssemblyAttributes.cs new file mode 100644 index 00000000..ca89eb66 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/AssemblyAttributes.cs @@ -0,0 +1,7 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Marain.Tenancy.Storage.Azure.BlobStorage.Specs")] \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj new file mode 100644 index 00000000..2596f274 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj @@ -0,0 +1,27 @@ + + + + + + netcoreapp3.1 + + enable + + + + AGPL-3.0-or-later + Azure Blob Store implementation of Corvus ITenantStore + Marain + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs new file mode 100644 index 00000000..ba0f0c91 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs @@ -0,0 +1,399 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Text; + using System.Threading; + using System.Threading.Tasks; + + using Corvus.Extensions; + using Corvus.Extensions.Json; + using Corvus.Json; + using Corvus.Storage.Azure.BlobStorage; + using Corvus.Storage.Azure.BlobStorage.Tenancy; + using Corvus.Tenancy; + using Corvus.Tenancy.Exceptions; + + using global::Azure; + using global::Azure.Storage.Blobs; + using global::Azure.Storage.Blobs.Models; + using global::Azure.Storage.Blobs.Specialized; + + using Newtonsoft.Json; + + /// + /// Tenant store implemented on Azure Blob Storage. + /// + internal class AzureBlobStorageTenantStore : ITenantStore + { + private const string TenancyContainerName = "corvustenancy"; + private const string TenancyV2ConfigKey = "StorageConfiguration__" + TenancyContainerName; + private const string TenancyV3ConfigKey = "StorageConfigurationV3__" + TenancyContainerName; + private const string LiveTenantsPrefix = "live/"; + private const string DeletedTenantsPrefix = "deleted/"; + private static readonly Encoding UTF8WithoutBom = new UTF8Encoding(false); + private readonly IBlobContainerSourceWithTenantLegacyTransition containerSource; + private readonly IPropertyBagFactory propertyBagFactory; + private readonly JsonSerializer jsonSerializer; + private readonly bool propagateRootStorageConfigAsV2; + private Task? rootContainerExistsCheck; + + /// + /// Creates a . + /// + /// Configuration settings. + /// Provides access to tenanted blob storage. + /// Settings for tenant serialization. + /// Property bag services. + public AzureBlobStorageTenantStore( + AzureBlobStorageTenantStoreConfiguration configuration, + IBlobContainerSourceWithTenantLegacyTransition containerSource, + IJsonSerializerSettingsProvider serializerSettingsProvider, + IPropertyBagFactory propertyBagFactory) + { + this.containerSource = containerSource; + this.propertyBagFactory = propertyBagFactory; + this.jsonSerializer = JsonSerializer.Create(serializerSettingsProvider.Instance); + this.propagateRootStorageConfigAsV2 = configuration.PropagateRootTenancyStorageConfigAsV2; + + // The root tenant is necessarily synthetic because we can't get access to storage + // without it. And regardless of what stage of v2 to v3 transition we're in with + // the store, we always configure the root tenant in v3 mode. + this.Root = new RootTenant(propertyBagFactory); + this.Root.UpdateProperties(values => + values.Append(new KeyValuePair( + TenancyV3ConfigKey, + configuration.RootStorageConfiguration))); + } + + /// + public RootTenant Root { get; } + + /// + public Task CreateChildTenantAsync(string parentTenantId, string name) + => this.CreateWellKnownChildTenantAsync(parentTenantId, Guid.NewGuid(), name); + + /// + public async Task CreateWellKnownChildTenantAsync( + string parentTenantId, + Guid wellKnownChildTenantGuid, + string name) + { + (ITenant parentTenant, BlobContainerClient container) = + await this.GetContainerAndTenantForChildTenantsOfAsync(parentTenantId).ConfigureAwait(false); + + // We need to copy blob storage settings for the Tenancy container definition from the parent to the new child + // to support the tenant blob store provider. We would expect this to be overridden by clients that wanted to + // establish their own settings. + bool configIsInV3 = true; + LegacyV2BlobStorageConfiguration? v2TenancyStorageConfiguration = null; + if (!parentTenant.Properties.TryGet(TenancyV3ConfigKey, out BlobContainerConfiguration tenancyStorageConfiguration)) + { + configIsInV3 = false; + if (!parentTenant.Properties.TryGet(TenancyV2ConfigKey, out v2TenancyStorageConfiguration)) + { + throw new InvalidOperationException($"No configuration found for ${TenancyV3ConfigKey} or ${TenancyV2ConfigKey}"); + } + } + + IPropertyBag childProperties; + if (parentTenantId == this.Root.Id && this.propagateRootStorageConfigAsV2) + { + configIsInV3 = false; + v2TenancyStorageConfiguration = new LegacyV2BlobStorageConfiguration + { + Container = tenancyStorageConfiguration.Container, + }; + if (tenancyStorageConfiguration.ConnectionStringPlainText != null) + { + v2TenancyStorageConfiguration.AccountName = tenancyStorageConfiguration.ConnectionStringPlainText; + } + else if (tenancyStorageConfiguration.AccountName != null) + { + v2TenancyStorageConfiguration.AccountName = tenancyStorageConfiguration.AccountName; + v2TenancyStorageConfiguration.KeyVaultName = tenancyStorageConfiguration.AccessKeyInKeyVault?.VaultName; + v2TenancyStorageConfiguration.AccountKeySecretName = tenancyStorageConfiguration.AccessKeyInKeyVault?.SecretName; + } + } + + if (configIsInV3) + { + childProperties = this.propertyBagFactory.Create(values => + values.Append(new KeyValuePair(TenancyV3ConfigKey, tenancyStorageConfiguration))); + } + else + { + childProperties = this.propertyBagFactory.Create(values => + values.Append(new KeyValuePair(TenancyV2ConfigKey, v2TenancyStorageConfiguration!))); + } + + var child = new Tenant( + parentTenantId.CreateChildId(wellKnownChildTenantGuid), + name, + childProperties); + + // TODO: this needs thinking through. + BlobContainerClient newTenantBlobContainer = await this.GetBlobContainer(child).ConfigureAwait(false); + await newTenantBlobContainer.CreateIfNotExistsAsync().ConfigureAwait(false); + + // As we create the new blob, we need to ensure there isn't already a tenant with the same Id. We do this by + // providing an If-None-Match header passing a "*", which will cause a storage exception with a 409 status + // code if a blob with the same Id already exists. + BlockBlobClient blob = GetLiveTenantBlockBlobReference(child.Id, container); + var content = new MemoryStream(); + using (var sw = new StreamWriter(content, UTF8WithoutBom, leaveOpen: true)) + using (JsonWriter writer = new JsonTextWriter(sw)) + { + this.jsonSerializer.Serialize(writer, child); + } + + content.Position = 0; + try + { + Response response = await blob.UploadAsync( + content, + new BlobUploadOptions { Conditions = new BlobRequestConditions { IfNoneMatch = ETag.All } }) + .ConfigureAwait(false); + child.ETag = response.Value.ETag.ToString("H"); + } + catch (global::Azure.RequestFailedException x) + when (x.ErrorCode == "BlobAlreadyExists") + { + // This exception is thrown because there's already a tenant with the same Id. This should never happen when + // this method has been called from CreateChildTenantAsync as the Guid will have been generated and the + // chances of it matching one previously generated are miniscule. However, it could happen when calling this + // method directly with a wellKnownChildTenantGuid that's already in use. In this case, the fault is with + // the client code - creating tenants with well known Ids is something one would expect to happen under + // controlled conditions, so it's only likely that a conflict will occur when either the client code has made + // a mistake or someone is actively trying to cause problems. + throw new ArgumentException( + $"A child tenant of '{parentTenantId}' with a well known Guid of '{wellKnownChildTenantGuid}' already exists.", + nameof(wellKnownChildTenantGuid)); + } + + return child; + } + + /// + public async Task DeleteTenantAsync(string tenantId) + { + string parentTenantId = TenantExtensions.GetRequiredParentId(tenantId); + (_, BlobContainerClient parentContainer) = + await this.GetContainerAndTenantForChildTenantsOfAsync(parentTenantId).ConfigureAwait(false); + (_, BlobContainerClient tenantContainer) = + await this.GetContainerAndTenantForChildTenantsOfAsync(tenantId).ConfigureAwait(false); + + BlockBlobClient blob = GetLiveTenantBlockBlobReference(tenantId, parentContainer); + Response response = await blob.DownloadContentAsync().ConfigureAwait(false); + using var blobContent = response.Value.Content.ToStream(); + BlockBlobClient? deletedBlob = parentContainer.GetBlockBlobClient(DeletedTenantsPrefix + tenantId); + await deletedBlob.UploadAsync(blobContent).ConfigureAwait(false); + await blob.DeleteIfExistsAsync().ConfigureAwait(false); + + await tenantContainer.DeleteAsync().ConfigureAwait(false); + } + + /// + public async Task GetChildrenAsync(string tenantId, int limit, string? continuationToken) + { + (ITenant _, BlobContainerClient container) = await this.GetContainerAndTenantForChildTenantsOfAsync(tenantId) + .ConfigureAwait(false); + + string? blobContinuationToken = DecodeUrlEncodedContinuationToken(continuationToken); + + AsyncPageable pageable = container.GetBlobsAsync(prefix: LiveTenantsPrefix); + IAsyncEnumerable> pages = pageable.AsPages(blobContinuationToken, limit); + await using IAsyncEnumerator> page = pages.GetAsyncEnumerator(); + Page? p = await page.MoveNextAsync() + ? page.Current + : null; + IEnumerable items = p?.Values ?? Enumerable.Empty(); + + return new TenantCollectionResult( + items.Select(s => s.Name.Substring(LiveTenantsPrefix.Length)).ToList(), + GenerateContinuationToken(p?.ContinuationToken)); + } + + /// + public async Task GetTenantAsync(string tenantId, string? eTag = null) + { + if (tenantId == RootTenant.RootTenantId) + { + (ITenant result, _) = await this.GetContainerAndTenantForChildTenantsOfAsync(tenantId) + .ConfigureAwait(false); + return result; + } + + string parentTenantId; + try + { + parentTenantId = TenantExtensions.GetRequiredParentId(tenantId); + } + catch (FormatException) + { + throw new TenantNotFoundException(); + } + + (ITenant _, BlobContainerClient container) = + await this.GetContainerAndTenantForChildTenantsOfAsync(parentTenantId).ConfigureAwait(false); + return await this.GetTenantFromContainerAsync(tenantId, container, eTag).ConfigureAwait(false); + } + + /// + public async Task UpdateTenantAsync( + string tenantId, + string? name = null, + IEnumerable>? propertiesToSetOrAdd = null, + IEnumerable? propertiesToRemove = null) + { + string parentTenantId = TenantExtensions.GetRequiredParentId(tenantId); + (ITenant _, BlobContainerClient parentContainer) = + await this.GetContainerAndTenantForChildTenantsOfAsync(parentTenantId).ConfigureAwait(false); + Tenant tenant = await this.GetTenantFromContainerAsync(tenantId, parentContainer, null).ConfigureAwait(false); + string currentTenantEtag = tenant.ETag ?? throw new InvalidOperationException("Existing tenant does not have ETag"); + + IPropertyBag updatedProperties = this.propertyBagFactory.CreateModified( + tenant.Properties, + propertiesToSetOrAdd, + propertiesToRemove); + + var updatedTenant = new Tenant( + tenant.Id, + name ?? tenant.Name, + updatedProperties); + + BlockBlobClient blob = GetLiveTenantBlockBlobReference(tenantId, parentContainer); + var content = new MemoryStream(); + using (var sw = new StreamWriter(content, UTF8WithoutBom, leaveOpen: true)) + using (JsonWriter writer = new JsonTextWriter(sw)) + { + this.jsonSerializer.Serialize(writer, updatedTenant); + } + + content.Position = 0; + try + { + Response response = await blob.UploadAsync( + content, + new BlobUploadOptions { Conditions = new BlobRequestConditions { IfMatch = new ETag(currentTenantEtag) } }) + .ConfigureAwait(false); + updatedTenant.ETag = response.Value.ETag.ToString("H"); + } + catch (RequestFailedException x) + when (x.Status == (int)HttpStatusCode.PreconditionFailed) + { + // This indicates that the blob changed between us reading it and applying the modification. + // TODO: perform a retry instead of bailing. + throw new InvalidOperationException($"Concurrent modifications detected."); + } + + return updatedTenant; + } + + private static BlockBlobClient GetLiveTenantBlockBlobReference(string tenantId, BlobContainerClient container) + { + return container.GetBlockBlobClient(LiveTenantsPrefix + tenantId); + } + + /// + /// Decodes a URL-friendly continuation token back to its original form. + /// + /// The continuation token. + /// A built from the continuation token. + private static string? DecodeUrlEncodedContinuationToken(string? continuationTokenInUrlForm) + => continuationTokenInUrlForm?.Base64UrlDecode(); + + /// + /// Generates a URL-friendly continuation token from a continuation token provided by blob storage. + /// + /// The continuation token in the form blob storage supplied it. + /// A URL-friendly string, or null if was null. + private static string? GenerateContinuationToken(string? continuationToken) + => string.IsNullOrWhiteSpace(continuationToken) ? null : continuationToken.Base64UrlEncode(); + + private async Task<(ITenant, BlobContainerClient)> GetContainerAndTenantForChildTenantsOfAsync(string tenantId) + { + // Get the repo for the root tenant + BlobContainerClient blobContainer = await this.GetBlobContainer(this.Root) + .ConfigureAwait(false); + + if (tenantId == RootTenant.RootTenantId) + { + await LazyInitializer.EnsureInitialized( + ref this.rootContainerExistsCheck, + async () => + { + await blobContainer.CreateIfNotExistsAsync().ConfigureAwait(false); + }); + return (this.Root, blobContainer); + } + + ITenant currentTenant = this.Root; + IEnumerable ids = tenantId.GetParentTree(); + foreach (string id in ids) + { + // Get the tenant from its parent's container + currentTenant = await this.GetTenantFromContainerAsync(id, blobContainer, null).ConfigureAwait(false); + + // Then get the container for that tenant + blobContainer = await this.GetBlobContainer(currentTenant).ConfigureAwait(false); + } + + // Finally, return the tenant repository which contains the children of the specified tenant + return (currentTenant, blobContainer); + } + + private async Task GetBlobContainer(ITenant tenant) + { + return await this.containerSource.GetBlobContainerClientFromTenantAsync( + tenant, + TenancyV2ConfigKey, + TenancyV3ConfigKey, + TenancyContainerName) + .ConfigureAwait(false); + } + + private async Task GetTenantFromContainerAsync( + string tenantId, BlobContainerClient container, string? etag) + { + BlockBlobClient blob = GetLiveTenantBlockBlobReference(tenantId, container); + Response response; + try + { + response = await blob.DownloadContentAsync( + string.IsNullOrEmpty(etag) + ? null + : new BlobRequestConditions { IfNoneMatch = new ETag(etag) }) + .ConfigureAwait(false); + } + catch (RequestFailedException x) + when (x.Status == 404) + { + throw new TenantNotFoundException(); + } + + Response httpResponse = response.GetRawResponse(); + if (httpResponse.Status == (int)HttpStatusCode.NotModified) + { + throw new TenantNotModifiedException(); + } + + Tenant tenant; + using (StreamReader sr = new (response.Value.Content.ToStream(), leaveOpen: false)) + using (JsonTextReader jr = new (sr)) + { + tenant = this.jsonSerializer.Deserialize(jr); + } + + tenant.ETag = response.Value.Details.ETag.ToString("H"); + return tenant; + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStoreConfiguration.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStoreConfiguration.cs new file mode 100644 index 00000000..2615bb1c --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStoreConfiguration.cs @@ -0,0 +1,41 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Marain.Tenancy.Storage.Azure.BlobStorage +{ + using Corvus.Storage.Azure.BlobStorage; + + /// + /// Configuration settings for . + /// + internal class AzureBlobStorageTenantStoreConfiguration + { + /// + /// Creates a . + /// + /// + /// The . + /// + /// + /// The value. + public AzureBlobStorageTenantStoreConfiguration( + BlobContainerConfiguration rootStorageConfiguration, + bool propagateRootTenancyStorageConfigAsV2) + { + this.RootStorageConfiguration = rootStorageConfiguration; + this.PropagateRootTenancyStorageConfigAsV2 = propagateRootTenancyStorageConfigAsV2; + } + + /// + /// Gets the storage configuration to use when accessing the root tenant. + /// + public BlobContainerConfiguration RootStorageConfiguration { get; } + + /// + /// Gets a value indicating whether new child tenants of the root should get the tenancy + /// storage configuration in V2 format, to support V2-V3 transition. + /// + public bool PropagateRootTenancyStorageConfigAsV2 { get; } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Microsoft/Extensions/DependencyInjection/TenancyBlobStorageServiceCollectionExtensions.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Microsoft/Extensions/DependencyInjection/TenancyBlobStorageServiceCollectionExtensions.cs new file mode 100644 index 00000000..f1bf9995 --- /dev/null +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Microsoft/Extensions/DependencyInjection/TenancyBlobStorageServiceCollectionExtensions.cs @@ -0,0 +1,89 @@ +// +// Copyright (c) Endjin Limited. All rights reserved. +// + +namespace Microsoft.Extensions.DependencyInjection +{ + using Corvus.Storage.Azure.BlobStorage; + using Corvus.Tenancy; + using Corvus.Tenancy.Internal; + + using Marain.Tenancy.Storage.Azure.BlobStorage; + + /// + /// Configuration of services for using the operations repository implemented on top of the + /// tenancy repository. + /// + public static class TenancyBlobStorageServiceCollectionExtensions + { + /// + /// Enable tenancy storage over Azure Blob Storage. + /// + /// The service collection. + /// + /// Storage configuration to use when accessing the root tenant. + /// + /// + /// If true, when a child tenant is created, the tenancy storage settings copied from the + /// parent tenant will be written in a V2 format regardless of whether the parent tenant is + /// using V2 or V3. + /// + /// The modified service collection. + /// + /// + /// The setting enables a gradual + /// transition of a system that had previously been using the Corvus.Tenancy V2 + /// over Azure Blob implementation. As the Corvus.Tenancy + /// documentation describes, the first step of a transition from V2 to V3 entails upgrading + /// all compute nodes with software that can understand V3 configuration, but which does + /// not attempt to use it. This is necessary because it can take a while for updates to be + /// rolled out across all nodes. If there is to be no downtime, there will be a time period + /// in which some of the compute nodes have been updated but some are still running code + /// that doesn't know how to use V3 configuration. + /// + /// + /// This tenant store implementation is V3-capable. It supports transition, in that it can + /// handle V2 configuration entries. However, it requires that the root configuration be + /// supplied in V3 format. This creates a potential problem if anything creates new child + /// tenants underneath the root. (Currently we don't expect this to happen often, since + /// usually, there are just two tenants here: the parent of all service tenants and the + /// parent of all client tenants. However, that's just a convention currently employed by + /// code using tenant. Also, integration tests for this code need to be able to create + /// tenants directly underneath the root.) If new children of the root just propagated + /// configuration directly, the V3 configuration supplied here would end up everywhere. + /// But we need that propagation to be able to downgrade the configuration to a V2 + /// format in cases where we're still in that initial phase. + /// + /// + /// The argument enables this + /// behaviour. It affects only the creation of children of the root. In all other cases, + /// configuration is propagated without alteration. + /// + /// + public static IServiceCollection AddTenantStoreOnAzureBlobStorage( + this IServiceCollection services, + BlobContainerConfiguration rootStorageConfiguration, + bool propagateRootTenancyStorageConfigAsV2 = false) + { + services.AddAzureBlobStorageClient(); + + // TODO: this next one is temporary. + // Corvus.Storage.Azure.BlobStorage.Tenancy should offer some successor to + // AddTenantCloudBlobContainerFactory, but since it currently only offers the + // transitional API (there is not yet an implementation of a native-v3 API) + // that hasn't been written yet, and so we need to call this bootstrapper + // in the Corvus.Tenancy.Internal namespace. + services.AddRequiredTenancyServices(); + + // TODO: This probably should also be called by Corvus.Storage.Azure.BlobStorage.Tenancy + services.AddAzureBlobStorageClient(); + + services.AddBlobContainerV2ToV3Transition(); + services.AddSingleton(new AzureBlobStorageTenantStoreConfiguration( + rootStorageConfiguration, + propagateRootTenancyStorageConfigAsV2)); + services.AddSingleton(); + return services; + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.sln b/Solutions/Marain.Tenancy.sln index 1e14a31a..f0f82dd2 100644 --- a/Solutions/Marain.Tenancy.sln +++ b/Solutions/Marain.Tenancy.sln @@ -1,10 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29102.190 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31912.275 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DevOps", "DevOps", "{D29CABE7-467E-4CF6-B44B-3C58AB76145A}" ProjectSection(SolutionItems) = preProject + ..\.gitignore = ..\.gitignore ..\azure-pipelines.release.yml = ..\azure-pipelines.release.yml ..\azure-pipelines.yml = ..\azure-pipelines.yml ..\GitVersion.yml = ..\GitVersion.yml @@ -26,6 +27,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marain.Tenancy.Cli", "Marai EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marain.Tenancy.Deployment", "Marain.Tenancy.Deployment\Marain.Tenancy.Deployment.csproj", "{0F4BEEC3-4434-4511-AB18-2C39D311F3A4}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marain.Tenancy.Storage.Azure.BlobStorage", "Marain.Tenancy.Storage.Azure.BlobStorage\Marain.Tenancy.Storage.Azure.BlobStorage.csproj", "{17F5E595-91A1-4EF4-9205-E772C4BF4ECE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marain.Tenancy.Storage.Azure.BlobStorage.Specs", "Marain.Tenancy.Storage.Azure.BlobStorage.Specs\Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj", "{B9D61A6F-9330-4590-98F2-3A033C96CD2E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -64,6 +69,14 @@ Global {0F4BEEC3-4434-4511-AB18-2C39D311F3A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {0F4BEEC3-4434-4511-AB18-2C39D311F3A4}.Release|Any CPU.ActiveCfg = Release|Any CPU {0F4BEEC3-4434-4511-AB18-2C39D311F3A4}.Release|Any CPU.Build.0 = Release|Any CPU + {17F5E595-91A1-4EF4-9205-E772C4BF4ECE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17F5E595-91A1-4EF4-9205-E772C4BF4ECE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17F5E595-91A1-4EF4-9205-E772C4BF4ECE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17F5E595-91A1-4EF4-9205-E772C4BF4ECE}.Release|Any CPU.Build.0 = Release|Any CPU + {B9D61A6F-9330-4590-98F2-3A033C96CD2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9D61A6F-9330-4590-98F2-3A033C96CD2E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9D61A6F-9330-4590-98F2-3A033C96CD2E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9D61A6F-9330-4590-98F2-3A033C96CD2E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Solutions/Marain.Tenancy.v3.ncrunchsolution b/Solutions/Marain.Tenancy.v3.ncrunchsolution new file mode 100644 index 00000000..f774ab93 --- /dev/null +++ b/Solutions/Marain.Tenancy.v3.ncrunchsolution @@ -0,0 +1,6 @@ + + + False + True + + \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 9abe9dc4..689f0328 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -23,7 +23,7 @@ jobs: solution_to_build: $(Endjin_Solution_To_Build) postCustomEnvironmentVariables: - powershell: | - Write-Host "##vso[task.setvariable variable=RootTenantBlobStorageConfigurationOptions__AccountName]$Env:ENDJIN_AZURESTORAGECONNECTIONSTRING" + Write-Host "##vso[task.setvariable variable=RootBlobStorageConfiguration__ConnectionStringPlainText]$Env:ENDJIN_AZURESTORAGECONNECTIONSTRING" Write-Host "##vso[task.setvariable variable=TenantCloudBlobContainerFactoryOptions__AzureServicesAuthConnectionString]$Env:ENDJIN_AZURESERVICESAUTHCONNECTIONSTRING" Write-Host "##vso[task.setvariable variable=TenantCacheConfiguration__GetTenantResponseCacheControlHeaderValue]$Env:TENANTCACHECONFIGURATION__GETTENANTRESPONSECACHECONTROLHEADERVALUE" displayName: 'Set Azure Connection String Environment Variable' From c760f6305174204ca6ba679dd051e4d1656e1760 Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Wed, 1 Dec 2021 20:01:20 +0000 Subject: [PATCH 04/10] Upgrade Marain.Tenancy.Client to Corvus.Identity v3 (#357) --- .../Marain/Tenancy/Cli/Program.cs | 8 +- .../Properties/launchSettings.json | 8 + .../appsettings.template.json | 2 +- .../Marain.Tenancy.Cli/packages.lock.json | 494 +++++------------- .../Marain.Tenancy.Client.csproj | 2 +- ...enancyClientServiceCollectionExtensions.cs | 18 +- .../packages.lock.json | 8 +- .../Marain.Tenancy.Specs/packages.lock.json | 258 ++++----- .../packages.lock.json | 12 +- ...n.Tenancy.Storage.Azure.BlobStorage.csproj | 2 +- 10 files changed, 279 insertions(+), 533 deletions(-) create mode 100644 Solutions/Marain.Tenancy.Cli/Properties/launchSettings.json diff --git a/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/Program.cs b/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/Program.cs index 78c4e28e..4d6d30fe 100644 --- a/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/Program.cs +++ b/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/Program.cs @@ -6,7 +6,9 @@ namespace Marain.Tenancy.Cli { using System; using System.Threading.Tasks; - using Corvus.Identity.ManagedServiceIdentity.ClientAuthentication; + + using Corvus.Identity.ClientAuthentication.Azure; + using Marain.Tenancy.Client; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -35,12 +37,12 @@ public static async Task Main(string[] args) services.AddJsonNetDateTimeOffsetToIso8601AndUnixTimeConverter(); services.AddSingleton(new StringEnumConverter(true)); - var msiTokenSourceOptions = new AzureManagedIdentityTokenSourceOptions + var msiTokenSourceOptions = new LegacyAzureServiceTokenProviderOptions { AzureServicesAuthConnectionString = ctx.Configuration["AzureServicesAuthConnectionString"], }; - services.AddAzureManagedIdentityBasedTokenSource(msiTokenSourceOptions); + services.AddServiceIdentityAzureTokenCredentialSourceFromLegacyConnectionString(msiTokenSourceOptions); var tenancyClientOptions = new TenancyClientOptions { diff --git a/Solutions/Marain.Tenancy.Cli/Properties/launchSettings.json b/Solutions/Marain.Tenancy.Cli/Properties/launchSettings.json new file mode 100644 index 00000000..faa09cd8 --- /dev/null +++ b/Solutions/Marain.Tenancy.Cli/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Cli: list": { + "commandName": "Project", + "commandLineArgs": "list" + } + } +} \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Cli/appsettings.template.json b/Solutions/Marain.Tenancy.Cli/appsettings.template.json index 191e9376..3a9d2fb4 100644 --- a/Solutions/Marain.Tenancy.Cli/appsettings.template.json +++ b/Solutions/Marain.Tenancy.Cli/appsettings.template.json @@ -2,7 +2,7 @@ // If running with a local tenancy service, point TenancyClient:TenancyServiceBaseUri at the localhost address for that // and set the ResourceIdForMsiAuthentication to an empty string. "TenancyClient:TenancyServiceBaseUri": "https://mardevtenancy.azurewebsites.net/", - "TenancyClient:ResourceIdForMsiAuthentication": "f1815180-9920-477b-95cc-7b93c2cd5de0" + "TenancyClient:ResourceIdForMsiAuthentication": "e7281b1b-6540-4c1b-ac18-eb0c2d42bfbf" // If TenancyClient:TenancyServiceBaseUri refers to an instance in Azure, or if you've configured // TenantCosmosContainerFactoryOptions, this local service will need to authenticate. diff --git a/Solutions/Marain.Tenancy.Cli/packages.lock.json b/Solutions/Marain.Tenancy.Cli/packages.lock.json index 6be21e86..8003a07a 100644 --- a/Solutions/Marain.Tenancy.Cli/packages.lock.json +++ b/Solutions/Marain.Tenancy.Cli/packages.lock.json @@ -65,6 +65,47 @@ "resolved": "1.1.118", "contentHash": "Onx6ovGSqXSK07n/0eM3ZusiNdB6cIlJdabQhWGgJp3Vooy9AaLS/tigeybOJAobqbtggTamoWndz72JscZBvw==" }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.17.0", + "contentHash": "ByJGsP7zqeMG+QFLEpd0ILzWVlRtB1ZWwgkqNWEN2KV0axRyWZDm6uPsKtsfBkNeiPtr4fUW0NSZez69TBSGrA==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.0.0", + "System.Buffers": "4.5.1", + "System.Diagnostics.DiagnosticSource": "4.6.0", + "System.Memory": "4.5.4", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.4.1", + "contentHash": "yuxWej20CUtK2HUU4jm9Vft1wPw2NWKpwS9Zr0hJyph0dp7vgihlzlujR26UdhmvgdMdswsFRZL+k0HcaS07tw==", + "dependencies": { + "Azure.Core": "1.17.0", + "Microsoft.Identity.Client": "4.30.1", + "Microsoft.Identity.Client.Extensions.Msal": "2.18.4", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.5.0", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Security.KeyVault.Secrets": { + "type": "Transitive", + "resolved": "4.2.0", + "contentHash": "ujVMKVzEtVNQom5A0iEXSDovNGoSidV0RO5QlOBFfcIZlXwFnBmO5OhOfS4D/F1gbMNCCFS3re39qd/Bgh6+QQ==", + "dependencies": { + "Azure.Core": "1.15.0", + "System.Memory": "4.5.4", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, "CacheCow.Client": { "type": "Transitive", "resolved": "2.8.3", @@ -123,13 +164,29 @@ "Newtonsoft.Json": "11.0.2" } }, - "Corvus.Identity.ManagedServiceIdentity.ClientAuthentication": { + "Corvus.Identity.Abstractions": { "type": "Transitive", - "resolved": "1.0.7", - "contentHash": "Druk5VSX3l83dyYC1GpPV3J+hG9tmLaT6LXEUoOoYdsuFj4cWcwJkhwJJSyG9ivLiGogTSeBdNqvCG60SbOvyA==", + "resolved": "3.0.0-alpha.2", + "contentHash": "q5SUNlPsyVoneFA5wHR8G6xP/RbE5i0OaA91c+WzdYCJYHSIYNXhdTQ9OAJdytw3URb4MQxSlgwsUMpZSrnnZg==" + }, + "Corvus.Identity.Azure": { + "type": "Transitive", + "resolved": "3.0.0-alpha.2", + "contentHash": "D+h1A+9TLSaCsV5hHTn8OC6+DzOto0YiTlS4EDLvpZg0TY3i+Z7FHyMa/+crtBFxCinO8T/Yl3lZcZscTQ1D8Q==", "dependencies": { - "Microsoft.Azure.Services.AppAuthentication": "1.6.1", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.16", + "Azure.Identity": "1.4.1", + "Azure.Security.KeyVault.Secrets": "4.2.0", + "Corvus.Identity.Abstractions": "3.0.0-alpha.2", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" + } + }, + "Corvus.Identity.MicrosoftRest": { + "type": "Transitive", + "resolved": "3.0.0-alpha.2", + "contentHash": "97ZgmvdWe8Dy0oAkps9qMZ7r3JHdHLHtAa53cedZam2c2SPIb9ZAttNG6wvxmP3up1lVnbEdLv3JxopgWvcb7g==", + "dependencies": { + "Corvus.Identity.Azure": "3.0.0-alpha.2", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", "Microsoft.Rest.ClientRuntime": "2.3.23" } }, @@ -166,14 +223,10 @@ "System.Text.Encodings.Web": "4.5.0" } }, - "Microsoft.Azure.Services.AppAuthentication": { + "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", - "resolved": "1.6.1", - "contentHash": "78AcjpxnhJDov7HJa4kPpZxpI0coZhS0tdA9ZLUSPExKz5KTgfozayBTLAXDuTuq0gLRzFyf85SvIkrtbB8KpA==", - "dependencies": { - "Microsoft.IdentityModel.Clients.ActiveDirectory": "5.2.0", - "System.Diagnostics.Process": "4.3.0" - } + "resolved": "1.0.0", + "contentHash": "K63Y4hORbBcKLWH5wnKgzyn7TOfYzevIEwIedQHBIkmkEBA9SCqgvom+XTuE+fAFGvINGkhFItaZ2dvMGdT5iw==" }, "Microsoft.Build.Tasks.Git": { "type": "Transitive", @@ -207,29 +260,6 @@ "Microsoft.CodeAnalysis.Common": "[3.11.0]" } }, - "Microsoft.CSharp": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "P+MBhIM0YX+JqROuf7i306ZLJEjQYA9uUyRDE+OqwUI5sh41e2ZbPQV3LfAPh+29cmceE1pUffXsGfR4eMY3KA==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Dynamic.Runtime": "4.3.0", - "System.Globalization": "4.3.0", - "System.Linq": "4.3.0", - "System.Linq.Expressions": "4.3.0", - "System.ObjectModel": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Extensions": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Runtime.InteropServices": "4.3.0", - "System.Threading": "4.3.0" - } - }, "Microsoft.Extensions.Caching.Abstractions": { "type": "Transitive", "resolved": "2.0.1", @@ -445,23 +475,18 @@ "resolved": "3.1.21", "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" }, - "Microsoft.IdentityModel.Clients.ActiveDirectory": { + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.30.1", + "contentHash": "xk8tJeGfB2yD3+d7a0DXyV7/HYyEG10IofUHYHoPYKmDbroi/j9t1BqSHgbq1nARDjg7m8Ki6e21AyNU7e/R4Q==" + }, + "Microsoft.Identity.Client.Extensions.Msal": { "type": "Transitive", - "resolved": "5.2.0", - "contentHash": "5zCom0plcWSAuPp2B/Fo7XFKdrPUOaE+1dhVW5Ui2Gny7YYv1fDJ1Z8GeZEJuCd3rKN4UBO834wPEhU5gIPQMw==", + "resolved": "2.18.4", + "contentHash": "HpG4oLwhQsy0ce7OWq9iDdLtJKOvKRStIKoSEOeBMKuohfuOWNDyhg8fMAJkpG/kFeoe4J329fiMHcJmmB+FPw==", "dependencies": { - "Microsoft.CSharp": "4.3.0", - "NETStandard.Library": "1.6.1", - "System.ComponentModel.TypeConverter": "4.3.0", - "System.Dynamic.Runtime": "4.3.0", - "System.Net.Http": "4.3.4", - "System.Runtime.Serialization.Formatters": "4.3.0", - "System.Runtime.Serialization.Json": "4.3.0", - "System.Runtime.Serialization.Primitives": "4.3.0", - "System.Security.Cryptography.X509Certificates": "4.3.0", - "System.Security.SecureString": "4.3.0", - "System.Xml.XDocument": "4.3.0", - "System.Xml.XmlDocument": "4.3.0" + "Microsoft.Identity.Client": "4.30.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" } }, "Microsoft.Net.Http.Headers": { @@ -591,18 +616,18 @@ }, "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "7VSGO0URRKoMEAq0Sc9cRz8mb6zbyx/BZDEWhgPdzzpmFhkam3fJ1DAGWFXBI4nGlma+uPKpfuMQP5LXRnOH5g==" + "resolved": "4.3.0", + "contentHash": "HdSSp5MnJSsg08KMfZThpuLPJpPwE5hBXvHwoKWosyHHfe8Mh5WKT0ylEOf6yNzX6Ngjxe4Whkafh5q7Ymac4Q==" }, "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "0oAaTAm6e2oVH+/Zttt0cuhGaePQYKII1dY8iaqP7CvOpVKgLybKRFvQjXR2LtxXOXTVPNv14j0ot8uV+HrUmw==" + "resolved": "4.3.0", + "contentHash": "+yH1a49wJMy8Zt4yx5RhJrxO/DBDByAiCzNwiETI+1S4mPdCu0OY4djdciC7Vssk0l22wQaDLrXxXkp+3+7bVA==" }, "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "G24ibsCNi5Kbz0oXWynBoRgtGvsw5ZSVEWjv13/KiCAM8C6wz9zzcCniMeQFIkJ2tasjo2kXlvlBZhplL51kGg==" + "resolved": "4.3.0", + "contentHash": "c3YNH1GQJbfIPJeCnr4avseugSqPrxwIqzthYyZDN6EuOyNOzq+y2KSUfRcXauya1sF4foESTgwM5e1A8arAKw==" }, "runtime.native.System": { "type": "Transitive", @@ -641,30 +666,30 @@ }, "runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "QR1OwtwehHxSeQvZKXe+iSd+d3XZNkEcuWMFYa2i0aG1l+lR739HPicKMlTbJst3spmeekDVBUS7SeS26s4U/g==", + "resolved": "4.3.0", + "contentHash": "NS1U+700m4KFRHR5o4vo9DSlTmlCKu/u7dtE5sUHVIPB+xpXxYQvgBgA6wEIeCz6Yfn0Z52/72WYsToCEPJnrw==", "dependencies": { - "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2", - "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2" + "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" } }, "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "I+GNKGg2xCHueRd1m9PzeEW7WLbNNLznmTuEi8/vZX71HudUbx1UTwlGkiwMri7JLl8hGaIAWnA/GONhu+LOyQ==" + "resolved": "4.3.0", + "contentHash": "b3pthNgxxFcD+Pc0WSEoC0+md3MyhRS6aCEeenvNE3Fdw1HyJ18ZhRFVJJzIeR/O/jpxPboB805Ho0T3Ul7w8A==" }, "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "1Z3TAq1ytS1IBRtPXJvEUZdVsfWfeNEhBkbiOCGEl9wwAfsjP2lz3ZFDx5tq8p60/EqbS0HItG5piHuB71RjoA==" + "resolved": "4.3.0", + "contentHash": "KeLz4HClKf+nFS7p/6Fi/CqyLXh81FpiGzcmuS8DGi9lUqSnZ6Es23/gv2O+1XVGfrbNmviF7CckBpavkBoIFQ==" }, "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": { "type": "Transitive", @@ -673,28 +698,28 @@ }, "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "6mU/cVmmHtQiDXhnzUImxIcDL48GbTk+TsptXyJA+MIOG9LRjPoAQC/qBFB7X+UNyK86bmvGwC8t+M66wsYC8w==" + "resolved": "4.3.0", + "contentHash": "X7IdhILzr4ROXd8mI1BUCQMSHSQwelUlBjF1JyTKCjXaOGn2fB4EKBxQbCK2VjO3WaWIdlXZL3W6TiIVnrhX4g==" }, "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "vjwG0GGcTW/PPg6KVud8F9GLWYuAV1rrw1BKAqY0oh4jcUqg15oYF1+qkGR2x2ZHM4DQnWKQ7cJgYbfncz/lYg==" + "resolved": "4.3.0", + "contentHash": "nyFNiCk/r+VOiIqreLix8yN+q3Wga9+SE8BCgkf+2BwEKiNx6DyvFjCgkfV743/grxv8jHJ8gUK4XEQw7yzRYg==" }, "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "7KMFpTkHC/zoExs+PwP8jDCWcrK9H6L7soowT80CUx3e+nxP/AFnq0AQAW5W76z2WYbLAYCRyPfwYFG6zkvQRw==" + "resolved": "4.3.0", + "contentHash": "ytoewC6wGorL7KoCAvRfsgoJPJbNq+64k2SqW6JcOAebWsFUvCCYgfzQMrnpvPiEl4OrblUlhF2ji+Q1+SVLrQ==" }, "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "xrlmRCnKZJLHxyyLIqkZjNXqgxnKdZxfItrPkjI+6pkRo5lHX8YvSZlWrSI5AVwLMi4HbNWP7064hcAWeZKp5w==" + "resolved": "4.3.0", + "contentHash": "I8bKw2I8k58Wx7fMKQJn2R8lamboCAiHfHeV/pS65ScKWMMI0+wJkLYlEKvgW1D/XvSl/221clBoR2q9QNNM7A==" }, "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", - "resolved": "4.3.2", - "contentHash": "leXiwfiIkW7Gmn7cgnNcdtNAU70SjmKW3jxGj1iKHOvdn0zRWsgv/l2OJUO5zdGdiv2VRFnAsxxhDgMzofPdWg==" + "resolved": "4.3.0", + "contentHash": "VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg==" }, "System.AppContext": { "type": "Transitive", @@ -706,8 +731,8 @@ }, "System.Buffers": { "type": "Transitive", - "resolved": "4.5.0", - "contentHash": "pL2ChpaRRWI/p4LXyy4RgeWlYF2sgfj/pnVMvBqwNFr5cXg7CXNnWZWxrOONLg8VGdFB8oB+EG2Qw4MLgTOe+A==" + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" }, "System.Collections": { "type": "Transitive", @@ -741,78 +766,11 @@ "resolved": "5.0.0", "contentHash": "FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==" }, - "System.Collections.NonGeneric": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "prtjIEMhGUnQq6RnPEYLpFt8AtLbp9yq2zxOSrY7KJJZrw25Fi97IzBqY7iqssbM61Ek5b8f3MG/sG1N2sN5KA==", - "dependencies": { - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Threading": "4.3.0" - } - }, - "System.Collections.Specialized": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Epx8PoVZR0iuOnJJDzp7pWvdfMMOAvpUo95pC4ScH2mJuXkKA2Y4aR3cG9qt2klHgSons1WFh4kcGW7cSXvrxg==", - "dependencies": { - "System.Collections.NonGeneric": "4.3.0", - "System.Globalization": "4.3.0", - "System.Globalization.Extensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Threading": "4.3.0" - } - }, - "System.ComponentModel": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "VyGn1jGRZVfxnh8EdvDCi71v3bMXrsu8aYJOwoV7SNDLVhiEqwP86pPMyRGsDsxhXAm2b3o9OIqeETfN5qfezw==", - "dependencies": { - "System.Runtime": "4.3.0" - } - }, "System.ComponentModel.Annotations": { "type": "Transitive", "resolved": "5.0.0", "contentHash": "dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==" }, - "System.ComponentModel.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "j8GUkCpM8V4d4vhLIIoBLGey2Z5bCkMVNjEZseyAlm4n5arcsJOeI3zkUP+zvZgzsbLTYh4lYeP/ZD/gdIAPrw==", - "dependencies": { - "System.ComponentModel": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0" - } - }, - "System.ComponentModel.TypeConverter": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "16pQ6P+EdhcXzPiEK4kbA953Fu0MNG2ovxTZU81/qsCd1zPRsKc3uif5NgvllCY598k6bI0KUyKW8fanlfaDQg==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Collections.NonGeneric": "4.3.0", - "System.Collections.Specialized": "4.3.0", - "System.ComponentModel": "4.3.0", - "System.ComponentModel.Primitives": "4.3.0", - "System.Globalization": "4.3.0", - "System.Linq": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Extensions": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Threading": "4.3.0" - } - }, "System.Console": { "type": "Transitive", "resolved": "4.3.0", @@ -837,15 +795,8 @@ }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "tD6kosZnTAGdrEa0tZSuFyunMbt/5KYDnHdndJYGqZoNy00XVXyACd5d6KnE1YgYv3ne2CjtAfNXo/fwEhnKUA==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Diagnostics.Tracing": "4.3.0", - "System.Reflection": "4.3.0", - "System.Runtime": "4.3.0", - "System.Threading": "4.3.0" - } + "resolved": "4.6.0", + "contentHash": "mbBgoR0rRfl2uimsZ2avZY8g7Xnh1Mza0rJZLPcxqiMWlkGukjmRkuMJ/er+AhQuiRIh80CR/Hpeztr80seV5g==" }, "System.Diagnostics.EventLog": { "type": "Transitive", @@ -857,34 +808,6 @@ "System.Security.Principal.Windows": "4.7.0" } }, - "System.Diagnostics.Process": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "J0wOX07+QASQblsfxmIMFc9Iq7KTXYL3zs2G/Xc704Ylv3NpuVdo6gij6V3PGiptTxqsK0K7CdXenRvKUnkA2g==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.Win32.Primitives": "4.3.0", - "Microsoft.Win32.Registry": "4.3.0", - "System.Collections": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.IO.FileSystem": "4.3.0", - "System.IO.FileSystem.Primitives": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Runtime.Handles": "4.3.0", - "System.Runtime.InteropServices": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Text.Encoding.Extensions": "4.3.0", - "System.Threading": "4.3.0", - "System.Threading.Tasks": "4.3.0", - "System.Threading.Thread": "4.3.0", - "System.Threading.ThreadPool": "4.3.0", - "runtime.native.System": "4.3.0" - } - }, "System.Diagnostics.Tools": { "type": "Transitive", "resolved": "4.3.0", @@ -905,27 +828,6 @@ "System.Runtime": "4.3.0" } }, - "System.Dynamic.Runtime": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "SNVi1E/vfWUAs/WYKhE9+qlS6KqK0YVhnlT0HQtr8pMIA8YX3lwy3uPMownDwdYISBdmAF/2holEIldVp85Wag==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Linq": "4.3.0", - "System.Linq.Expressions": "4.3.0", - "System.ObjectModel": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Emit": "4.3.0", - "System.Reflection.Emit.ILGeneration": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Threading": "4.3.0" - } - }, "System.Globalization": { "type": "Transitive", "resolved": "4.3.0", @@ -1079,12 +981,21 @@ "resolved": "4.5.4", "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, "System.Net.Http": { "type": "Transitive", - "resolved": "4.3.4", - "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", + "resolved": "4.3.0", + "contentHash": "sYg+FtILtRQuYWSIAuNOELwVuVsxVyJGWQyOnlAzhV4xvhyFnON1bAzYYC+jjRW8JREM45R0R5Dgi8MTC5sEwA==", "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Platforms": "1.1.0", "System.Collections": "4.3.0", "System.Diagnostics.Debug": "4.3.0", "System.Diagnostics.DiagnosticSource": "4.3.0", @@ -1109,7 +1020,7 @@ "System.Threading.Tasks": "4.3.0", "runtime.native.System": "4.3.0", "runtime.native.System.Net.Http": "4.3.0", - "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2" + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" } }, "System.Net.Primitives": { @@ -1136,6 +1047,11 @@ "System.Threading.Tasks": "4.3.0" } }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, "System.ObjectModel": { "type": "Transitive", "resolved": "4.3.0", @@ -1148,38 +1064,6 @@ "System.Threading": "4.3.0" } }, - "System.Private.DataContractSerialization": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "yDaJ2x3mMmjdZEDB4IbezSnCsnjQ4BxinKhRAaP6kEgL6Bb6jANWphs5SzyD8imqeC/3FxgsuXT6ykkiH1uUmA==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Collections.Concurrent": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Linq": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Emit.ILGeneration": "4.3.0", - "System.Reflection.Emit.Lightweight": "4.3.0", - "System.Reflection.Extensions": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Runtime.Serialization.Primitives": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Text.Encoding.Extensions": "4.3.0", - "System.Text.RegularExpressions": "4.3.0", - "System.Threading": "4.3.0", - "System.Threading.Tasks": "4.3.0", - "System.Xml.ReaderWriter": "4.3.0", - "System.Xml.XDocument": "4.3.0", - "System.Xml.XmlDocument": "4.3.0", - "System.Xml.XmlSerializer": "4.3.0" - } - }, "System.Reflection": { "type": "Transitive", "resolved": "4.3.0", @@ -1357,37 +1241,6 @@ "System.Runtime.Extensions": "4.3.0" } }, - "System.Runtime.Serialization.Formatters": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "KT591AkTNFOTbhZlaeMVvfax3RqhH1EJlcwF50Wm7sfnBLuHiOeZRRKrr1ns3NESkM20KPZ5Ol/ueMq5vg4QoQ==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Reflection": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Serialization.Primitives": "4.3.0" - } - }, - "System.Runtime.Serialization.Json": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "CpVfOH0M/uZ5PH+M9+Gu56K0j9lJw3M+PKRegTkcrY/stOIvRUeonggxNrfBYLA5WOHL2j15KNJuTuld3x4o9w==", - "dependencies": { - "System.IO": "4.3.0", - "System.Private.DataContractSerialization": "4.3.0", - "System.Runtime": "4.3.0" - } - }, - "System.Runtime.Serialization.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==", - "dependencies": { - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0" - } - }, "System.Security.AccessControl": { "type": "Transitive", "resolved": "4.7.0", @@ -1509,6 +1362,11 @@ "System.Threading.Tasks": "4.3.0" } }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "wLBKzFnDCxP12VL9ANydSYhk59fC4cvOr9ypYQLPnAj48NQIhqnjdD2yhP8yEKyBJEjERWS9DisKL7rX5eU25Q==" + }, "System.Security.Cryptography.X509Certificates": { "type": "Transitive", "resolved": "4.3.0", @@ -1546,21 +1404,6 @@ "resolved": "4.7.0", "contentHash": "ojD0PX0XhneCsUbAZVKdb7h/70vyYMDYs85lwEI+LngEONe/17A0cFaRFqZU+sOEidcVswYWikYOQ9PPfjlbtQ==" }, - "System.Security.SecureString": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "PnXp38O9q/2Oe4iZHMH60kinScv6QiiL2XH54Pj2t0Y6c2zKPEiAZsM/M3wBOHLNTBDFP0zfy13WN2M0qFz5jg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Handles": "4.3.0", - "System.Runtime.InteropServices": "4.3.0", - "System.Security.Cryptography.Primitives": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Threading": "4.3.0" - } - }, "System.Text.Encoding": { "type": "Transitive", "resolved": "4.3.0", @@ -1593,8 +1436,13 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "4.5.0", - "contentHash": "Xg4G4Indi4dqP1iuAiMSwpiWS54ZghzR644OtsRCm/m/lBMG8dUBhLVN7hLm8NNrNTR+iGbshCPTwrvxZPlm4g==" + "resolved": "4.7.2", + "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.6.0", + "contentHash": "4F8Xe+JIkVoDJ8hDAZ7HqLkjctN/6WItJIzQaifBwClC7wmoLSda/Sv2i6i1kycqDb3hWF4JCVbpAweyOKHEUA==" }, "System.Text.RegularExpressions": { "type": "Transitive", @@ -1628,23 +1476,6 @@ "resolved": "4.5.4", "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==" }, - "System.Threading.Thread": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "OHmbT+Zz065NKII/ZHcH9XO1dEuLGI1L2k7uYss+9C1jLxTC9kTZZuzUOyXHayRk+dft9CiDf3I/QZ0t8JKyBQ==", - "dependencies": { - "System.Runtime": "4.3.0" - } - }, - "System.Threading.ThreadPool": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "k/+g4b7vjdd4aix83sTgC9VG6oXYKAktSfNIJUNGxPEj7ryEOfzHHhfnmsZvjxawwcD9HyWXKCXmPjX8U4zeSw==", - "dependencies": { - "System.Runtime": "4.3.0", - "System.Runtime.Handles": "4.3.0" - } - }, "System.Threading.Timer": { "type": "Transitive", "resolved": "4.3.0", @@ -1696,54 +1527,13 @@ "System.Xml.ReaderWriter": "4.3.0" } }, - "System.Xml.XmlDocument": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "lJ8AxvkX7GQxpC6GFCeBj8ThYVyQczx2+f/cWHJU8tjS7YfI6Cv6bon70jVEgs2CiFbmmM8b9j1oZVx0dSI2Ww==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Threading": "4.3.0", - "System.Xml.ReaderWriter": "4.3.0" - } - }, - "System.Xml.XmlSerializer": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "MYoTCP7EZ98RrANESW05J5ZwskKDoN0AuZ06ZflnowE50LTpbR5yRg3tHckTVm5j/m47stuGgCrCHWePyHS70Q==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Linq": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Emit": "4.3.0", - "System.Reflection.Emit.ILGeneration": "4.3.0", - "System.Reflection.Extensions": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Text.RegularExpressions": "4.3.0", - "System.Threading": "4.3.0", - "System.Xml.ReaderWriter": "4.3.0", - "System.Xml.XmlDocument": "4.3.0" - } - }, "marain.tenancy.client": { "type": "Project", "dependencies": { "CacheCow.Client": "2.8.3", "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Corvus.Identity.ManagedServiceIdentity.ClientAuthentication": "1.0.7", + "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.2", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } diff --git a/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj b/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj index 61a1476c..2157953b 100644 --- a/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj +++ b/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj @@ -27,7 +27,7 @@ - + diff --git a/Solutions/Marain.Tenancy.Client/Marain/Tenancy/Client/TenancyClientServiceCollectionExtensions.cs b/Solutions/Marain.Tenancy.Client/Marain/Tenancy/Client/TenancyClientServiceCollectionExtensions.cs index 5e282361..65d91eb0 100644 --- a/Solutions/Marain.Tenancy.Client/Marain/Tenancy/Client/TenancyClientServiceCollectionExtensions.cs +++ b/Solutions/Marain.Tenancy.Client/Marain/Tenancy/Client/TenancyClientServiceCollectionExtensions.cs @@ -9,7 +9,8 @@ namespace Marain.Tenancy.Client using System.Net.Http; using CacheCow.Client; using Corvus.Extensions.Json; - using Corvus.Identity.ManagedServiceIdentity.ClientAuthentication; + using Corvus.Identity.ClientAuthentication; + using Corvus.Identity.ClientAuthentication.MicrosoftRest; using Microsoft.Extensions.DependencyInjection; using Microsoft.Rest; using Newtonsoft.Json; @@ -44,10 +45,19 @@ public static IServiceCollection AddTenancyClient( /// Flag indicating whether or not response caching should be enabled for GET operations. /// The modified service collection. /// + /// /// This requires the to be available from DI in order /// to discover the base URI of the Operations control service, and, if required, to /// specify the resource id to use when obtaining an authentication token representing the /// hosting service's identity. + /// + /// + /// This also requires an implementation of + /// to be available via DI. This is normally achieved through one of the various + /// AddServiceIdentityAzureTokenCredentialSource... extension methods available when + /// you install the Corvus.Identity.Azure NuGet package, but applications are free + /// to supply alternate implementations. + /// /// public static IServiceCollection AddTenancyClient( this IServiceCollection services, @@ -75,9 +85,9 @@ public static IServiceCollection AddTenancyClient( else { var tokenCredentials = new TokenCredentials( - new ServiceIdentityTokenProvider( - sp.GetRequiredService(), - options.ResourceIdForMsiAuthentication)); + new MicrosoftRestTokenProvider( + sp.GetRequiredService(), + $"{options.ResourceIdForMsiAuthentication}/.default")); service = new TenancyService(options.TenancyServiceBaseUri, tokenCredentials, handlers); } diff --git a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json index 9737083f..3259d761 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json +++ b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json @@ -209,11 +209,11 @@ }, "Corvus.Storage.Azure.BlobStorage.Tenancy": { "type": "Transitive", - "resolved": "3.0.0-make-v2config-legacy-public.3", - "contentHash": "6m+s8Ki5m7xl0tXtjUdE/1SsFlkip5/rNh3REy3tQKg8oHUO4VHbj3CjjMFBrAtQQ/wb95aHiL1az3R8pJBceA==", + "resolved": "3.0.0-alpha.3", + "contentHash": "aQ/WtonoXdEtJbnx5H9++LyOQscxdsOLR7B6u4SIWYsNqq3Lsxb9GNmVN2OVh3TaaMPoLCKVUEUUKd2Sp/t/Rg==", "dependencies": { "Corvus.Storage.Azure.BlobStorage": "3.0.0-1-refactor-from-tenancy.10", - "Corvus.Tenancy.Abstractions": "3.0.0-make-v2config-legacy-public.3" + "Corvus.Tenancy.Abstractions": "3.0.0-alpha.3" } }, "Corvus.Storage.Common": { @@ -1903,7 +1903,7 @@ "marain.tenancy.storage.azure.blobstorage": { "type": "Project", "dependencies": { - "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-make-v2config-legacy-public.3", + "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-alpha.3", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0" } } diff --git a/Solutions/Marain.Tenancy.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Specs/packages.lock.json index aa8a57b4..e3010b5b 100644 --- a/Solutions/Marain.Tenancy.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Specs/packages.lock.json @@ -43,6 +43,47 @@ "Microsoft.Extensions.Configuration.FileExtensions": "3.1.21" } }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.17.0", + "contentHash": "ByJGsP7zqeMG+QFLEpd0ILzWVlRtB1ZWwgkqNWEN2KV0axRyWZDm6uPsKtsfBkNeiPtr4fUW0NSZez69TBSGrA==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.0.0", + "System.Buffers": "4.5.1", + "System.Diagnostics.DiagnosticSource": "4.6.0", + "System.Memory": "4.5.4", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.4.1", + "contentHash": "yuxWej20CUtK2HUU4jm9Vft1wPw2NWKpwS9Zr0hJyph0dp7vgihlzlujR26UdhmvgdMdswsFRZL+k0HcaS07tw==", + "dependencies": { + "Azure.Core": "1.17.0", + "Microsoft.Identity.Client": "4.30.1", + "Microsoft.Identity.Client.Extensions.Msal": "2.18.4", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.5.0", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "Azure.Security.KeyVault.Secrets": { + "type": "Transitive", + "resolved": "4.2.0", + "contentHash": "ujVMKVzEtVNQom5A0iEXSDovNGoSidV0RO5QlOBFfcIZlXwFnBmO5OhOfS4D/F1gbMNCCFS3re39qd/Bgh6+QQ==", + "dependencies": { + "Azure.Core": "1.15.0", + "System.Memory": "4.5.4", + "System.Text.Json": "4.6.0", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, "BoDi": { "type": "Transitive", "resolved": "1.5.0", @@ -123,13 +164,29 @@ "Newtonsoft.Json": "11.0.2" } }, - "Corvus.Identity.ManagedServiceIdentity.ClientAuthentication": { + "Corvus.Identity.Abstractions": { "type": "Transitive", - "resolved": "1.0.7", - "contentHash": "Druk5VSX3l83dyYC1GpPV3J+hG9tmLaT6LXEUoOoYdsuFj4cWcwJkhwJJSyG9ivLiGogTSeBdNqvCG60SbOvyA==", + "resolved": "3.0.0-alpha.2", + "contentHash": "q5SUNlPsyVoneFA5wHR8G6xP/RbE5i0OaA91c+WzdYCJYHSIYNXhdTQ9OAJdytw3URb4MQxSlgwsUMpZSrnnZg==" + }, + "Corvus.Identity.Azure": { + "type": "Transitive", + "resolved": "3.0.0-alpha.2", + "contentHash": "D+h1A+9TLSaCsV5hHTn8OC6+DzOto0YiTlS4EDLvpZg0TY3i+Z7FHyMa/+crtBFxCinO8T/Yl3lZcZscTQ1D8Q==", "dependencies": { - "Microsoft.Azure.Services.AppAuthentication": "1.6.1", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.16", + "Azure.Identity": "1.4.1", + "Azure.Security.KeyVault.Secrets": "4.2.0", + "Corvus.Identity.Abstractions": "3.0.0-alpha.2", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" + } + }, + "Corvus.Identity.MicrosoftRest": { + "type": "Transitive", + "resolved": "3.0.0-alpha.2", + "contentHash": "97ZgmvdWe8Dy0oAkps9qMZ7r3JHdHLHtAa53cedZam2c2SPIb9ZAttNG6wvxmP3up1lVnbEdLv3JxopgWvcb7g==", + "dependencies": { + "Corvus.Identity.Azure": "3.0.0-alpha.2", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", "Microsoft.Rest.ClientRuntime": "2.3.23" } }, @@ -284,14 +341,10 @@ "System.Text.Encodings.Web": "4.5.0" } }, - "Microsoft.Azure.Services.AppAuthentication": { + "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", - "resolved": "1.6.1", - "contentHash": "78AcjpxnhJDov7HJa4kPpZxpI0coZhS0tdA9ZLUSPExKz5KTgfozayBTLAXDuTuq0gLRzFyf85SvIkrtbB8KpA==", - "dependencies": { - "Microsoft.IdentityModel.Clients.ActiveDirectory": "5.2.0", - "System.Diagnostics.Process": "4.3.0" - } + "resolved": "1.0.0", + "contentHash": "K63Y4hORbBcKLWH5wnKgzyn7TOfYzevIEwIedQHBIkmkEBA9SCqgvom+XTuE+fAFGvINGkhFItaZ2dvMGdT5iw==" }, "Microsoft.CodeAnalysis.Analyzers": { "type": "Transitive", @@ -510,23 +563,18 @@ "resolved": "3.1.21", "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" }, - "Microsoft.IdentityModel.Clients.ActiveDirectory": { + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.30.1", + "contentHash": "xk8tJeGfB2yD3+d7a0DXyV7/HYyEG10IofUHYHoPYKmDbroi/j9t1BqSHgbq1nARDjg7m8Ki6e21AyNU7e/R4Q==" + }, + "Microsoft.Identity.Client.Extensions.Msal": { "type": "Transitive", - "resolved": "5.2.0", - "contentHash": "5zCom0plcWSAuPp2B/Fo7XFKdrPUOaE+1dhVW5Ui2Gny7YYv1fDJ1Z8GeZEJuCd3rKN4UBO834wPEhU5gIPQMw==", + "resolved": "2.18.4", + "contentHash": "HpG4oLwhQsy0ce7OWq9iDdLtJKOvKRStIKoSEOeBMKuohfuOWNDyhg8fMAJkpG/kFeoe4J329fiMHcJmmB+FPw==", "dependencies": { - "Microsoft.CSharp": "4.3.0", - "NETStandard.Library": "1.6.1", - "System.ComponentModel.TypeConverter": "4.3.0", - "System.Dynamic.Runtime": "4.3.0", - "System.Net.Http": "4.3.4", - "System.Runtime.Serialization.Formatters": "4.3.0", - "System.Runtime.Serialization.Json": "4.3.0", - "System.Runtime.Serialization.Primitives": "4.3.0", - "System.Security.Cryptography.X509Certificates": "4.3.0", - "System.Security.SecureString": "4.3.0", - "System.Xml.XDocument": "4.3.0", - "System.Xml.XmlDocument": "4.3.0" + "Microsoft.Identity.Client": "4.30.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" } }, "Microsoft.Net.Http.Headers": { @@ -883,8 +931,8 @@ }, "System.Buffers": { "type": "Transitive", - "resolved": "4.5.0", - "contentHash": "pL2ChpaRRWI/p4LXyy4RgeWlYF2sgfj/pnVMvBqwNFr5cXg7CXNnWZWxrOONLg8VGdFB8oB+EG2Qw4MLgTOe+A==" + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" }, "System.CodeDom": { "type": "Transitive", @@ -1053,16 +1101,6 @@ "runtime.native.System": "4.3.0" } }, - "System.Diagnostics.Tools": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.NETCore.Targets": "1.1.0", - "System.Runtime": "4.3.0" - } - }, "System.Diagnostics.TraceSource": { "type": "Transitive", "resolved": "4.3.0", @@ -1235,6 +1273,15 @@ "resolved": "4.5.4", "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, "System.Net.Http": { "type": "Transitive", "resolved": "4.3.4", @@ -1279,6 +1326,11 @@ "System.Runtime.Handles": "4.3.0" } }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, "System.ObjectModel": { "type": "Transitive", "resolved": "4.3.0", @@ -1291,38 +1343,6 @@ "System.Threading": "4.3.0" } }, - "System.Private.DataContractSerialization": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "yDaJ2x3mMmjdZEDB4IbezSnCsnjQ4BxinKhRAaP6kEgL6Bb6jANWphs5SzyD8imqeC/3FxgsuXT6ykkiH1uUmA==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Collections.Concurrent": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Linq": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Emit.ILGeneration": "4.3.0", - "System.Reflection.Emit.Lightweight": "4.3.0", - "System.Reflection.Extensions": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Runtime.Serialization.Primitives": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Text.Encoding.Extensions": "4.3.0", - "System.Text.RegularExpressions": "4.3.0", - "System.Threading": "4.3.0", - "System.Threading.Tasks": "4.3.0", - "System.Xml.ReaderWriter": "4.3.0", - "System.Xml.XDocument": "4.3.0", - "System.Xml.XmlDocument": "4.3.0", - "System.Xml.XmlSerializer": "4.3.0" - } - }, "System.Reflection": { "type": "Transitive", "resolved": "4.3.0", @@ -1500,37 +1520,6 @@ "System.Runtime.Extensions": "4.3.0" } }, - "System.Runtime.Serialization.Formatters": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "KT591AkTNFOTbhZlaeMVvfax3RqhH1EJlcwF50Wm7sfnBLuHiOeZRRKrr1ns3NESkM20KPZ5Ol/ueMq5vg4QoQ==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Reflection": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Serialization.Primitives": "4.3.0" - } - }, - "System.Runtime.Serialization.Json": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "CpVfOH0M/uZ5PH+M9+Gu56K0j9lJw3M+PKRegTkcrY/stOIvRUeonggxNrfBYLA5WOHL2j15KNJuTuld3x4o9w==", - "dependencies": { - "System.IO": "4.3.0", - "System.Private.DataContractSerialization": "4.3.0", - "System.Runtime": "4.3.0" - } - }, - "System.Runtime.Serialization.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==", - "dependencies": { - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0" - } - }, "System.Security.AccessControl": { "type": "Transitive", "resolved": "4.7.0", @@ -1702,21 +1691,6 @@ "resolved": "4.7.0", "contentHash": "ojD0PX0XhneCsUbAZVKdb7h/70vyYMDYs85lwEI+LngEONe/17A0cFaRFqZU+sOEidcVswYWikYOQ9PPfjlbtQ==" }, - "System.Security.SecureString": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "PnXp38O9q/2Oe4iZHMH60kinScv6QiiL2XH54Pj2t0Y6c2zKPEiAZsM/M3wBOHLNTBDFP0zfy13WN2M0qFz5jg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Handles": "4.3.0", - "System.Runtime.InteropServices": "4.3.0", - "System.Security.Cryptography.Primitives": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Threading": "4.3.0" - } - }, "System.Text.Encoding": { "type": "Transitive", "resolved": "4.3.0", @@ -1752,6 +1726,11 @@ "resolved": "4.7.2", "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.6.0", + "contentHash": "4F8Xe+JIkVoDJ8hDAZ7HqLkjctN/6WItJIzQaifBwClC7wmoLSda/Sv2i6i1kycqDb3hWF4JCVbpAweyOKHEUA==" + }, "System.Text.RegularExpressions": { "type": "Transitive", "resolved": "4.3.0", @@ -1823,25 +1802,6 @@ "System.Threading.Tasks.Extensions": "4.3.0" } }, - "System.Xml.XDocument": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Diagnostics.Tools": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Reflection": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Threading": "4.3.0", - "System.Xml.ReaderWriter": "4.3.0" - } - }, "System.Xml.XmlDocument": { "type": "Transitive", "resolved": "4.3.0", @@ -1859,30 +1819,6 @@ "System.Xml.ReaderWriter": "4.3.0" } }, - "System.Xml.XmlSerializer": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "MYoTCP7EZ98RrANESW05J5ZwskKDoN0AuZ06ZflnowE50LTpbR5yRg3tHckTVm5j/m47stuGgCrCHWePyHS70Q==", - "dependencies": { - "System.Collections": "4.3.0", - "System.Globalization": "4.3.0", - "System.IO": "4.3.0", - "System.Linq": "4.3.0", - "System.Reflection": "4.3.0", - "System.Reflection.Emit": "4.3.0", - "System.Reflection.Emit.ILGeneration": "4.3.0", - "System.Reflection.Extensions": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Reflection.TypeExtensions": "4.3.0", - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0", - "System.Runtime.Extensions": "4.3.0", - "System.Text.RegularExpressions": "4.3.0", - "System.Threading": "4.3.0", - "System.Xml.ReaderWriter": "4.3.0", - "System.Xml.XmlDocument": "4.3.0" - } - }, "System.Xml.XPath": { "type": "Transitive", "resolved": "4.3.0", @@ -1930,7 +1866,7 @@ "CacheCow.Client": "2.8.3", "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Corvus.Identity.ManagedServiceIdentity.ClientAuthentication": "1.0.7", + "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.2", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json index 96d91d63..d5701541 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json @@ -226,11 +226,11 @@ }, "Corvus.Storage.Azure.BlobStorage.Tenancy": { "type": "Transitive", - "resolved": "3.0.0-make-v2config-legacy-public.3", - "contentHash": "6m+s8Ki5m7xl0tXtjUdE/1SsFlkip5/rNh3REy3tQKg8oHUO4VHbj3CjjMFBrAtQQ/wb95aHiL1az3R8pJBceA==", + "resolved": "3.0.0-alpha.3", + "contentHash": "aQ/WtonoXdEtJbnx5H9++LyOQscxdsOLR7B6u4SIWYsNqq3Lsxb9GNmVN2OVh3TaaMPoLCKVUEUUKd2Sp/t/Rg==", "dependencies": { "Corvus.Storage.Azure.BlobStorage": "3.0.0-1-refactor-from-tenancy.10", - "Corvus.Tenancy.Abstractions": "3.0.0-make-v2config-legacy-public.3" + "Corvus.Tenancy.Abstractions": "3.0.0-alpha.3" } }, "Corvus.Storage.Common": { @@ -245,8 +245,8 @@ }, "Corvus.Tenancy.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-make-v2config-legacy-public.3", - "contentHash": "MD+0aq9+HSjfxZ1qNc0KOBN/kZ5paT5mrc12/bPYDokuF+Cvml+BkkbQo1ydsDwxgZNrKnOGIYc5AlEf/BYANg==", + "resolved": "3.0.0-alpha.3", + "contentHash": "YsPXYMqVXydyZp9I28bwFZV9cjA5XUJIHInw8iN/WVHUegPYr0rrP38PltqnPLn6cLnInEA9Ge4NMUM9EUFa3A==", "dependencies": { "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", @@ -1767,7 +1767,7 @@ "marain.tenancy.storage.azure.blobstorage": { "type": "Project", "dependencies": { - "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-make-v2config-legacy-public.3", + "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-alpha.3", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0" } } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj index 2596f274..5f64e067 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj @@ -16,7 +16,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 49b3eeadfa64120712434738539a8a0b374f84ec Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Thu, 2 Dec 2021 17:02:57 +0000 Subject: [PATCH 05/10] Use newly synchronous IServiceIdentityMicrosoftRestTokenProviderSource (#358) --- .../Marain.Tenancy.Cli/packages.lock.json | 18 +++++++++--------- .../Marain.Tenancy.Client.csproj | 2 +- ...TenancyClientServiceCollectionExtensions.cs | 3 +-- .../Marain.Tenancy.Specs/packages.lock.json | 18 +++++++++--------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/Solutions/Marain.Tenancy.Cli/packages.lock.json b/Solutions/Marain.Tenancy.Cli/packages.lock.json index 8003a07a..49ccceac 100644 --- a/Solutions/Marain.Tenancy.Cli/packages.lock.json +++ b/Solutions/Marain.Tenancy.Cli/packages.lock.json @@ -166,26 +166,26 @@ }, "Corvus.Identity.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-alpha.2", - "contentHash": "q5SUNlPsyVoneFA5wHR8G6xP/RbE5i0OaA91c+WzdYCJYHSIYNXhdTQ9OAJdytw3URb4MQxSlgwsUMpZSrnnZg==" + "resolved": "3.0.0-alpha.3", + "contentHash": "9ejidQMzyEnEmjRn7fWIqbcYPnO79eeyGDf+2vCDRT4SxclwLQ97IIt0LMZSeqnqhdlm6lqZojJB0B84e+jR+Q==" }, "Corvus.Identity.Azure": { "type": "Transitive", - "resolved": "3.0.0-alpha.2", - "contentHash": "D+h1A+9TLSaCsV5hHTn8OC6+DzOto0YiTlS4EDLvpZg0TY3i+Z7FHyMa/+crtBFxCinO8T/Yl3lZcZscTQ1D8Q==", + "resolved": "3.0.0-alpha.3", + "contentHash": "MYFzUYDF1kACA18Vb+5+sfQ5fv58pAAipfq7BHM/5tDs5xcfrGErcitFS3fbPTCVrSAW62E9hEpsiuXNPzc7TA==", "dependencies": { "Azure.Identity": "1.4.1", "Azure.Security.KeyVault.Secrets": "4.2.0", - "Corvus.Identity.Abstractions": "3.0.0-alpha.2", + "Corvus.Identity.Abstractions": "3.0.0-alpha.3", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" } }, "Corvus.Identity.MicrosoftRest": { "type": "Transitive", - "resolved": "3.0.0-alpha.2", - "contentHash": "97ZgmvdWe8Dy0oAkps9qMZ7r3JHdHLHtAa53cedZam2c2SPIb9ZAttNG6wvxmP3up1lVnbEdLv3JxopgWvcb7g==", + "resolved": "3.0.0-alpha.3", + "contentHash": "aOHqhlUH57XB+m1m103eyKs7m4XZ83LkkV2eHUu799XX8MdAwGRhuOme34u6PeZRj0hy35qcfJMx8H7MQ11/oA==", "dependencies": { - "Corvus.Identity.Azure": "3.0.0-alpha.2", + "Corvus.Identity.Azure": "3.0.0-alpha.3", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", "Microsoft.Rest.ClientRuntime": "2.3.23" } @@ -1533,7 +1533,7 @@ "CacheCow.Client": "2.8.3", "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.2", + "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.3", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } diff --git a/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj b/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj index 2157953b..ce7f9900 100644 --- a/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj +++ b/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj @@ -27,7 +27,7 @@ - + diff --git a/Solutions/Marain.Tenancy.Client/Marain/Tenancy/Client/TenancyClientServiceCollectionExtensions.cs b/Solutions/Marain.Tenancy.Client/Marain/Tenancy/Client/TenancyClientServiceCollectionExtensions.cs index 65d91eb0..f62fd701 100644 --- a/Solutions/Marain.Tenancy.Client/Marain/Tenancy/Client/TenancyClientServiceCollectionExtensions.cs +++ b/Solutions/Marain.Tenancy.Client/Marain/Tenancy/Client/TenancyClientServiceCollectionExtensions.cs @@ -85,8 +85,7 @@ public static IServiceCollection AddTenancyClient( else { var tokenCredentials = new TokenCredentials( - new MicrosoftRestTokenProvider( - sp.GetRequiredService(), + sp.GetRequiredService().GetTokenProvider( $"{options.ResourceIdForMsiAuthentication}/.default")); service = new TenancyService(options.TenancyServiceBaseUri, tokenCredentials, handlers); } diff --git a/Solutions/Marain.Tenancy.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Specs/packages.lock.json index e3010b5b..f76f21b9 100644 --- a/Solutions/Marain.Tenancy.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Specs/packages.lock.json @@ -166,26 +166,26 @@ }, "Corvus.Identity.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-alpha.2", - "contentHash": "q5SUNlPsyVoneFA5wHR8G6xP/RbE5i0OaA91c+WzdYCJYHSIYNXhdTQ9OAJdytw3URb4MQxSlgwsUMpZSrnnZg==" + "resolved": "3.0.0-alpha.3", + "contentHash": "9ejidQMzyEnEmjRn7fWIqbcYPnO79eeyGDf+2vCDRT4SxclwLQ97IIt0LMZSeqnqhdlm6lqZojJB0B84e+jR+Q==" }, "Corvus.Identity.Azure": { "type": "Transitive", - "resolved": "3.0.0-alpha.2", - "contentHash": "D+h1A+9TLSaCsV5hHTn8OC6+DzOto0YiTlS4EDLvpZg0TY3i+Z7FHyMa/+crtBFxCinO8T/Yl3lZcZscTQ1D8Q==", + "resolved": "3.0.0-alpha.3", + "contentHash": "MYFzUYDF1kACA18Vb+5+sfQ5fv58pAAipfq7BHM/5tDs5xcfrGErcitFS3fbPTCVrSAW62E9hEpsiuXNPzc7TA==", "dependencies": { "Azure.Identity": "1.4.1", "Azure.Security.KeyVault.Secrets": "4.2.0", - "Corvus.Identity.Abstractions": "3.0.0-alpha.2", + "Corvus.Identity.Abstractions": "3.0.0-alpha.3", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" } }, "Corvus.Identity.MicrosoftRest": { "type": "Transitive", - "resolved": "3.0.0-alpha.2", - "contentHash": "97ZgmvdWe8Dy0oAkps9qMZ7r3JHdHLHtAa53cedZam2c2SPIb9ZAttNG6wvxmP3up1lVnbEdLv3JxopgWvcb7g==", + "resolved": "3.0.0-alpha.3", + "contentHash": "aOHqhlUH57XB+m1m103eyKs7m4XZ83LkkV2eHUu799XX8MdAwGRhuOme34u6PeZRj0hy35qcfJMx8H7MQ11/oA==", "dependencies": { - "Corvus.Identity.Azure": "3.0.0-alpha.2", + "Corvus.Identity.Azure": "3.0.0-alpha.3", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", "Microsoft.Rest.ClientRuntime": "2.3.23" } @@ -1866,7 +1866,7 @@ "CacheCow.Client": "2.8.3", "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.2", + "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.3", "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } From ea7d9e89226ed2456b757dfa57c3ca4b90b8fbfd Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Fri, 3 Dec 2021 19:53:18 +0000 Subject: [PATCH 06/10] Upgrade to .NET 6.0 (#359) --- .../Marain.Tenancy.Cli.csproj | 4 +- .../Marain/Tenancy/Cli/Commands/Create.cs | 2 +- .../Marain/Tenancy/Cli/TenancyCliCommand.cs | 2 + .../Marain.Tenancy.Cli/packages.lock.json | 320 ++++++++++-------- .../Marain.Tenancy.Client.csproj | 4 +- ...Marain.Tenancy.ClientTenantProvider.csproj | 2 +- .../Marain/Tenancy/ClientTenantStore.cs | 16 +- .../Marain/Tenancy/Mappers/TenantMapper.cs | 2 +- .../Marain.Tenancy.Deployment.csproj | 2 +- .../Marain.Tenancy.Host.Functions.csproj | 8 +- .../local.settings.template.json | 2 +- .../packages.lock.json | 206 ++++++----- .../Marain.Tenancy.Hosting.AspNetCore.csproj | 5 +- .../TenancyServiceCollectionExtensions.cs | 9 +- .../Marain.Tenancy.OpenApi.Service.csproj | 13 +- .../Marain/Tenancy/OpenApi/TenancyService.cs | 10 +- .../Integration/Bindings/FunctionBindings.cs | 4 +- .../Bindings/TenancyClientBindings.cs | 4 +- .../Integration/Bindings/TestTenantCleanup.cs | 3 +- .../Integration/Steps/JsonSteps.cs | 10 +- .../Integration/Steps/TenancyApiSteps.cs | 23 +- .../Marain.Tenancy.Specs.csproj | 8 +- .../Marain.Tenancy.Specs/packages.lock.json | 194 ++++++----- .../TenancyContainerSetupDirectToStorage.cs | 8 +- .../Bindings/TenancyContainerSetupViaApi.cs | 8 +- ...ncy.Storage.Azure.BlobStorage.Specs.csproj | 12 +- .../MultiMode/MultiSetupTestBase.cs | 4 +- .../EnumerateChildTenantsSteps.cs | 2 +- .../local.settings.template.json | 10 +- .../packages.lock.json | 120 ++++--- ...n.Tenancy.Storage.Azure.BlobStorage.csproj | 4 +- .../AzureBlobStorageTenantStore.cs | 2 +- azure-pipelines.yml | 16 +- build.ps1 | 140 ++++++++ 34 files changed, 704 insertions(+), 475 deletions(-) create mode 100644 build.ps1 diff --git a/Solutions/Marain.Tenancy.Cli/Marain.Tenancy.Cli.csproj b/Solutions/Marain.Tenancy.Cli/Marain.Tenancy.Cli.csproj index 4e479805..b19e7ce0 100644 --- a/Solutions/Marain.Tenancy.Cli/Marain.Tenancy.Cli.csproj +++ b/Solutions/Marain.Tenancy.Cli/Marain.Tenancy.Cli.csproj @@ -3,7 +3,7 @@ Exe - netcoreapp3.1 + net6.0 tenancy false enable @@ -40,7 +40,7 @@ - + diff --git a/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/Commands/Create.cs b/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/Commands/Create.cs index 434c1a90..748580c2 100644 --- a/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/Commands/Create.cs +++ b/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/Commands/Create.cs @@ -73,7 +73,7 @@ public async Task OnExecute(CommandLineApplication app) if (string.IsNullOrEmpty(this.Name)) { - throw new ArgumentException("Name must be supplied", nameof(this.Name)); + throw new InvalidOperationException("Name must be supplied"); } Guid wellKnownGuid = string.IsNullOrEmpty(this.WellKnownTenantGuid) diff --git a/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/TenancyCliCommand.cs b/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/TenancyCliCommand.cs index 7fff9658..ae856a47 100644 --- a/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/TenancyCliCommand.cs +++ b/Solutions/Marain.Tenancy.Cli/Marain/Tenancy/Cli/TenancyCliCommand.cs @@ -4,6 +4,7 @@ namespace Marain.Tenancy.Cli { + using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Marain.Tenancy.Cli.Commands; using McMaster.Extensions.CommandLineUtils; @@ -23,6 +24,7 @@ public class TenancyCliCommand /// /// The current CommandLineApplication. /// A representing the asynchronous operation. + [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "The command line framework requires this to be an instance method")] protected Task OnExecute(CommandLineApplication app) { app.ShowHelp(); diff --git a/Solutions/Marain.Tenancy.Cli/packages.lock.json b/Solutions/Marain.Tenancy.Cli/packages.lock.json index 49ccceac..15b4025f 100644 --- a/Solutions/Marain.Tenancy.Cli/packages.lock.json +++ b/Solutions/Marain.Tenancy.Cli/packages.lock.json @@ -1,7 +1,7 @@ { "version": 1, "dependencies": { - ".NETCoreApp,Version=v3.1": { + "net6.0": { "ConsoleTables": { "type": "Direct", "requested": "[2.4.2, )", @@ -41,22 +41,31 @@ }, "Microsoft.Extensions.Hosting": { "type": "Direct", - "requested": "[3.1.*, )", - "resolved": "3.1.21", - "contentHash": "SZkklCAA1KMAo4qGMix43qUaBhjk0nfMLNcgik/GRxJ2H/W6a3woO2Q2ixlJN9XAqnJgYMMPVqGDbENguqrznw==", - "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21", - "Microsoft.Extensions.Configuration.CommandLine": "3.1.21", - "Microsoft.Extensions.Configuration.EnvironmentVariables": "3.1.21", - "Microsoft.Extensions.Configuration.UserSecrets": "3.1.21", - "Microsoft.Extensions.DependencyInjection": "3.1.21", - "Microsoft.Extensions.FileProviders.Physical": "3.1.21", - "Microsoft.Extensions.Hosting.Abstractions": "3.1.21", - "Microsoft.Extensions.Logging": "3.1.21", - "Microsoft.Extensions.Logging.Console": "3.1.21", - "Microsoft.Extensions.Logging.Debug": "3.1.21", - "Microsoft.Extensions.Logging.EventLog": "3.1.21", - "Microsoft.Extensions.Logging.EventSource": "3.1.21" + "requested": "[6.0.*, )", + "resolved": "6.0.0", + "contentHash": "M8VzD0ni5VarIRT8njnwK4K2WSAo0kZH4Zc3mKcSGkP4CjDZ91T9ZEFmmwhmo4z7x8AFq+tW0WFi9wX+K2cxkQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.Binder": "6.0.0", + "Microsoft.Extensions.Configuration.CommandLine": "6.0.0", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "6.0.0", + "Microsoft.Extensions.Configuration.FileExtensions": "6.0.0", + "Microsoft.Extensions.Configuration.Json": "6.0.0", + "Microsoft.Extensions.Configuration.UserSecrets": "6.0.0", + "Microsoft.Extensions.DependencyInjection": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Physical": "6.0.0", + "Microsoft.Extensions.Hosting.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Configuration": "6.0.0", + "Microsoft.Extensions.Logging.Console": "6.0.0", + "Microsoft.Extensions.Logging.Debug": "6.0.0", + "Microsoft.Extensions.Logging.EventLog": "6.0.0", + "Microsoft.Extensions.Logging.EventSource": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0" } }, "StyleCop.Analyzers": { @@ -280,200 +289,238 @@ }, "Microsoft.Extensions.Configuration": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "iFO6wyyv/mBr6v9wBJXG+i4baN1GOUf2ClwJilWSSE8CnWgEV2T7w4sTRmE73iS3tdHBiMMnQ2Ynyw8X78ayVw==", + "resolved": "6.0.0", + "contentHash": "tq2wXyh3fL17EMF2bXgRhU7JrbO3on93MRKYxzz4JzzvuGSA1l0W3GI9/tl8EO89TH+KWEymP7bcFway6z9fXg==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "3Ef65E9wCkGJVPQZ7S7GtDJ8JXpCQ3c2b83XLIOINoVV7GSEjKyW/vycc3jQfdc5BIf/lnjodkDiKnjdTzXAZA==", + "resolved": "6.0.0", + "contentHash": "qWzV9o+ZRWq+pGm+1dF+R7qTgTYoXvbyowRoBxQJGfqTpqDun2eteerjRQhq5PQ/14S+lqto3Ft4gYaRyl4rdQ==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.Binder": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "gMI0aMhlJzOvqhREbENDufDaSwnxBs6COgEz+owrfFcb1J2yvBZqhN9YIayHn03JMvm8xtSmNzNL/ZCm7TWjsw==", + "resolved": "6.0.0", + "contentHash": "b3ErKzND8LIC7o08QAVlKfaEIYEvLJbtmVbFZVBRXeu9YkKfSSzLZfR1SUfQPBIy9mKLhEtJgGYImkcMNaKE0A==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Configuration.CommandLine": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "XwAttgBpOvasVPqS1XBq3+ncxwLMIZVWDOO+G8XCQhVhIu1rOByei9psFFMbU/4QBYYWuHEvsD4VvnrVrx3ffA==", + "resolved": "6.0.0", + "contentHash": "3nL1qCkZ1Oxx14ZTzgo4MmlO7tso7F+TtMZAY2jUAtTLyAcDp+EDjk3RqafoKiNaePyPvvlleEcBxh3b2Hzl1g==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Configuration.EnvironmentVariables": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "4nMwSpAIANpzegZxT05jO2IM30kdRtHSfJOBXI3V8fVXlhxsXBj5EEQGSOnSzzEaeBzHkjQFF4dxDHIgMuYwmQ==", + "resolved": "6.0.0", + "contentHash": "DjYkzqvhiHCq38LW71PcIxXk6nhtV6VySP9yDcSO0goPl7YCU1VG1f2Wbgy58lkA10pWkjHCblZPUyboCB93ZA==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Configuration.FileExtensions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "uAucC/Vq3/2duacja/sLbMKU9y2RJT9uloFT1xrl3MufDKFRAkSbIakw2Rv61XNqHCcEIHgsUiW/L7Tuz7Uomw==", + "resolved": "6.0.0", + "contentHash": "V4Dth2cYMZpw3HhGw9XUDIijpI6gN+22LDt0AhufIgOppCUfpWX4483OmN+dFXRJkJLc8Tv0Q8QK+1ingT2+KQ==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21", - "Microsoft.Extensions.FileProviders.Physical": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Physical": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.Json": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "JATr/lcsjJM8R9hyylxWzR+fxteAf0xv2SBD5tpLj1qPVauuuwcgKe3swfMK/TyfP/tVHNeuLVlfBlcl6ZIhjQ==", + "resolved": "6.0.0", + "contentHash": "GJGery6QytCzS/BxJ96klgG9in3uH26KcUBbiVG/coNDXCRq6LGVVlUT4vXq34KPuM+R2av+LeYdX9h4IZOCUg==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21", - "Microsoft.Extensions.Configuration.FileExtensions": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.FileExtensions": "6.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "System.Text.Json": "6.0.0" } }, "Microsoft.Extensions.Configuration.UserSecrets": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "myw1iM0S+0Z1+TMbuRvAB/xLuTUVKecB08M+mCxLh3gsPsueAIXD/IA5xWhx2njKRXWhAXdayfycR6bZaY2wbg==", + "resolved": "6.0.0", + "contentHash": "lB0Hb2V4+RUHy+LjEcqEr4EcV4RWc9EnjAV2GdtWQEdljQX+R4hGREftI7sInU9okP93pDrJiaj6QUJ6ZsslOA==", "dependencies": { - "Microsoft.Extensions.Configuration.Json": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.Json": "6.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Physical": "6.0.0" } }, "Microsoft.Extensions.DependencyInjection": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "js24vxT9kzGfH7nc/EL9Yi2s5jQilFTxIYHIpX/oIEINVRW4qlnQXsfzsbXE5Y0BAG5TTidnfZ+IyOEsW9XTVA==", + "resolved": "6.0.0", + "contentHash": "k6PWQMuoBDGGHOQTtyois2u4AwyVcIwL2LaSLlTZQm2CYcJ1pxbt6jfAnpWmzENA/wfrYRI/X9DTLoUkE4AsLw==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "PWfBWk54+UcMYA/DqD0l/HSOlbnclR4kp6rYgI28s5zPZ8tIMetKa9+jk+cialrSbvz/+xs/JrXqy7VDiy/0dQ==" + "resolved": "6.0.0", + "contentHash": "xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg==" }, "Microsoft.Extensions.FileProviders.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "52amnz03Px8X7Pw7uI6qrQPUx++Qq7MB5rhjJh+4YRq3NgUls4KqJDvOuGnnS4pRt2T8IbIrgYxRn2wMrW8Xwg==", + "resolved": "6.0.0", + "contentHash": "0pd4/fho0gC12rQswaGQxbU34jOS1TPS8lZPpkFCH68ppQjHNHYle9iRuHeev1LhrJ94YPvzcRd8UmIuFk23Qw==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.FileProviders.Physical": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "w8vwWXVdFPX/hJptNybW6Nv21j3I6vOrztt3gwp0IPts+v56X9tNjR36ivx6CbEpDs2jP2kx8w8YOTYVwIuwgg==", + "resolved": "6.0.0", + "contentHash": "QvkL7l0nM8udt3gfyu0Vw8bbCXblxaKOl7c2oBfgGy4LCURRaL9XWZX1FWJrQc43oMokVneVxH38iz+bY1sbhg==", "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "3.1.21", - "Microsoft.Extensions.FileSystemGlobbing": "3.1.21" + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "Microsoft.Extensions.FileSystemGlobbing": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.FileSystemGlobbing": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "Vao4dtipoDQf6jkfYql9MZWJm1U2gv5Ro4a0sMuE0K8Ze3+yRmSyNTtmZer8GLb99xAGyYa2JhfQlFobt269aA==" + "resolved": "6.0.0", + "contentHash": "ip8jnL1aPiaPeKINCqaTEbvBFDmVx9dXQEBZ2HOBRXPD1eabGNqP/bKlsIcp7U2lGxiXd5xIhoFcmY8nM4Hdiw==" }, "Microsoft.Extensions.Hosting.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "0l0tDTMEkPzm/mz8J1msoqxih60pqwIEWsH0FIwGrkwEFpA3MzhL14T5j+iwg3hUawsfsxrwJVsMc9U3zo24yw==", + "resolved": "6.0.0", + "contentHash": "GcT5l2CYXL6Sa27KCSh0TixsRfADUgth+ojQSD5EkzisZxmGFh7CwzkcYuGwvmXLjr27uWRNrJ2vuuEjMhU05Q==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", - "Microsoft.Extensions.FileProviders.Abstractions": "3.1.21", - "Microsoft.Extensions.Logging.Abstractions": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "5D0RMBkH4eliNeR2a3VFV4stIer/CsFTeAGo2Uv1dm2X9Ttz8n0lbc7gl8+NogTiKfGm1RqoLF0HtH/1V4wxmw==", + "resolved": "6.0.0", + "contentHash": "eIbyj40QDg1NDz0HBW0S5f3wrLVnKWnDJ/JtZ+yJDFnDj90VoPuoPmFkeaXrtu+0cKm5GRAwoDf+dBWXK0TUdg==", "dependencies": { - "Microsoft.Extensions.Configuration.Binder": "3.1.21", - "Microsoft.Extensions.DependencyInjection": "3.1.21", - "Microsoft.Extensions.Logging.Abstractions": "3.1.21", - "Microsoft.Extensions.Options": "3.1.21" + "Microsoft.Extensions.DependencyInjection": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "System.Diagnostics.DiagnosticSource": "6.0.0" } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "FTEjNPyjJ4eXp+dAP8YfH/MRk0LAKXhQ6FHOX9Wju7AB0/huyjG7NQGWFrnDmviPyCMzR1ZitjT/Zv27JfEsEw==" + "resolved": "6.0.0", + "contentHash": "/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==" }, "Microsoft.Extensions.Logging.Configuration": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "E2rKFPOPAiDdPszCN0VWOpRoqZ0gBfIXkX5K9l93ZgK4z7RyqYDD/gqpF33bc0OZTjGovgItrZ/zHawazplMrA==", + "resolved": "6.0.0", + "contentHash": "ZDskjagmBAbv+K8rYW9VhjPplhbOE63xUD0DiuydZJwt15dRyoqicYklLd86zzeintUc7AptDkHn+YhhYkYo8A==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.21", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.Binder": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "6.0.0" } }, "Microsoft.Extensions.Logging.Console": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "wLKHCHAhQxBTwwznLySdLnJEmpo/l9+LeqEOrMNkHXfDu+Cx0cVX1U/m1PV2JJonpwEqeChE311OCLF+MZv1iA==", + "resolved": "6.0.0", + "contentHash": "gsqKzOEdsvq28QiXFxagmn1oRB9GeI5GgYCkoybZtQA0IUb7QPwf1WmN3AwJeNIsadTvIFQCiVK0OVIgKfOBGg==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", - "Microsoft.Extensions.Logging": "3.1.21", - "Microsoft.Extensions.Logging.Configuration": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Configuration": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "System.Text.Json": "6.0.0" } }, "Microsoft.Extensions.Logging.Debug": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "/WZhDvqehx5Ls1A7JfyNjXTpmeeTCt1LEbq1ScNgYuf8KVGypurvBKbiksGcumQ+T+izgXiLlcLWFDu3pQm+9Q==", + "resolved": "6.0.0", + "contentHash": "M9g/JixseSZATJE9tcMn9uzoD4+DbSglivFqVx8YkRJ7VVPmnvCEbOZ0AAaxsL1EKyI4cz07DXOOJExxNsUOHw==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Logging.EventLog": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "MDWWRs8qT2ppfiueVZhSWyJVhsgWY6Yryy2wpn5HCI78I6GKaq1g42m46mL4ftgPJQvGW+d3MAch62b9MgZCKQ==", + "resolved": "6.0.0", + "contentHash": "rlo0RxlMd0WtLG3CHI0qOTp6fFn7MvQjlrCjucA31RqmiMFCZkF8CHNbe8O7tbBIyyoLGWB1he9CbaA5iyHthg==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.21", - "System.Diagnostics.EventLog": "4.7.0" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "System.Diagnostics.EventLog": "6.0.0" } }, "Microsoft.Extensions.Logging.EventSource": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "N290999NEj1ZgtpV4SIbYNP+dCh2wC2wFQWphFi0DGDe+4YAvMk1B6jnv7rCeqK5+sYNcg+27JLQc2tN44lthg==", + "resolved": "6.0.0", + "contentHash": "BeDyyqt7nkm/nr+Gdk+L8n1tUT/u33VkbXAOesgYSNsxDM9hJ1NOBGoZfj9rCbeD2+9myElI6JOVVFmnzgeWQA==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Json": "6.0.0" } }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "lLI84rWombp1a6RF8VKBP9Iu4AYif5GqyxDYrkwvnMt1hagwRyJQpm6EiamFRyQYdGpEpTZNblUygYY7dEn9xg==", + "resolved": "6.0.0", + "contentHash": "dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Options.ConfigurationExtensions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "8SXTqWPYOYdM0O51/cB7wzVsqFemCGMbcHb82Ix5bmsHO8stcb7YKXERiQ18JSigVogb828gCTK8gMfiSGO4ug==", + "resolved": "6.0.0", + "contentHash": "bXWINbTn0vC0FYc9GaQTISbxhQLAMrvtbuvD9N6JelEaIS/Pr62wUCinrq5bf1WRBGczt1v4wDhxFtVFNcMdUQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", - "Microsoft.Extensions.Configuration.Binder": "3.1.21", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", - "Microsoft.Extensions.Options": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.Binder": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" + "resolved": "6.0.0", + "contentHash": "9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "Microsoft.Identity.Client": { "type": "Transitive", @@ -500,8 +547,8 @@ }, "Microsoft.NETCore.Platforms": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "z7aeg8oHln2CuNulfhiLYxCVMPEwBl3rzicjvIX+4sUuCwvXw5oXQEtbiU2c0z4qYL5L3Kmx0mMA/+t/SbY67w==" + "resolved": "2.1.2", + "contentHash": "mOJy3M0UN+LUG21dLGMxaWZEP6xYpQEpLuvuEQBaownaX4YuhH6NmNUlN9si+vNkAS6dwJ//N1O4DmLf2CikVg==" }, "Microsoft.NETCore.Targets": { "type": "Transitive", @@ -540,15 +587,6 @@ "System.Runtime": "4.3.0" } }, - "Microsoft.Win32.Registry": { - "type": "Transitive", - "resolved": "4.7.0", - "contentHash": "KSrRMb5vNi0CWSGG1++id2ZOs/1QhRqROt+qgbEAdQuGjGrFcl4AOl4/exGPUYz2wUnU42nvJqon1T3U0kPXLA==", - "dependencies": { - "System.Security.AccessControl": "4.7.0", - "System.Security.Principal.Windows": "4.7.0" - } - }, "NETStandard.Library": { "type": "Transitive", "resolved": "1.6.1", @@ -795,18 +833,16 @@ }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", - "resolved": "4.6.0", - "contentHash": "mbBgoR0rRfl2uimsZ2avZY8g7Xnh1Mza0rJZLPcxqiMWlkGukjmRkuMJ/er+AhQuiRIh80CR/Hpeztr80seV5g==" + "resolved": "6.0.0", + "contentHash": "frQDfv0rl209cKm1lnwTgFPzNigy2EKk1BS3uAvHvlBVKe5cymGyHO+Sj+NLv5VF/AhHsqPIUUwya5oV4CHMUw==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "System.Diagnostics.EventLog": { "type": "Transitive", - "resolved": "4.7.0", - "contentHash": "iDoKGQcRwX0qwY+eAEkaJGae0d/lHlxtslO+t8pJWAUxlvY3tqLtVOPnW2UU4cFjP0Y/L1QBqhkZfSyGqVMR2w==", - "dependencies": { - "Microsoft.NETCore.Platforms": "3.1.0", - "Microsoft.Win32.Registry": "4.7.0", - "System.Security.Principal.Windows": "4.7.0" - } + "resolved": "6.0.0", + "contentHash": "lcyUiXTsETK2ALsZrX+nWuHSIQeazhqPphLfaRxzdGaG93+0kELqpgEHtwWOlQe7+jSFnKwaCAgL4kjeZCQJnw==" }, "System.Diagnostics.Tools": { "type": "Transitive", @@ -1123,10 +1159,7 @@ "System.Reflection.Metadata": { "type": "Transitive", "resolved": "5.0.0", - "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==", - "dependencies": { - "System.Collections.Immutable": "5.0.0" - } + "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" }, "System.Reflection.Primitives": { "type": "Transitive", @@ -1170,8 +1203,8 @@ }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==" + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" }, "System.Runtime.Extensions": { "type": "Transitive", @@ -1241,15 +1274,6 @@ "System.Runtime.Extensions": "4.3.0" } }, - "System.Security.AccessControl": { - "type": "Transitive", - "resolved": "4.7.0", - "contentHash": "JECvTt5aFF3WT3gHpfofL2MNNP6v84sxtXxpqhLBCcDRzqsPBmHhQ6shv4DwwN2tRlzsUxtb3G9M3763rbXKDg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "3.1.0", - "System.Security.Principal.Windows": "4.7.0" - } - }, "System.Security.Cryptography.Algorithms": { "type": "Transitive", "resolved": "4.3.0", @@ -1399,11 +1423,6 @@ "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" } }, - "System.Security.Principal.Windows": { - "type": "Transitive", - "resolved": "4.7.0", - "contentHash": "ojD0PX0XhneCsUbAZVKdb7h/70vyYMDYs85lwEI+LngEONe/17A0cFaRFqZU+sOEidcVswYWikYOQ9PPfjlbtQ==" - }, "System.Text.Encoding": { "type": "Transitive", "resolved": "4.3.0", @@ -1436,13 +1455,20 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "4.7.2", - "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" + "resolved": "6.0.0", + "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "System.Text.Json": { "type": "Transitive", - "resolved": "4.6.0", - "contentHash": "4F8Xe+JIkVoDJ8hDAZ7HqLkjctN/6WItJIzQaifBwClC7wmoLSda/Sv2i6i1kycqDb3hWF4JCVbpAweyOKHEUA==" + "resolved": "6.0.0", + "contentHash": "zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "6.0.0" + } }, "System.Text.RegularExpressions": { "type": "Transitive", @@ -1534,7 +1560,7 @@ "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } }, diff --git a/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj b/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj index ce7f9900..d4f6ca6b 100644 --- a/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj +++ b/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj @@ -6,7 +6,7 @@ --> - netstandard2.0;netstandard2.1 + net6.0 bin\$(Configuration)\ $(OutputPath)$(TargetFramework.ToLowerInvariant())\$(AssemblyName).xml @@ -28,7 +28,7 @@ - + diff --git a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj index cd4bed8d..6050d1b8 100644 --- a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj +++ b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj @@ -2,7 +2,7 @@ - netstandard2.0;netstandard2.1 + net6.0 enable diff --git a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain/Tenancy/ClientTenantStore.cs b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain/Tenancy/ClientTenantStore.cs index cf55d468..9edf3cee 100644 --- a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain/Tenancy/ClientTenantStore.cs +++ b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain/Tenancy/ClientTenantStore.cs @@ -107,7 +107,7 @@ public async Task GetChildrenAsync(string tenantId, int if (getTenantLinks == null) { - tenantIds = new string[0]; + tenantIds = Array.Empty(); } else if (getTenantLinks is JArray) { @@ -198,12 +198,12 @@ public async Task UpdateTenantAsync( { var patch = new List(); - if (name is string) + if (name is not null) { patch.Add(new UpdateTenantJsonPatchEntry("/name", "replace", name)); } - if (!(propertiesToSetOrAdd is null)) + if (propertiesToSetOrAdd is not null) { // When adding new values, we convert them to JTokens here so that we can use our own serializer // settings. Once we send things into the generated TenantService class, we lose control of @@ -224,7 +224,7 @@ public async Task UpdateTenantAsync( } } - if (!(propertiesToRemove is null)) + if (propertiesToRemove is not null) { foreach (string propertyName in propertiesToRemove) { @@ -267,19 +267,15 @@ private async Task CreateChildTenantAsync(string parentTenantId, string } // TODO: How do we determine a duplicate Id? + // See https://github.com/marain-dotnet/Marain.Tenancy/issues/237 if (result.Response.StatusCode == HttpStatusCode.Conflict) { throw new TenantConflictException(); } - if (result.Response.StatusCode == HttpStatusCode.BadRequest) - { - throw new ArgumentException(); - } - if (!result.Response.IsSuccessStatusCode) { - throw new Exception(result.Response.ReasonPhrase); + throw new InvalidOperationException(result.Response.ReasonPhrase); } object tenant = await this.TenantService.GetTenantAsync( diff --git a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain/Tenancy/Mappers/TenantMapper.cs b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain/Tenancy/Mappers/TenantMapper.cs index 7b5f5f66..ba0af47b 100644 --- a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain/Tenancy/Mappers/TenantMapper.cs +++ b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain/Tenancy/Mappers/TenantMapper.cs @@ -72,7 +72,7 @@ public string ExtractTenantIdFrom(Uri baseUri, string location) offset += 1; } - return location.Substring(offset, location.IndexOf('/', offset) - offset); + return location[offset..location.IndexOf('/', offset)]; } /// diff --git a/Solutions/Marain.Tenancy.Deployment/Marain.Tenancy.Deployment.csproj b/Solutions/Marain.Tenancy.Deployment/Marain.Tenancy.Deployment.csproj index 81673606..84d0a85a 100644 --- a/Solutions/Marain.Tenancy.Deployment/Marain.Tenancy.Deployment.csproj +++ b/Solutions/Marain.Tenancy.Deployment/Marain.Tenancy.Deployment.csproj @@ -1,6 +1,6 @@  - netcoreapp3.1 + net6.0 false \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Host.Functions/Marain.Tenancy.Host.Functions.csproj b/Solutions/Marain.Tenancy.Host.Functions/Marain.Tenancy.Host.Functions.csproj index 876bcc46..50434c21 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/Marain.Tenancy.Host.Functions.csproj +++ b/Solutions/Marain.Tenancy.Host.Functions/Marain.Tenancy.Host.Functions.csproj @@ -2,12 +2,12 @@ - netcoreapp3.1 + net6.0 + v4 false - v3 @@ -41,9 +41,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + - + diff --git a/Solutions/Marain.Tenancy.Host.Functions/local.settings.template.json b/Solutions/Marain.Tenancy.Host.Functions/local.settings.template.json index fd2c79d6..52bdb94b 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/local.settings.template.json +++ b/Solutions/Marain.Tenancy.Host.Functions/local.settings.template.json @@ -4,7 +4,7 @@ "AzureWebJobsStorage": "UseDevelopmentStorage=true", "AzureWebJobsDashboard": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "dotnet", - "FUNCTIONS_EXTENSION_VERSION": "~3", + "FUNCTIONS_EXTENSION_VERSION": "~4", "APPINSIGHTS_INSTRUMENTATIONKEY": "", "AI:DeveloperMode": "true", diff --git a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json index 3259d761..7a4ef92f 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json +++ b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json @@ -1,7 +1,7 @@ { "version": 1, "dependencies": { - ".NETCoreApp,Version=v3.1": { + "net6.0": { "Corvus.Monitoring.ApplicationInsights": { "type": "Direct", "requested": "[1.3.2, )", @@ -34,26 +34,29 @@ }, "Microsoft.Extensions.Logging.Console": { "type": "Direct", - "requested": "[3.1.*, )", - "resolved": "3.1.21", - "contentHash": "wLKHCHAhQxBTwwznLySdLnJEmpo/l9+LeqEOrMNkHXfDu+Cx0cVX1U/m1PV2JJonpwEqeChE311OCLF+MZv1iA==", + "requested": "[6.0.*, )", + "resolved": "6.0.0", + "contentHash": "gsqKzOEdsvq28QiXFxagmn1oRB9GeI5GgYCkoybZtQA0IUb7QPwf1WmN3AwJeNIsadTvIFQCiVK0OVIgKfOBGg==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", - "Microsoft.Extensions.Logging": "3.1.21", - "Microsoft.Extensions.Logging.Configuration": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Configuration": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "System.Text.Json": "6.0.0" } }, "Microsoft.NET.Sdk.Functions": { "type": "Direct", - "requested": "[3.0.13, )", - "resolved": "3.0.13", - "contentHash": "8BEt6I6OLm7fo9bh8VGI7Mkc7xs/vI/KDira8MQcfZIA+K+lmDRb2PAL/+728eYfXI4SVrGs4MLhUZvKtpWfvQ==", + "requested": "[4.0.1, )", + "resolved": "4.0.1", + "contentHash": "ETL2yIoB66dUBorl0cllKHXuK1ItXDgC68AhzXX7amnQNv/rG+zS+ivLs7xpczhXq1Tkcdr02rPGoE0X7HTBwQ==", "dependencies": { "Microsoft.Azure.Functions.Analyzers": "[1.0.0, 2.0.0)", "Microsoft.Azure.WebJobs": "[3.0.23, 3.1.0)", "Microsoft.Azure.WebJobs.Extensions": "3.0.6", "Microsoft.Azure.WebJobs.Extensions.Http": "[3.0.2, 3.1.0)", - "Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator": "1.2.2", + "Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator": "4.0.1", "Newtonsoft.Json": "11.0.2" } }, @@ -238,15 +241,15 @@ }, "Menes.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-preview.5", - "contentHash": "6gOemt+Y+DoIZTrnhlyxurjOpZevjRYyPBgP7UC3tLd28lOOtcBNYQTS8vYWr4+wF40j+0BmM4C1gYhrI3+qIg==", + "resolved": "3.0.0-vnext.4", + "contentHash": "nUerpY8sRmgB9N9Bbyf/qe1hcDyvRPCrhHZpzlgftR4TcFf2S4OG/2Lbfs3UfcFokpG58hYXuWVPwGSNEEkBEQ==", "dependencies": { - "Corvus.ContentHandling": "2.0.4", - "Corvus.Extensions": "1.1.2", - "Corvus.Extensions.Newtonsoft.Json": "2.0.2", - "Corvus.Monitoring.Instrumentation.Abstractions": "1.2.0", + "Corvus.ContentHandling": "2.0.8", + "Corvus.Extensions": "1.1.3", + "Corvus.Extensions.Newtonsoft.Json": "2.0.4", + "Corvus.Monitoring.Instrumentation.Abstractions": "1.3.0", "Microsoft.CSharp": "4.7.0", - "Microsoft.Extensions.Logging": "3.1.15", + "Microsoft.Extensions.Logging": "3.1.16", "Microsoft.OpenApi.Readers": "1.2.3", "System.Interactive": "4.1.1", "System.Text.Encodings.Web": "4.7.2", @@ -255,24 +258,24 @@ }, "Menes.Hosting": { "type": "Transitive", - "resolved": "3.0.0-preview.5", - "contentHash": "ul2Jljp/5RTBnKKjPUSLP4XJMF72jCDw0w5ra/0gVTrQ+kFOKUoxshE4MEGqXhENFzZLsYVUUbvGVNWUN7F1ew==", + "resolved": "3.0.0-vnext.4", + "contentHash": "WactTL+8zqUA1j94FEWFxtaaFIHutJk93/XaGh0qT1aXQiHVH7w6dlvyHhZNcOkoLxMC29kjtFQP7XT7yuRXug==", "dependencies": { - "Menes.Abstractions": "3.0.0-preview.5" + "Menes.Abstractions": "3.0.0-vnext.4" } }, "Menes.Hosting.AspNetCore": { "type": "Transitive", - "resolved": "3.0.0-preview.5", - "contentHash": "+DJ5ggmxjsUsy0UkJDgM7YJeGDdnXQL1RCzYEDCdbDaTOfj7Rp1b0RE7bI3Z9bhphURJtY5fd/tuWQVZ5UNf3g==", + "resolved": "3.0.0-vnext.4", + "contentHash": "QXmIh1CiafSaaxC9iEH81P3xngxeYk5Sd7v6aXa0hixUnJBFWbPa7MFJYFnhoiYF82t92aWsaIGfhTJEalvoVQ==", "dependencies": { - "Menes.Hosting": "3.0.0-preview.5" + "Menes.Hosting": "3.0.0-vnext.4" } }, "Microsoft.ApplicationInsights": { "type": "Transitive", - "resolved": "2.18.0", - "contentHash": "milJB3VOCoC4EWmpE/Co9cOJ7SV6Ji6VqV4Rf5UlqL9QCg+rAX1y+3Y+j1Gu/j4IExYiPq7SEKqkP2BFnEu6Vw==", + "resolved": "2.19.0", + "contentHash": "QMs/5PVRyVv5T5G+UCtCCzSXjVR3WdcgeZqNhwtHCE+5k9S6mc+8pRE5WpsUsjgqwgNYES82bfQ6PsSu4YVPAA==", "dependencies": { "System.Diagnostics.DiagnosticSource": "5.0.0" } @@ -385,11 +388,11 @@ }, "Microsoft.AspNetCore.JsonPatch": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "o9BB9hftnCsyJalz9IT0DUFxz8Xvgh3TOfGWolpuf19duxB4FySq7c25XDYBmBMS+sun5/PsEUAi58ra4iJAoA==", + "resolved": "6.0.0", + "contentHash": "SUiwg0XQ5NtmnELHXSdX4mAwawFnAOwSx2Zz6NIhQnEN1tZDoAWEHc8dS/S7y8cE52+9bHj+XbYZuLGF7OrQPA==", "dependencies": { - "Microsoft.CSharp": "4.5.0", - "Newtonsoft.Json": "11.0.2" + "Microsoft.CSharp": "4.7.0", + "Newtonsoft.Json": "13.0.1" } }, "Microsoft.AspNetCore.Mvc.Abstractions": { @@ -545,8 +548,8 @@ }, "Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator": { "type": "Transitive", - "resolved": "1.2.2", - "contentHash": "vpiNt3JM1pt/WrDIkg7G2DHhIpI4t5I+R9rmXCxIGiby5oPGEolyfiYZdEf2kMMN3SbWzVAbk4Q3jKgFhO9MaQ==", + "resolved": "4.0.1", + "contentHash": "o1E0hetLv8Ix0teA1hGH9D136RGSs24Njm5+a4FKzJHLlxfclvmOxmcg87vcr6LIszKzenNKd1oJGnOwg2WMnw==", "dependencies": { "System.Runtime.Loader": "4.3.0" } @@ -610,26 +613,27 @@ }, "Microsoft.Extensions.Configuration": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "iFO6wyyv/mBr6v9wBJXG+i4baN1GOUf2ClwJilWSSE8CnWgEV2T7w4sTRmE73iS3tdHBiMMnQ2Ynyw8X78ayVw==", + "resolved": "6.0.0", + "contentHash": "tq2wXyh3fL17EMF2bXgRhU7JrbO3on93MRKYxzz4JzzvuGSA1l0W3GI9/tl8EO89TH+KWEymP7bcFway6z9fXg==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "3Ef65E9wCkGJVPQZ7S7GtDJ8JXpCQ3c2b83XLIOINoVV7GSEjKyW/vycc3jQfdc5BIf/lnjodkDiKnjdTzXAZA==", + "resolved": "6.0.0", + "contentHash": "qWzV9o+ZRWq+pGm+1dF+R7qTgTYoXvbyowRoBxQJGfqTpqDun2eteerjRQhq5PQ/14S+lqto3Ft4gYaRyl4rdQ==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.Binder": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "gMI0aMhlJzOvqhREbENDufDaSwnxBs6COgEz+owrfFcb1J2yvBZqhN9YIayHn03JMvm8xtSmNzNL/ZCm7TWjsw==", + "resolved": "6.0.0", + "contentHash": "b3ErKzND8LIC7o08QAVlKfaEIYEvLJbtmVbFZVBRXeu9YkKfSSzLZfR1SUfQPBIy9mKLhEtJgGYImkcMNaKE0A==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Configuration.EnvironmentVariables": { @@ -661,16 +665,17 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "js24vxT9kzGfH7nc/EL9Yi2s5jQilFTxIYHIpX/oIEINVRW4qlnQXsfzsbXE5Y0BAG5TTidnfZ+IyOEsW9XTVA==", + "resolved": "6.0.0", + "contentHash": "k6PWQMuoBDGGHOQTtyois2u4AwyVcIwL2LaSLlTZQm2CYcJ1pxbt6jfAnpWmzENA/wfrYRI/X9DTLoUkE4AsLw==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "PWfBWk54+UcMYA/DqD0l/HSOlbnclR4kp6rYgI28s5zPZ8tIMetKa9+jk+cialrSbvz/+xs/JrXqy7VDiy/0dQ==" + "resolved": "6.0.0", + "contentHash": "xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg==" }, "Microsoft.Extensions.DependencyModel": { "type": "Transitive", @@ -731,27 +736,34 @@ }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "5D0RMBkH4eliNeR2a3VFV4stIer/CsFTeAGo2Uv1dm2X9Ttz8n0lbc7gl8+NogTiKfGm1RqoLF0HtH/1V4wxmw==", + "resolved": "6.0.0", + "contentHash": "eIbyj40QDg1NDz0HBW0S5f3wrLVnKWnDJ/JtZ+yJDFnDj90VoPuoPmFkeaXrtu+0cKm5GRAwoDf+dBWXK0TUdg==", "dependencies": { - "Microsoft.Extensions.Configuration.Binder": "3.1.21", - "Microsoft.Extensions.DependencyInjection": "3.1.21", - "Microsoft.Extensions.Logging.Abstractions": "3.1.21", - "Microsoft.Extensions.Options": "3.1.21" + "Microsoft.Extensions.DependencyInjection": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "System.Diagnostics.DiagnosticSource": "6.0.0" } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "FTEjNPyjJ4eXp+dAP8YfH/MRk0LAKXhQ6FHOX9Wju7AB0/huyjG7NQGWFrnDmviPyCMzR1ZitjT/Zv27JfEsEw==" + "resolved": "6.0.0", + "contentHash": "/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==" }, "Microsoft.Extensions.Logging.Configuration": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "E2rKFPOPAiDdPszCN0VWOpRoqZ0gBfIXkX5K9l93ZgK4z7RyqYDD/gqpF33bc0OZTjGovgItrZ/zHawazplMrA==", + "resolved": "6.0.0", + "contentHash": "ZDskjagmBAbv+K8rYW9VhjPplhbOE63xUD0DiuydZJwt15dRyoqicYklLd86zzeintUc7AptDkHn+YhhYkYo8A==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.21", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.Binder": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "6.0.0" } }, "Microsoft.Extensions.ObjectPool": { @@ -761,28 +773,32 @@ }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "lLI84rWombp1a6RF8VKBP9Iu4AYif5GqyxDYrkwvnMt1hagwRyJQpm6EiamFRyQYdGpEpTZNblUygYY7dEn9xg==", + "resolved": "6.0.0", + "contentHash": "dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Options.ConfigurationExtensions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "8SXTqWPYOYdM0O51/cB7wzVsqFemCGMbcHb82Ix5bmsHO8stcb7YKXERiQ18JSigVogb828gCTK8gMfiSGO4ug==", + "resolved": "6.0.0", + "contentHash": "bXWINbTn0vC0FYc9GaQTISbxhQLAMrvtbuvD9N6JelEaIS/Pr62wUCinrq5bf1WRBGczt1v4wDhxFtVFNcMdUQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", - "Microsoft.Extensions.Configuration.Binder": "3.1.21", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", - "Microsoft.Extensions.Options": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.Binder": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" + "resolved": "6.0.0", + "contentHash": "9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "Microsoft.Identity.Client": { "type": "Transitive", @@ -912,8 +928,8 @@ }, "Newtonsoft.Json": { "type": "Transitive", - "resolved": "11.0.2", - "contentHash": "IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==" + "resolved": "13.0.1", + "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" }, "Newtonsoft.Json.Bson": { "type": "Transitive", @@ -1113,8 +1129,11 @@ }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "tCQTzPsGZh/A9LhhA6zrqCRV4hOHsK90/G7q3Khxmn6tnB1PuNU0cRaKANP2AWcF9bn0zsuOoZOSrHuJk6oNBA==" + "resolved": "6.0.0", + "contentHash": "frQDfv0rl209cKm1lnwTgFPzNigy2EKk1BS3uAvHvlBVKe5cymGyHO+Sj+NLv5VF/AhHsqPIUUwya5oV4CHMUw==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "System.Diagnostics.Tools": { "type": "Transitive", @@ -1469,10 +1488,7 @@ "System.Reflection.Metadata": { "type": "Transitive", "resolved": "5.0.0", - "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==", - "dependencies": { - "System.Collections.Immutable": "5.0.0" - } + "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" }, "System.Reflection.Primitives": { "type": "Transitive", @@ -1516,8 +1532,8 @@ }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==" + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" }, "System.Runtime.Extensions": { "type": "Transitive", @@ -1768,13 +1784,20 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "4.7.2", - "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" + "resolved": "6.0.0", + "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "System.Text.Json": { "type": "Transitive", - "resolved": "4.6.0", - "contentHash": "4F8Xe+JIkVoDJ8hDAZ7HqLkjctN/6WItJIzQaifBwClC7wmoLSda/Sv2i6i1kycqDb3hWF4JCVbpAweyOKHEUA==" + "resolved": "6.0.0", + "contentHash": "zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "6.0.0" + } }, "System.Text.RegularExpressions": { "type": "Transitive", @@ -1885,26 +1908,25 @@ "type": "Project", "dependencies": { "Marain.Tenancy.OpenApi.Service": "1.0.0", - "Menes.Hosting.AspNetCore": "3.0.0-preview.5" + "Menes.Hosting.AspNetCore": "3.0.0-vnext.4" } }, "marain.tenancy.openapi.service": { "type": "Project", "dependencies": { "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", - "Menes.Abstractions": "2.0.1", - "Microsoft.ApplicationInsights": "2.18.0", - "Microsoft.AspNetCore.JsonPatch": "2.2.0", - "Microsoft.Extensions.Configuration.Abstractions": "3.1.0", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.0", - "Newtonsoft.Json": "11.0.2" + "Menes.Abstractions": "3.0.0-vnext.4", + "Microsoft.ApplicationInsights": "2.19.0", + "Microsoft.AspNetCore.JsonPatch": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "6.0.0" } }, "marain.tenancy.storage.azure.blobstorage": { "type": "Project", "dependencies": { "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-alpha.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0" } } } diff --git a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj index 31cc51d8..9db70673 100644 --- a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj +++ b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj @@ -2,7 +2,8 @@ - netcoreapp3.1 + net6.0 + enable @@ -17,7 +18,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyServiceCollectionExtensions.cs b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyServiceCollectionExtensions.cs index 43826850..8d49f623 100644 --- a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyServiceCollectionExtensions.cs +++ b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Microsoft/Extensions/DependencyInjection/TenancyServiceCollectionExtensions.cs @@ -14,6 +14,7 @@ namespace Microsoft.Extensions.DependencyInjection using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using Newtonsoft.Json.Converters; + using Newtonsoft.Json.Serialization; /// /// Extension methods for configuring DI for the Operations Open API services. @@ -29,7 +30,7 @@ public static class TenancyServiceCollectionExtensions [Obsolete("Use AddTenancyApiWithOpenApiActionResultHosting, or consider changing to AddTenancyApiWithAspNetPipelineHosting")] public static IServiceCollection AddTenancyApi( this IServiceCollection services, - Action configureHost = null) + Action? configureHost = null) { return AddTenancyApiWithOpenApiActionResultHosting(services, configureHost); } @@ -42,7 +43,7 @@ public static IServiceCollection AddTenancyApi( /// The service collection, to enable chaining. public static IServiceCollection AddTenancyApiWithAspNetPipelineHosting( this IServiceCollection services, - Action configureHost = null) + Action? configureHost = null) { if (services.Any(s => typeof(TenancyService).IsAssignableFrom(s.ServiceType))) { @@ -68,7 +69,7 @@ public static IServiceCollection AddTenancyApiWithAspNetPipelineHosting( /// The service collection, to enable chaining. public static IServiceCollection AddTenancyApiWithOpenApiActionResultHosting( this IServiceCollection services, - Action configureHost = null) + Action? configureHost = null) { if (services.Any(s => typeof(TenancyService).IsAssignableFrom(s.ServiceType))) { @@ -103,7 +104,7 @@ private static void AddEverythingExceptHosting(this IServiceCollection services) services.AddJsonNetPropertyBag(); services.AddJsonNetCultureInfoConverter(); services.AddJsonNetDateTimeOffsetToIso8601AndUnixTimeConverter(); - services.AddSingleton(new StringEnumConverter(true)); + services.AddSingleton(new StringEnumConverter(new CamelCaseNamingStrategy())); // Add caching config. services.AddSingleton( diff --git a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj index b624a50a..fbda2873 100644 --- a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj +++ b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj @@ -2,7 +2,7 @@ - netcoreapp3.1 + net6.0 enable @@ -30,11 +30,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + + + + + diff --git a/Solutions/Marain.Tenancy.OpenApi.Service/Marain/Tenancy/OpenApi/TenancyService.cs b/Solutions/Marain.Tenancy.OpenApi.Service/Marain/Tenancy/OpenApi/TenancyService.cs index 0c694222..5d9932ff 100644 --- a/Solutions/Marain.Tenancy.OpenApi.Service/Marain/Tenancy/OpenApi/TenancyService.cs +++ b/Solutions/Marain.Tenancy.OpenApi.Service/Marain/Tenancy/OpenApi/TenancyService.cs @@ -335,7 +335,7 @@ public async Task UpdateTenantAsync( { if (operation.path.StartsWith("/properties/")) { - string propertyName = operation.path.Substring(12); + string propertyName = operation.path[12..]; switch (operation.OperationType) { case OperationType.Add: @@ -404,13 +404,17 @@ public async Task DeleteChildTenantAsync( if (childTenantId.GetParentId() != tenantId) { - this.logger.LogError($"The discovered parent tenant ID {childTenantId.GetParentId()} of the child {childTenantId} does not match the specified parent {tenantId}"); + this.logger.LogError( + "The discovered parent tenant ID {discoveredParentTenantId} of the child {childTenantId} does not match the specified parent {specifiedParentTenantId}", + childTenantId.GetParentId(), + childTenantId, + tenantId); throw new OpenApiNotFoundException(); } try { - this.logger.LogInformation($"Attempting to delete {childTenantId}"); + this.logger.LogInformation("Attempting to delete {childTenantId}", childTenantId); await this.tenantStore.DeleteTenantAsync(childTenantId).ConfigureAwait(false); return this.OkResult(); } diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/FunctionBindings.cs b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/FunctionBindings.cs index df876387..c30b736c 100644 --- a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/FunctionBindings.cs +++ b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/FunctionBindings.cs @@ -24,7 +24,7 @@ public static class FunctionBindings { public const int TenancyApiPort = 7071; - public static readonly Uri TenancyApiBaseUri = new Uri($"http://localhost:{TenancyApiPort}"); + public static readonly Uri TenancyApiBaseUri = new ($"http://localhost:{TenancyApiPort}"); /// /// Runs the public API function. @@ -45,7 +45,7 @@ public static Task RunPublicApiFunction(FeatureContext featureContext) return functionsController.StartFunctionsInstance( "Marain.Tenancy.Host.Functions", TenancyApiPort, - "netcoreapp3.1", + "net6.0", "csharp", functionsConfig); } diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyClientBindings.cs b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyClientBindings.cs index 0baf7148..239ede40 100644 --- a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyClientBindings.cs +++ b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TenancyClientBindings.cs @@ -12,6 +12,8 @@ namespace Marain.Tenancy.Specs.Integration.Bindings using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Converters; + using Newtonsoft.Json.Serialization; + using TechTalk.SpecFlow; /// @@ -46,7 +48,7 @@ public static void SetupFeature(FeatureContext featureContext) serviceCollection.AddJsonNetPropertyBag(); serviceCollection.AddJsonNetCultureInfoConverter(); serviceCollection.AddJsonNetDateTimeOffsetToIso8601AndUnixTimeConverter(); - serviceCollection.AddSingleton(new StringEnumConverter(true)); + serviceCollection.AddSingleton(new StringEnumConverter(new CamelCaseNamingStrategy())); serviceCollection.AddSingleton(sp => sp.GetRequiredService().Get()); diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TestTenantCleanup.cs b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TestTenantCleanup.cs index e534f281..98b500b5 100644 --- a/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TestTenantCleanup.cs +++ b/Solutions/Marain.Tenancy.Specs/Integration/Bindings/TestTenantCleanup.cs @@ -15,9 +15,8 @@ namespace Marain.Tenancy.Specs.Integration.Bindings [Binding] public class TestTenantCleanup { - private static readonly HttpClient HttpClient = new HttpClient(); + private static readonly HttpClient HttpClient = new (); private readonly HashSet<(string ParentId, string TenantId)> tenantsToDelete = new(); - private readonly HashSet<(string ParentId, string TenantId)> wellKnownTenantsToDelete = new(); public void AddTenantToDelete(string parentId, string id) { diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Steps/JsonSteps.cs b/Solutions/Marain.Tenancy.Specs/Integration/Steps/JsonSteps.cs index 25c28d30..6c5170c9 100644 --- a/Solutions/Marain.Tenancy.Specs/Integration/Steps/JsonSteps.cs +++ b/Solutions/Marain.Tenancy.Specs/Integration/Steps/JsonSteps.cs @@ -24,7 +24,7 @@ public void ThenTheResponseObjectShouldHaveAStringPropertyCalledWithValue(string { JToken actualToken = this.GetRequiredTokenFromResponseObject(propertyPath); - string actualValue = actualToken.Value(); + string? actualValue = actualToken.Value(); Assert.AreEqual(expectedValue, actualValue, $"Expected value of property '{propertyPath}' was '{expectedValue}', but actual value was '{actualValue}'"); } @@ -59,7 +59,7 @@ public void ThenTheResponseObjectShouldHaveALongPropertyCalledWithValue(string p public void ThenTheResponseObjectShouldNotHaveAPropertyCalled(string propertyPath) { JObject data = this.ScenarioContext.Get(); - JToken token = data.SelectToken(propertyPath); + JToken? token = data.SelectToken(propertyPath); Assert.IsNull(token, $"Expected not to find a property with path '{propertyPath}', but one was present."); } @@ -86,7 +86,7 @@ public void ThenEachItemInTheResponseContentArrayPropertyCalledShouldHaveAProper public void GivenIHaveStoredTheValueOfTheResponseObjectPropertyCalledAs(string propertyPath, string storeAsName) { JToken token = this.GetRequiredTokenFromResponseObject(propertyPath); - string valueAsString = token.Value(); + string? valueAsString = token.Value(); this.ScenarioContext.Set(valueAsString, storeAsName); } @@ -109,9 +109,9 @@ public JToken GetRequiredTokenFromResponseObject(string propertyPath) public static JToken GetRequiredToken(JToken data, string propertyPath) { - JToken token = data.SelectToken(propertyPath); + JToken? token = data.SelectToken(propertyPath); Assert.IsNotNull(token, $"Could not locate a property with path '{propertyPath}' under the token with path '{data.Path}'"); - return token; + return token!; } } } diff --git a/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyApiSteps.cs b/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyApiSteps.cs index c5233cee..4e1d4049 100644 --- a/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyApiSteps.cs +++ b/Solutions/Marain.Tenancy.Specs/Integration/Steps/TenancyApiSteps.cs @@ -28,7 +28,7 @@ namespace Marain.Tenancy.Specs.Integration.Steps [Binding] public class TenancyApiSteps : Steps { - private static readonly HttpClient HttpClient = new HttpClient(); + private static readonly HttpClient HttpClient = new (); private readonly TestTenantCleanup testTenantCleanup; private HttpResponseMessage? response; private string? responseContent; @@ -55,13 +55,15 @@ public Task WhenIRequestTheTenantWithIdFromTheAPI(string tenantId) [When("I request the tenant using the Location from the previous response")] public Task WhenIRequestTheTenantUsingTheLocationFromThePreviousResponse() { - return this.SendGetRequest(FunctionBindings.TenancyApiBaseUri, this.Response.Headers.Location.ToString()); + return this.SendGetRequest( + FunctionBindings.TenancyApiBaseUri, + (this.Response.Headers.Location ?? throw new InvalidOperationException("Location header unavailable")).ToString()); } [Given("I store the value of the response Location header as '(.*)'")] public void GivenIStoreTheValueOfTheResponseLocationHeaderAs(string name) { - this.ScenarioContext.Set(this.Response.Headers.Location.ToString(), name); + this.ScenarioContext.Set(this.Response.Headers.Location?.ToString(), name); } [Given("I have requested the tenant using the path called '(.*)'")] @@ -76,7 +78,10 @@ public Task WhenIRequestTheTenantUsingThePathCalledAndTheEtagFromThePreviousResp { string path = this.ScenarioContext.Get(name); - return this.SendGetRequest(FunctionBindings.TenancyApiBaseUri, path, this.Response.Headers.ETag.Tag); + return this.SendGetRequest( + FunctionBindings.TenancyApiBaseUri, + path, + (this.Response.Headers.ETag ?? throw new InvalidOperationException("ETag not available from previous response")).Tag); } [Given("I have used the API to create a new tenant")] @@ -86,7 +91,7 @@ public async Task WhenIUseTheAPIToCreateANewTenant(Table table) string parentId = table.Rows[0]["ParentTenantId"]; string name = table.Rows[0]["Name"]; - await this.SendPostRequest(FunctionBindings.TenancyApiBaseUri, $"/{parentId}/marain/tenant/children?tenantName={Uri.EscapeUriString(name)}", null); + await this.SendPostRequest(FunctionBindings.TenancyApiBaseUri, $"/{parentId}/marain/tenant/children?tenantName={Uri.EscapeDataString(name)}", null); if (this.Response.IsSuccessStatusCode && this.Response.Headers.Location is not null) { string location = this.Response.Headers.Location.ToString(); @@ -137,9 +142,9 @@ private async Task SendGetRequest(Uri baseUri, string path, string? etag = null) } this.response = await HttpClient.SendAsync(request).ConfigureAwait(false); - this.responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + this.responseContent = await this.response.Content.ReadAsStringAsync().ConfigureAwait(false); - if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(this.responseContent)) + if (this.response.IsSuccessStatusCode && !string.IsNullOrEmpty(this.responseContent)) { var parsedResponse = JObject.Parse(this.responseContent); this.ScenarioContext.Set(parsedResponse); @@ -150,7 +155,7 @@ private async Task SendPostRequest(Uri baseUri, string path, object? data) { HttpContent? content = null; - if (!(data is null)) + if (data is not null) { IServiceProvider serviceProvider = ContainerBindings.GetServiceProvider(this.FeatureContext); IJsonSerializerSettingsProvider serializerSettingsProvider = serviceProvider.GetRequiredService(); @@ -159,7 +164,7 @@ private async Task SendPostRequest(Uri baseUri, string path, object? data) } this.response = await HttpClient.PostAsync(new Uri(baseUri, path), content).ConfigureAwait(false); - this.responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + this.responseContent = await this.response.Content.ReadAsStringAsync().ConfigureAwait(false); } } } diff --git a/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.csproj b/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.csproj index 9cf40e5a..b1f85357 100644 --- a/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.csproj +++ b/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.csproj @@ -2,7 +2,7 @@ - netcoreapp3.1 + net6.0 latest false Marain.Tenancy.Specs @@ -42,9 +42,9 @@ - - - + + + diff --git a/Solutions/Marain.Tenancy.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Specs/packages.lock.json index f76f21b9..17cfb427 100644 --- a/Solutions/Marain.Tenancy.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Specs/packages.lock.json @@ -1,7 +1,7 @@ { "version": 1, "dependencies": { - ".NETCoreApp,Version=v3.1": { + "net6.0": { "Corvus.Testing.AzureFunctions.SpecFlow.NUnit": { "type": "Direct", "requested": "[1.4.6, )", @@ -17,30 +17,35 @@ }, "Microsoft.Extensions.Configuration": { "type": "Direct", - "requested": "[3.1.*, )", - "resolved": "3.1.21", - "contentHash": "iFO6wyyv/mBr6v9wBJXG+i4baN1GOUf2ClwJilWSSE8CnWgEV2T7w4sTRmE73iS3tdHBiMMnQ2Ynyw8X78ayVw==", + "requested": "[6.0.*, )", + "resolved": "6.0.0", + "contentHash": "tq2wXyh3fL17EMF2bXgRhU7JrbO3on93MRKYxzz4JzzvuGSA1l0W3GI9/tl8EO89TH+KWEymP7bcFway6z9fXg==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.EnvironmentVariables": { "type": "Direct", - "requested": "[3.1.*, )", - "resolved": "3.1.21", - "contentHash": "4nMwSpAIANpzegZxT05jO2IM30kdRtHSfJOBXI3V8fVXlhxsXBj5EEQGSOnSzzEaeBzHkjQFF4dxDHIgMuYwmQ==", + "requested": "[6.0.*, )", + "resolved": "6.0.0", + "contentHash": "DjYkzqvhiHCq38LW71PcIxXk6nhtV6VySP9yDcSO0goPl7YCU1VG1f2Wbgy58lkA10pWkjHCblZPUyboCB93ZA==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Configuration.Json": { "type": "Direct", - "requested": "[3.1.*, )", - "resolved": "3.1.21", - "contentHash": "JATr/lcsjJM8R9hyylxWzR+fxteAf0xv2SBD5tpLj1qPVauuuwcgKe3swfMK/TyfP/tVHNeuLVlfBlcl6ZIhjQ==", + "requested": "[6.0.*, )", + "resolved": "6.0.0", + "contentHash": "GJGery6QytCzS/BxJ96klgG9in3uH26KcUBbiVG/coNDXCRq6LGVVlUT4vXq34KPuM+R2av+LeYdX9h4IZOCUg==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21", - "Microsoft.Extensions.Configuration.FileExtensions": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.FileExtensions": "6.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "System.Text.Json": "6.0.0" } }, "Azure.Core": { @@ -197,10 +202,10 @@ }, "Corvus.Monitoring.Instrumentation.Abstractions": { "type": "Transitive", - "resolved": "1.2.0", - "contentHash": "dXBsCEnAlpkiky2b620wRhCpXnlPaCKRsQLV3E+MJKhQh/XYD5tNEbfPkpSOPL7P3U7HCQwbNYzsJgvIbwTlwA==", + "resolved": "1.3.0", + "contentHash": "fhULZvrr4d6imDMzohP1t2QPEZ5jRyNDIwMX2kQySSECSLn27Hf83FaRKStMD5PoZjc5QLLtpnrTsLRu8WHxeA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.11" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.16" } }, "Corvus.Tenancy.Abstractions": { @@ -275,15 +280,15 @@ }, "Menes.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-preview.5", - "contentHash": "6gOemt+Y+DoIZTrnhlyxurjOpZevjRYyPBgP7UC3tLd28lOOtcBNYQTS8vYWr4+wF40j+0BmM4C1gYhrI3+qIg==", + "resolved": "3.0.0-vnext.4", + "contentHash": "nUerpY8sRmgB9N9Bbyf/qe1hcDyvRPCrhHZpzlgftR4TcFf2S4OG/2Lbfs3UfcFokpG58hYXuWVPwGSNEEkBEQ==", "dependencies": { - "Corvus.ContentHandling": "2.0.4", - "Corvus.Extensions": "1.1.2", - "Corvus.Extensions.Newtonsoft.Json": "2.0.2", - "Corvus.Monitoring.Instrumentation.Abstractions": "1.2.0", + "Corvus.ContentHandling": "2.0.8", + "Corvus.Extensions": "1.1.3", + "Corvus.Extensions.Newtonsoft.Json": "2.0.4", + "Corvus.Monitoring.Instrumentation.Abstractions": "1.3.0", "Microsoft.CSharp": "4.7.0", - "Microsoft.Extensions.Logging": "3.1.15", + "Microsoft.Extensions.Logging": "3.1.16", "Microsoft.OpenApi.Readers": "1.2.3", "System.Interactive": "4.1.1", "System.Text.Encodings.Web": "4.7.2", @@ -292,24 +297,24 @@ }, "Menes.Hosting": { "type": "Transitive", - "resolved": "3.0.0-preview.5", - "contentHash": "ul2Jljp/5RTBnKKjPUSLP4XJMF72jCDw0w5ra/0gVTrQ+kFOKUoxshE4MEGqXhENFzZLsYVUUbvGVNWUN7F1ew==", + "resolved": "3.0.0-vnext.4", + "contentHash": "WactTL+8zqUA1j94FEWFxtaaFIHutJk93/XaGh0qT1aXQiHVH7w6dlvyHhZNcOkoLxMC29kjtFQP7XT7yuRXug==", "dependencies": { - "Menes.Abstractions": "3.0.0-preview.5" + "Menes.Abstractions": "3.0.0-vnext.4" } }, "Menes.Hosting.AspNetCore": { "type": "Transitive", - "resolved": "3.0.0-preview.5", - "contentHash": "+DJ5ggmxjsUsy0UkJDgM7YJeGDdnXQL1RCzYEDCdbDaTOfj7Rp1b0RE7bI3Z9bhphURJtY5fd/tuWQVZ5UNf3g==", + "resolved": "3.0.0-vnext.4", + "contentHash": "QXmIh1CiafSaaxC9iEH81P3xngxeYk5Sd7v6aXa0hixUnJBFWbPa7MFJYFnhoiYF82t92aWsaIGfhTJEalvoVQ==", "dependencies": { - "Menes.Hosting": "3.0.0-preview.5" + "Menes.Hosting": "3.0.0-vnext.4" } }, "Microsoft.ApplicationInsights": { "type": "Transitive", - "resolved": "2.18.0", - "contentHash": "milJB3VOCoC4EWmpE/Co9cOJ7SV6Ji6VqV4Rf5UlqL9QCg+rAX1y+3Y+j1Gu/j4IExYiPq7SEKqkP2BFnEu6Vw==", + "resolved": "2.19.0", + "contentHash": "QMs/5PVRyVv5T5G+UCtCCzSXjVR3WdcgeZqNhwtHCE+5k9S6mc+8pRE5WpsUsjgqwgNYES82bfQ6PsSu4YVPAA==", "dependencies": { "System.Diagnostics.DiagnosticSource": "5.0.0" } @@ -325,11 +330,11 @@ }, "Microsoft.AspNetCore.JsonPatch": { "type": "Transitive", - "resolved": "2.2.0", - "contentHash": "o9BB9hftnCsyJalz9IT0DUFxz8Xvgh3TOfGWolpuf19duxB4FySq7c25XDYBmBMS+sun5/PsEUAi58ra4iJAoA==", + "resolved": "6.0.0", + "contentHash": "SUiwg0XQ5NtmnELHXSdX4mAwawFnAOwSx2Zz6NIhQnEN1tZDoAWEHc8dS/S7y8cE52+9bHj+XbYZuLGF7OrQPA==", "dependencies": { - "Microsoft.CSharp": "4.5.0", - "Newtonsoft.Json": "11.0.2" + "Microsoft.CSharp": "4.7.0", + "Newtonsoft.Json": "13.0.1" } }, "Microsoft.AspNetCore.WebUtilities": { @@ -433,27 +438,30 @@ }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "3Ef65E9wCkGJVPQZ7S7GtDJ8JXpCQ3c2b83XLIOINoVV7GSEjKyW/vycc3jQfdc5BIf/lnjodkDiKnjdTzXAZA==", + "resolved": "6.0.0", + "contentHash": "qWzV9o+ZRWq+pGm+1dF+R7qTgTYoXvbyowRoBxQJGfqTpqDun2eteerjRQhq5PQ/14S+lqto3Ft4gYaRyl4rdQ==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.Binder": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "gMI0aMhlJzOvqhREbENDufDaSwnxBs6COgEz+owrfFcb1J2yvBZqhN9YIayHn03JMvm8xtSmNzNL/ZCm7TWjsw==", + "resolved": "6.0.0", + "contentHash": "b3ErKzND8LIC7o08QAVlKfaEIYEvLJbtmVbFZVBRXeu9YkKfSSzLZfR1SUfQPBIy9mKLhEtJgGYImkcMNaKE0A==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Configuration.FileExtensions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "uAucC/Vq3/2duacja/sLbMKU9y2RJT9uloFT1xrl3MufDKFRAkSbIakw2Rv61XNqHCcEIHgsUiW/L7Tuz7Uomw==", + "resolved": "6.0.0", + "contentHash": "V4Dth2cYMZpw3HhGw9XUDIijpI6gN+22LDt0AhufIgOppCUfpWX4483OmN+dFXRJkJLc8Tv0Q8QK+1ingT2+KQ==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21", - "Microsoft.Extensions.FileProviders.Physical": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Physical": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.DependencyInjection": { @@ -466,8 +474,8 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "PWfBWk54+UcMYA/DqD0l/HSOlbnclR4kp6rYgI28s5zPZ8tIMetKa9+jk+cialrSbvz/+xs/JrXqy7VDiy/0dQ==" + "resolved": "6.0.0", + "contentHash": "xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg==" }, "Microsoft.Extensions.DependencyModel": { "type": "Transitive", @@ -483,25 +491,26 @@ }, "Microsoft.Extensions.FileProviders.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "52amnz03Px8X7Pw7uI6qrQPUx++Qq7MB5rhjJh+4YRq3NgUls4KqJDvOuGnnS4pRt2T8IbIrgYxRn2wMrW8Xwg==", + "resolved": "6.0.0", + "contentHash": "0pd4/fho0gC12rQswaGQxbU34jOS1TPS8lZPpkFCH68ppQjHNHYle9iRuHeev1LhrJ94YPvzcRd8UmIuFk23Qw==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.FileProviders.Physical": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "w8vwWXVdFPX/hJptNybW6Nv21j3I6vOrztt3gwp0IPts+v56X9tNjR36ivx6CbEpDs2jP2kx8w8YOTYVwIuwgg==", + "resolved": "6.0.0", + "contentHash": "QvkL7l0nM8udt3gfyu0Vw8bbCXblxaKOl7c2oBfgGy4LCURRaL9XWZX1FWJrQc43oMokVneVxH38iz+bY1sbhg==", "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "3.1.21", - "Microsoft.Extensions.FileSystemGlobbing": "3.1.21" + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "Microsoft.Extensions.FileSystemGlobbing": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.FileSystemGlobbing": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "Vao4dtipoDQf6jkfYql9MZWJm1U2gv5Ro4a0sMuE0K8Ze3+yRmSyNTtmZer8GLb99xAGyYa2JhfQlFobt269aA==" + "resolved": "6.0.0", + "contentHash": "ip8jnL1aPiaPeKINCqaTEbvBFDmVx9dXQEBZ2HOBRXPD1eabGNqP/bKlsIcp7U2lGxiXd5xIhoFcmY8nM4Hdiw==" }, "Microsoft.Extensions.Logging": { "type": "Transitive", @@ -540,28 +549,32 @@ }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "lLI84rWombp1a6RF8VKBP9Iu4AYif5GqyxDYrkwvnMt1hagwRyJQpm6EiamFRyQYdGpEpTZNblUygYY7dEn9xg==", + "resolved": "6.0.0", + "contentHash": "dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Options.ConfigurationExtensions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "8SXTqWPYOYdM0O51/cB7wzVsqFemCGMbcHb82Ix5bmsHO8stcb7YKXERiQ18JSigVogb828gCTK8gMfiSGO4ug==", + "resolved": "6.0.0", + "contentHash": "bXWINbTn0vC0FYc9GaQTISbxhQLAMrvtbuvD9N6JelEaIS/Pr62wUCinrq5bf1WRBGczt1v4wDhxFtVFNcMdUQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", - "Microsoft.Extensions.Configuration.Binder": "3.1.21", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", - "Microsoft.Extensions.Options": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.Binder": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" + "resolved": "6.0.0", + "contentHash": "9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "Microsoft.Identity.Client": { "type": "Transitive", @@ -683,8 +696,8 @@ }, "Newtonsoft.Json": { "type": "Transitive", - "resolved": "11.0.2", - "contentHash": "IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==" + "resolved": "13.0.1", + "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" }, "Newtonsoft.Json.Bson": { "type": "Transitive", @@ -1402,10 +1415,7 @@ "System.Reflection.Metadata": { "type": "Transitive", "resolved": "5.0.0", - "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==", - "dependencies": { - "System.Collections.Immutable": "5.0.0" - } + "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" }, "System.Reflection.Primitives": { "type": "Transitive", @@ -1449,8 +1459,8 @@ }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==" + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" }, "System.Runtime.Extensions": { "type": "Transitive", @@ -1723,13 +1733,20 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "4.7.2", - "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" + "resolved": "6.0.0", + "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "System.Text.Json": { "type": "Transitive", - "resolved": "4.6.0", - "contentHash": "4F8Xe+JIkVoDJ8hDAZ7HqLkjctN/6WItJIzQaifBwClC7wmoLSda/Sv2i6i1kycqDb3hWF4JCVbpAweyOKHEUA==" + "resolved": "6.0.0", + "contentHash": "zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "6.0.0" + } }, "System.Text.RegularExpressions": { "type": "Transitive", @@ -1867,7 +1884,7 @@ "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } }, @@ -1883,19 +1900,18 @@ "type": "Project", "dependencies": { "Marain.Tenancy.OpenApi.Service": "1.0.0", - "Menes.Hosting.AspNetCore": "3.0.0-preview.5" + "Menes.Hosting.AspNetCore": "3.0.0-vnext.4" } }, "marain.tenancy.openapi.service": { "type": "Project", "dependencies": { "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", - "Menes.Abstractions": "2.0.1", - "Microsoft.ApplicationInsights": "2.18.0", - "Microsoft.AspNetCore.JsonPatch": "2.2.0", - "Microsoft.Extensions.Configuration.Abstractions": "3.1.0", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.0", - "Newtonsoft.Json": "11.0.2" + "Menes.Abstractions": "3.0.0-vnext.4", + "Microsoft.ApplicationInsights": "2.19.0", + "Microsoft.AspNetCore.JsonPatch": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "6.0.0" } } } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs index 5c4d0bfe..d438f095 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs @@ -29,6 +29,7 @@ namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings internal class TenancyContainerSetupDirectToStorage : ITenancyContainerSetup { + private static readonly Lazy Sha1 = new (() => SHA1.Create()); private readonly BlobContainerConfiguration configuration; private readonly IBlobContainerSourceByConfiguration blobContainerSource; private readonly IPropertyBagFactory propertyBagFactory; @@ -74,9 +75,7 @@ public async Task EnsureWellKnownChildTenantExistsAsync( "StorageConfiguration__corvustenancy", new LegacyV2BlobStorageConfiguration { - AccountName = this.configuration.ConnectionStringPlainText != null - ? this.configuration.ConnectionStringPlainText - : this.configuration.AccountName, + AccountName = this.configuration.ConnectionStringPlainText ?? this.configuration.AccountName, KeyVaultName = this.configuration.AccessKeyInKeyVault?.VaultName, AccountKeySecretName = this.configuration.AccessKeyInKeyVault?.SecretName, }) @@ -120,8 +119,7 @@ public async Task DeleteTenantAsync(string tenantId, bool leaveContainer) private static string HashAndEncodeBlobContainerName(string containerName) { byte[] byteContents = Encoding.UTF8.GetBytes(containerName); - using SHA1CryptoServiceProvider hash = new (); - byte[] hashedBytes = hash.ComputeHash(byteContents); + byte[] hashedBytes = Sha1.Value.ComputeHash(byteContents); return TenantExtensions.ByteArrayToHexViaLookup32(hashedBytes); } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs index de92ef05..565a6064 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs @@ -19,6 +19,7 @@ namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings internal class TenancyContainerSetupViaApi : ITenancyContainerSetup { + private static readonly Lazy Sha1 = new (() => SHA1.Create()); private readonly BlobContainerConfiguration configuration; // Deferred tenant store fetching - it's important we don't try to use this before @@ -59,9 +60,7 @@ public async Task EnsureWellKnownChildTenantExistsAsync( { var v2Config = new LegacyV2BlobStorageConfiguration { - AccountName = v3Config.ConnectionStringPlainText != null - ? v3Config.ConnectionStringPlainText - : v3Config.AccountName, + AccountName = v3Config.ConnectionStringPlainText ?? v3Config.AccountName, KeyVaultName = v3Config.AccessKeyInKeyVault?.VaultName, AccountKeySecretName = v3Config.AccessKeyInKeyVault?.SecretName, }; @@ -117,8 +116,7 @@ public async Task DeleteTenantAsync(string tenantId, bool leaveContainer) private static string HashAndEncodeBlobContainerName(string containerName) { byte[] byteContents = Encoding.UTF8.GetBytes(containerName); - using SHA1CryptoServiceProvider hash = new (); - byte[] hashedBytes = hash.ComputeHash(byteContents); + byte[] hashedBytes = Sha1.Value.ComputeHash(byteContents); return TenantExtensions.ByteArrayToHexViaLookup32(hashedBytes); } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj index 6932ecfe..ce9a7f1b 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj @@ -3,7 +3,7 @@ - netcoreapp3.1 + net6.0 enable Marain.Tenancy.Storage.Azure.BlobStorage.Specs @@ -44,11 +44,11 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/MultiSetupTestBase.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/MultiSetupTestBase.cs index 9d46d6cf..cc07ef3b 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/MultiSetupTestBase.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/MultiMode/MultiSetupTestBase.cs @@ -77,7 +77,7 @@ private protected MultiSetupTestBase(SetupModes testType) [AttributeUsage(AttributeTargets.Class)] public class MultiSetupTestAttribute : Attribute, IFixtureBuilder2 { - private readonly NUnitTestFixtureBuilder builder = new NUnitTestFixtureBuilder(); + private readonly NUnitTestFixtureBuilder builder = new (); /// public IEnumerable BuildFrom(ITypeInfo typeInfo, IPreFilter filter) @@ -112,7 +112,7 @@ public IEnumerable BuildFrom(ITypeInfo typeInfo) private class NullPrefilter : IPreFilter { - public static readonly NullPrefilter Instance = new NullPrefilter(); + public static readonly NullPrefilter Instance = new (); public bool IsMatch(Type type) => true; diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/EnumerateChildTenantsSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/EnumerateChildTenantsSteps.cs index 470856e4..faaf0963 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/EnumerateChildTenantsSteps.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/EnumerateChildTenantsSteps.cs @@ -20,7 +20,7 @@ namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.StepDefinitions [Binding] public class EnumerateChildTenantsSteps : TenantStepsBase { - private List getChildrenResults = new (); + private readonly List getChildrenResults = new (); public EnumerateChildTenantsSteps(TenantProperties tenantProperties) : base(tenantProperties) diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/local.settings.template.json b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/local.settings.template.json index 08ed9c69..4cd0b18a 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/local.settings.template.json +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/local.settings.template.json @@ -2,15 +2,15 @@ "AzureServicesAuthConnectionString": "RunAs=Developer; DeveloperTool=AzureCLI", "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "dotnet", - "FUNCTIONS_EXTENSION_VERSION": "~2", + "FUNCTIONS_EXTENSION_VERSION": "~4", "APPINSIGHTS_INSTRUMENTATIONKEY": "", "TenantCacheConfiguration:GetTenantResponseCacheControlHeaderValue": "max-age=300", // This... - //"RootBlobStorageConfiguration:ConnectionStringPlainText": "UseDevelopmentStorage=true", + "RootBlobStorageConfiguration:ConnectionStringPlainText": "UseDevelopmentStorage=true", // or this: - "RootBlobStorageConfiguration:AccountName": "", - "RootBlobStorageConfiguration:AccessKeyInKeyVault:VaultName": "", - "RootBlobStorageConfiguration:AccessKeyInKeyVault:SecretName": "" + //"RootBlobStorageConfiguration:AccountName": "", + //"RootBlobStorageConfiguration:AccessKeyInKeyVault:VaultName": "", + //"RootBlobStorageConfiguration:AccessKeyInKeyVault:SecretName": "" } \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json index d5701541..399a74e3 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json @@ -1,7 +1,7 @@ { "version": 1, "dependencies": { - ".NETCoreApp,Version=v3.1": { + "net6.0": { "Corvus.Testing.AzureFunctions.SpecFlow.NUnit": { "type": "Direct", "requested": "[1.4.6, )", @@ -26,48 +26,53 @@ }, "FluentAssertions": { "type": "Direct", - "requested": "[6.1.0, )", - "resolved": "6.1.0", - "contentHash": "JbLis99YvgAuA3Khr9m5WvngBWGEmfYq3u2GxV7ksbOK9x7BCeQUCTjn5LHxrG/qu5XmlfDs4O60xTMvARiKYA==", + "requested": "[6.2.0, )", + "resolved": "6.2.0", + "contentHash": "5YOZLB0Tay1bw+wEYZTAZlPThQ/Yntk1HSPJYluMd5PW/Xg9E8I1mRC03AKRsnuANBR0kYaHq0NX1fg7RgrGNA==", "dependencies": { "System.Configuration.ConfigurationManager": "4.4.0" } }, "Microsoft.Extensions.Configuration": { "type": "Direct", - "requested": "[3.1.*, )", - "resolved": "3.1.21", - "contentHash": "iFO6wyyv/mBr6v9wBJXG+i4baN1GOUf2ClwJilWSSE8CnWgEV2T7w4sTRmE73iS3tdHBiMMnQ2Ynyw8X78ayVw==", + "requested": "[6.0.*, )", + "resolved": "6.0.0", + "contentHash": "tq2wXyh3fL17EMF2bXgRhU7JrbO3on93MRKYxzz4JzzvuGSA1l0W3GI9/tl8EO89TH+KWEymP7bcFway6z9fXg==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.Binder": { "type": "Direct", - "requested": "[3.1.*, )", - "resolved": "3.1.21", - "contentHash": "gMI0aMhlJzOvqhREbENDufDaSwnxBs6COgEz+owrfFcb1J2yvBZqhN9YIayHn03JMvm8xtSmNzNL/ZCm7TWjsw==", + "requested": "[6.0.*, )", + "resolved": "6.0.0", + "contentHash": "b3ErKzND8LIC7o08QAVlKfaEIYEvLJbtmVbFZVBRXeu9YkKfSSzLZfR1SUfQPBIy9mKLhEtJgGYImkcMNaKE0A==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21" + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Configuration.EnvironmentVariables": { "type": "Direct", - "requested": "[3.1.*, )", - "resolved": "3.1.21", - "contentHash": "4nMwSpAIANpzegZxT05jO2IM30kdRtHSfJOBXI3V8fVXlhxsXBj5EEQGSOnSzzEaeBzHkjQFF4dxDHIgMuYwmQ==", + "requested": "[6.0.*, )", + "resolved": "6.0.0", + "contentHash": "DjYkzqvhiHCq38LW71PcIxXk6nhtV6VySP9yDcSO0goPl7YCU1VG1f2Wbgy58lkA10pWkjHCblZPUyboCB93ZA==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0" } }, "Microsoft.Extensions.Configuration.Json": { "type": "Direct", - "requested": "[3.1.*, )", - "resolved": "3.1.21", - "contentHash": "JATr/lcsjJM8R9hyylxWzR+fxteAf0xv2SBD5tpLj1qPVauuuwcgKe3swfMK/TyfP/tVHNeuLVlfBlcl6ZIhjQ==", + "requested": "[6.0.*, )", + "resolved": "6.0.0", + "contentHash": "GJGery6QytCzS/BxJ96klgG9in3uH26KcUBbiVG/coNDXCRq6LGVVlUT4vXq34KPuM+R2av+LeYdX9h4IZOCUg==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21", - "Microsoft.Extensions.Configuration.FileExtensions": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.Configuration.FileExtensions": "6.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "System.Text.Json": "6.0.0" } }, "StyleCop.Analyzers": { @@ -387,19 +392,22 @@ }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "3Ef65E9wCkGJVPQZ7S7GtDJ8JXpCQ3c2b83XLIOINoVV7GSEjKyW/vycc3jQfdc5BIf/lnjodkDiKnjdTzXAZA==", + "resolved": "6.0.0", + "contentHash": "qWzV9o+ZRWq+pGm+1dF+R7qTgTYoXvbyowRoBxQJGfqTpqDun2eteerjRQhq5PQ/14S+lqto3Ft4gYaRyl4rdQ==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.FileExtensions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "uAucC/Vq3/2duacja/sLbMKU9y2RJT9uloFT1xrl3MufDKFRAkSbIakw2Rv61XNqHCcEIHgsUiW/L7Tuz7Uomw==", + "resolved": "6.0.0", + "contentHash": "V4Dth2cYMZpw3HhGw9XUDIijpI6gN+22LDt0AhufIgOppCUfpWX4483OmN+dFXRJkJLc8Tv0Q8QK+1ingT2+KQ==", "dependencies": { - "Microsoft.Extensions.Configuration": "3.1.21", - "Microsoft.Extensions.FileProviders.Physical": "3.1.21" + "Microsoft.Extensions.Configuration": "6.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "Microsoft.Extensions.FileProviders.Physical": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.DependencyInjection": { @@ -412,8 +420,8 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "PWfBWk54+UcMYA/DqD0l/HSOlbnclR4kp6rYgI28s5zPZ8tIMetKa9+jk+cialrSbvz/+xs/JrXqy7VDiy/0dQ==" + "resolved": "6.0.0", + "contentHash": "xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg==" }, "Microsoft.Extensions.DependencyModel": { "type": "Transitive", @@ -429,25 +437,26 @@ }, "Microsoft.Extensions.FileProviders.Abstractions": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "52amnz03Px8X7Pw7uI6qrQPUx++Qq7MB5rhjJh+4YRq3NgUls4KqJDvOuGnnS4pRt2T8IbIrgYxRn2wMrW8Xwg==", + "resolved": "6.0.0", + "contentHash": "0pd4/fho0gC12rQswaGQxbU34jOS1TPS8lZPpkFCH68ppQjHNHYle9iRuHeev1LhrJ94YPvzcRd8UmIuFk23Qw==", "dependencies": { - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.FileProviders.Physical": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "w8vwWXVdFPX/hJptNybW6Nv21j3I6vOrztt3gwp0IPts+v56X9tNjR36ivx6CbEpDs2jP2kx8w8YOTYVwIuwgg==", + "resolved": "6.0.0", + "contentHash": "QvkL7l0nM8udt3gfyu0Vw8bbCXblxaKOl7c2oBfgGy4LCURRaL9XWZX1FWJrQc43oMokVneVxH38iz+bY1sbhg==", "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "3.1.21", - "Microsoft.Extensions.FileSystemGlobbing": "3.1.21" + "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0", + "Microsoft.Extensions.FileSystemGlobbing": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.FileSystemGlobbing": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "Vao4dtipoDQf6jkfYql9MZWJm1U2gv5Ro4a0sMuE0K8Ze3+yRmSyNTtmZer8GLb99xAGyYa2JhfQlFobt269aA==" + "resolved": "6.0.0", + "contentHash": "ip8jnL1aPiaPeKINCqaTEbvBFDmVx9dXQEBZ2HOBRXPD1eabGNqP/bKlsIcp7U2lGxiXd5xIhoFcmY8nM4Hdiw==" }, "Microsoft.Extensions.Logging": { "type": "Transitive", @@ -506,8 +515,11 @@ }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "hhfhugCsGsceQTSdHhtvOnzgGKUDMxcGIMU8z4m8HTTb99B0Ujf7gyT6C4/0hA/KocSN3p/Flt54Y1db9N2TiA==" + "resolved": "6.0.0", + "contentHash": "9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "Microsoft.Identity.Client": { "type": "Transitive", @@ -1314,10 +1326,7 @@ "System.Reflection.Metadata": { "type": "Transitive", "resolved": "5.0.0", - "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==", - "dependencies": { - "System.Collections.Immutable": "5.0.0" - } + "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" }, "System.Reflection.Primitives": { "type": "Transitive", @@ -1361,8 +1370,8 @@ }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==" + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" }, "System.Runtime.Extensions": { "type": "Transitive", @@ -1635,13 +1644,20 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "4.7.2", - "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" + "resolved": "6.0.0", + "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "System.Text.Json": { "type": "Transitive", - "resolved": "4.6.0", - "contentHash": "4F8Xe+JIkVoDJ8hDAZ7HqLkjctN/6WItJIzQaifBwClC7wmoLSda/Sv2i6i1kycqDb3hWF4JCVbpAweyOKHEUA==" + "resolved": "6.0.0", + "contentHash": "zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "6.0.0" + } }, "System.Text.RegularExpressions": { "type": "Transitive", @@ -1768,7 +1784,7 @@ "type": "Project", "dependencies": { "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-alpha.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.0" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0" } } } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj index 5f64e067..e6dcb701 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj @@ -3,7 +3,7 @@ - netcoreapp3.1 + net6.0 enable @@ -21,7 +21,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs index ba0f0c91..fdfc2d53 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs @@ -217,7 +217,7 @@ public async Task GetChildrenAsync(string tenantId, int IEnumerable items = p?.Values ?? Enumerable.Empty(); return new TenantCollectionResult( - items.Select(s => s.Name.Substring(LiveTenantsPrefix.Length)).ToList(), + items.Select(s => s.Name[LiveTenantsPrefix.Length..]).ToList(), GenerateContinuationToken(p?.ContinuationToken)); } diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 689f0328..19d93a63 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -3,6 +3,7 @@ trigger: include: - master - main + - feature/* tags: include: - '*' @@ -13,14 +14,14 @@ resources: type: github name: endjin/Endjin.RecommendedPractices.AzureDevopsPipelines.GitHub endpoint: marain-github + ref: refs/heads/feature/scripted-build jobs: -- template: templates/build.and.release.yml@recommended_practices +- template: templates/build.and.release.scripted.yml@recommended_practices parameters: vmImage: 'windows-latest' service_connection_nuget_org: $(Endjin_Service_Connection_NuGet_Org) service_connection_github: $(Endjin_Service_Connection_GitHub) - solution_to_build: $(Endjin_Solution_To_Build) postCustomEnvironmentVariables: - powershell: | Write-Host "##vso[task.setvariable variable=RootBlobStorageConfiguration__ConnectionStringPlainText]$Env:ENDJIN_AZURESTORAGECONNECTIONSTRING" @@ -32,11 +33,11 @@ jobs: ENDJIN_AZURESERVICESAUTHCONNECTIONSTRING: $(Endjin_AzureServicesAuthConnectionString) TENANTCACHECONFIGURATION__GETTENANTRESPONSECACHECONTROLHEADERVALUE: $(TenantCacheConfiguration__GetTenantResponseCacheControlHeaderValue) - task: Npm@1 - displayName: 'Install Latest Azure Functions V3 Runtime' + displayName: 'Install Latest Azure Functions V4 Runtime' inputs: command: custom verbose: false - customCommand: 'install -g azure-functions-core-tools@3 --unsafe-perm true' + customCommand: 'install -g azure-functions-core-tools@4 --unsafe-perm true' # We want to include the deployment project in the assets. Currently this is experimental, # and once we're done, probably some of this is going to move into the common templates. @@ -47,7 +48,10 @@ jobs: # up with an asset in the GitHub for every file in that project. So I think we need to # ZIP it up. # Something we can't currently do is set labels on GitHub release assets. - postPack: + # TODO: find the right way to do this: + # * integrate with scripted build + # * use the correct folders once we're on .NET 6.0 for most things + preCopyNugetPackages: - task: ArchiveFiles@2 displayName: 'ZIP Azure Deployment Project' inputs: @@ -86,4 +90,4 @@ jobs: SourceFolder: '$(Build.SourcesDirectory)/Solutions/Marain.Tenancy.Host.Functions/bin/$(BuildConfiguration)/publish/' Contents: '*.zip' TargetFolder: '$(Build.ArtifactStagingDirectory)/Release/Marain.Deployment.Functions' - netSdkVersion: '3.x' \ No newline at end of file + netSdkVersion: '6.x' \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 00000000..4a8ecb2d --- /dev/null +++ b/build.ps1 @@ -0,0 +1,140 @@ +<# +.SYNOPSIS + Runs a .NET flavoured build process. +.DESCRIPTION + This script was scaffolded using a template from the Endjin.RecommendedPractices.Build PowerShell module. + It uses the InvokeBuild module to orchestrate an opinonated software build process for .NET solutions. +.EXAMPLE + PS C:\> ./build.ps1 + Downloads any missing module dependencies (Endjin.RecommendedPractices.Build & InvokeBuild) and executes + the build process. +.PARAMETER Tasks + Optionally override the default task executed as the entry-point of the build. +.PARAMETER Configuration + The build configuration, defaults to 'Release'. +.PARAMETER BuildRepositoryUri + Optional URI that supports pulling MSBuild logic from a web endpoint (e.g. a GitHub blob). +.PARAMETER SourcesDir + The path where the source code to be built is located, defaults to the current working directory. +.PARAMETER CoverageDir + The output path for the test coverage data, if run. +.PARAMETER TestReportTypes + The test report format that should be generated by the test report generator, if run. +.PARAMETER PackagesDir + The output path for any packages produced as part of the build. +.PARAMETER LogLevel + The logging verbosity. +.PARAMETER Clean + When true, the .NET solution will be cleaned and all output/intermediate folders deleted. +.PARAMETER BuildModulePath + The path to import the Endjin.RecommendedPractices.Build module from. This is useful when + testing pre-release versions of the Endjin.RecommendedPractices.Build that are not yet + available in the PowerShell Gallery. +#> +[CmdletBinding()] +param ( + [Parameter(Position=0)] + [string[]] $Tasks = @("."), + + [Parameter()] + [string] $Configuration = "Release", + + [Parameter()] + [string] $BuildRepositoryUri = "", + + [Parameter()] + [string] $SourcesDir = $PWD, + + [Parameter()] + [string] $CoverageDir = "_codeCoverage", + + [Parameter()] + [string] $TestReportTypes = "Cobertura", + + [Parameter()] + [string] $PackagesDir = "_packages", + + [Parameter()] + [ValidateSet("minimal","normal","detailed")] + [string] $LogLevel = "minimal", + + [Parameter()] + [switch] $Clean, + + [Parameter()] + [string] $BuildModulePath +) + +$ErrorActionPreference = $ErrorActionPreference ? $ErrorActionPreference : 'Stop' +$InformationPreference = $InformationAction ? $InformationAction : 'Continue' + +$here = Split-Path -Parent $PSCommandPath + +#region InvokeBuild setup +if (!(Get-Module -ListAvailable InvokeBuild)) { + Install-Module InvokeBuild -RequiredVersion 5.7.1 -Scope CurrentUser -Force -Repository PSGallery +} +Import-Module InvokeBuild +# This handles calling the build engine when this file is run like a normal PowerShell script +# (i.e. avoids the need to have another script to setup the InvokeBuild environment and issue the 'Invoke-Build' command ) +if ($MyInvocation.ScriptName -notlike '*Invoke-Build.ps1') { + try { + Invoke-Build $Tasks $MyInvocation.MyCommand.Path @PSBoundParameters + } + catch { + $_.ScriptStackTrace + throw + } + return +} +#endregion + +# Import shared tasks and initialise build framework +if (!($BuildModulePath)) { + if (!(Get-Module -ListAvailable Endjin.RecommendedPractices.Build)) { + Write-Information "Installing 'Endjin.RecommendedPractices.Build' module..." + Install-Module Endjin.RecommendedPractices.Build -RequiredVersion 0.1.0 -AllowPrerelease -Scope CurrentUser -Force -Repository PSGallery + } + $BuildModulePath = "Endjin.RecommendedPractices.Build" +} +else { + Write-Information "BuildModulePath: $BuildModulePath" +} +Import-Module $BuildModulePath -Force + +# Load the build process & tasks +. Endjin.RecommendedPractices.Build.tasks + +# +# Build process control options +# +$SkipVersion = $false +$SkipBuild = $false +$CleanBuild = $false +$SkipTest = $false +$SkipTestReport = $false +$SkipPackage = $false + +# Advanced build settings +$EnableGitVersionAdoVariableWorkaround = $false + +# +# Build process configuration +# +$SolutionToBuild = (Resolve-Path (Join-Path $here ".\Solutions\Marain.Tenancy.sln")).Path + + +# Synopsis: Build, Test and Package +task . FullBuild + + +# build extensibility tasks +task PreBuild {} +task PostBuild {} +task PreTest {} +task PostTest {} +task PreTestReport {} +task PostTestReport {} +task PrePackage {} +task PostPackage {} + From 430f8fa379806f5e5d7eede6a7d3563b395816d2 Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Fri, 17 Dec 2021 15:02:39 +0000 Subject: [PATCH 07/10] Upgrade to Corvus.Tenancy 3.0.0 release (#363) Update various other NuGet refs too. --- .../Marain.Tenancy.Cli/packages.lock.json | 85 +++--- .../Marain.Tenancy.Client.csproj | 4 +- ...Marain.Tenancy.ClientTenantProvider.csproj | 2 +- .../packages.lock.json | 98 ++++--- .../Marain.Tenancy.OpenApi.Service.csproj | 4 +- .../Marain.Tenancy.Specs.csproj | 2 +- .../Marain.Tenancy.Specs/packages.lock.json | 242 ++++++++--------- .../TenancyContainerSetupDirectToStorage.cs | 8 +- .../Bindings/TenancyContainerSetupViaApi.cs | 8 +- .../Bindings/TenantSetupSteps.cs | 4 +- ...ncy.Storage.Azure.BlobStorage.Specs.csproj | 2 +- .../packages.lock.json | 252 +++++++++--------- ...n.Tenancy.Storage.Azure.BlobStorage.csproj | 2 +- ...yBlobStorageServiceCollectionExtensions.cs | 15 +- 14 files changed, 360 insertions(+), 368 deletions(-) diff --git a/Solutions/Marain.Tenancy.Cli/packages.lock.json b/Solutions/Marain.Tenancy.Cli/packages.lock.json index 15b4025f..1b41ddff 100644 --- a/Solutions/Marain.Tenancy.Cli/packages.lock.json +++ b/Solutions/Marain.Tenancy.Cli/packages.lock.json @@ -76,32 +76,30 @@ }, "Azure.Core": { "type": "Transitive", - "resolved": "1.17.0", - "contentHash": "ByJGsP7zqeMG+QFLEpd0ILzWVlRtB1ZWwgkqNWEN2KV0axRyWZDm6uPsKtsfBkNeiPtr4fUW0NSZez69TBSGrA==", + "resolved": "1.20.0", + "contentHash": "q7xigZIBjLjSKJA/Y+VygmJ2iZGiEyNuicN5iRX9oJL7451SulZm/CQ7qd8YCeL5TgNCNYCIrTIqRaams95zHA==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "1.0.0", - "System.Buffers": "4.5.1", "System.Diagnostics.DiagnosticSource": "4.6.0", - "System.Memory": "4.5.4", "System.Memory.Data": "1.0.2", "System.Numerics.Vectors": "4.5.0", "System.Text.Encodings.Web": "4.7.2", "System.Text.Json": "4.6.0", - "System.Threading.Tasks.Extensions": "4.5.2" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Azure.Identity": { "type": "Transitive", - "resolved": "1.4.1", - "contentHash": "yuxWej20CUtK2HUU4jm9Vft1wPw2NWKpwS9Zr0hJyph0dp7vgihlzlujR26UdhmvgdMdswsFRZL+k0HcaS07tw==", + "resolved": "1.5.0", + "contentHash": "VfF88dqrgKXZNOS/y4XrX/jmIfP3pkY+hBUzBNpoKml1nR+QshX6XlXWyToLtWV80TDQ1CmUVCJksktDg5+j1w==", "dependencies": { - "Azure.Core": "1.17.0", + "Azure.Core": "1.20.0", "Microsoft.Identity.Client": "4.30.1", "Microsoft.Identity.Client.Extensions.Msal": "2.18.4", "System.Memory": "4.5.4", "System.Security.Cryptography.ProtectedData": "4.5.0", "System.Text.Json": "4.6.0", - "System.Threading.Tasks.Extensions": "4.5.2" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Azure.Security.KeyVault.Secrets": { @@ -117,19 +115,19 @@ }, "CacheCow.Client": { "type": "Transitive", - "resolved": "2.8.3", - "contentHash": "hatqwAMz+SPi5I0M7iRu5/d/44oimH7UjwWRGCTRCkWC1MszuZx+C1Geys1SG76vaYy+aXSzwMOnuG7R+JCxAg==", + "resolved": "2.9.0", + "contentHash": "Ae625OchaUKohRc3OqQOXs1J1tO9g3naVtiwtaQNx2wGJuncZUAY7uLYREVQm1qWtGks9dMtXzCcd3ADUohDoQ==", "dependencies": { - "CacheCow.Common": "2.8.3", + "CacheCow.Common": "2.9.0", "Microsoft.AspNet.WebApi.Client": "5.2.5", - "Microsoft.Extensions.Caching.Memory": "2.0.1", + "Microsoft.Extensions.Caching.Memory": "5.0.0", "Newtonsoft.Json": "11.0.1" } }, "CacheCow.Common": { "type": "Transitive", - "resolved": "2.8.3", - "contentHash": "eJF4/Tn2sVza/7c4RJG8CoBTO/nzdyuesDmL8OE28kN8BML47/6A9/UQk1QEpogG7tLgOfEylrSR8rLRYMPn+Q==", + "resolved": "2.9.0", + "contentHash": "ZIga1BwXYWazY+v+Q8OjvLqhjPVZnAlEZy+8bHJLTxE7q/Ks2CFEFgw+ugO24R4gVsiffyBHSC1sFx/C4agXgA==", "dependencies": { "Microsoft.AspNet.WebApi.Client": "5.2.5", "Newtonsoft.Json": "11.0.1" @@ -175,27 +173,28 @@ }, "Corvus.Identity.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-alpha.3", - "contentHash": "9ejidQMzyEnEmjRn7fWIqbcYPnO79eeyGDf+2vCDRT4SxclwLQ97IIt0LMZSeqnqhdlm6lqZojJB0B84e+jR+Q==" + "resolved": "3.0.0", + "contentHash": "fGYhKMz/n1Ejv77r+0bmzdC9EW3sCfZ3P8dky6rrOEGK4Kijd9yjTwoFEaG9ZHPXu5C7r2O2VqpesgIDkn5iQA==" }, "Corvus.Identity.Azure": { "type": "Transitive", - "resolved": "3.0.0-alpha.3", - "contentHash": "MYFzUYDF1kACA18Vb+5+sfQ5fv58pAAipfq7BHM/5tDs5xcfrGErcitFS3fbPTCVrSAW62E9hEpsiuXNPzc7TA==", + "resolved": "3.0.0", + "contentHash": "TYNTb4CD0pyn9WX4gC8TFGTU0v4inAkVEEG9xCyASgpp0ahMlL8RUfgQAwKZqr6yJ+tHpdjlx02mHJeSWidSiA==", "dependencies": { - "Azure.Identity": "1.4.1", + "Azure.Identity": "1.5.0", "Azure.Security.KeyVault.Secrets": "4.2.0", - "Corvus.Identity.Abstractions": "3.0.0-alpha.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" + "Corvus.Identity.Abstractions": "3.0.0", + "Microsoft.Extensions.Caching.Memory": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0" } }, "Corvus.Identity.MicrosoftRest": { "type": "Transitive", - "resolved": "3.0.0-alpha.3", - "contentHash": "aOHqhlUH57XB+m1m103eyKs7m4XZ83LkkV2eHUu799XX8MdAwGRhuOme34u6PeZRj0hy35qcfJMx8H7MQ11/oA==", + "resolved": "3.0.0", + "contentHash": "vo0093/bxEASSxC7TFJ6ZPKo9Paj2bIwREic0iTzrjiO4K6JI+oKMW58zPwciEZ2gJJYvov0mx68LmIpibSZSw==", "dependencies": { - "Corvus.Identity.Azure": "3.0.0-alpha.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Corvus.Identity.Azure": "3.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } }, @@ -206,12 +205,12 @@ }, "Corvus.Tenancy.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-v3-blob.11", - "contentHash": "bRhFGCHioBAMbGxPLmfIXKYWq9Tx18gMPZ5aISVgVoRErxt9TNIOkLhQG3WkjayX22bA9zWSm9vg4qG3DIsRPg==", + "resolved": "3.0.0", + "contentHash": "pDCUxkUHTCE0fywCBmNnTjoBofrY5wo3IMfEvuCws2T6gi823UpwHWqWOJLhc8xxw8Br4tX1FWuSOVx2DFAHyA==", "dependencies": { "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.AspNet.WebApi.Client": { @@ -271,20 +270,22 @@ }, "Microsoft.Extensions.Caching.Abstractions": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "NobDNbehAbMYUApMXLd9XSt9UznGCgPW9PW4Ybe6S5jKqkd5RcTnaKm0FODcgyx+7B1hIGx7dZwa1bVdiSbHAg==", + "resolved": "6.0.0", + "contentHash": "bcz5sSFJbganH0+YrfvIjJDIcKNW7TL07C4d1eTmXy/wOt52iz4LVogJb6pazs7W0+74j0YpXFErvp++Aq5Bsw==", "dependencies": { - "Microsoft.Extensions.Primitives": "2.0.0" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Caching.Memory": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "GVtJD0uhoLOkXBfYZAIRDexEr2qg0QHbUo3CIjmtoGpFWHuGHTvjGqRlybMKIYTpt0BxKpXMn4fqhS4ff10llA==", + "resolved": "6.0.0", + "contentHash": "Ve3BlCzhAlVp5IgO3+8dacAhZk1A0GlIlFNkAcfR2TfAibLKWIt5DhVJZfu4YtW+XZ89OjYf/agMcgjDtPxdGA==", "dependencies": { - "Microsoft.Extensions.Caching.Abstractions": "2.0.1", - "Microsoft.Extensions.DependencyInjection.Abstractions": "2.0.0", - "Microsoft.Extensions.Options": "2.0.1" + "Microsoft.Extensions.Caching.Abstractions": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration": { @@ -769,8 +770,8 @@ }, "System.Buffers": { "type": "Transitive", - "resolved": "4.5.1", - "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + "resolved": "4.5.0", + "contentHash": "pL2ChpaRRWI/p4LXyy4RgeWlYF2sgfj/pnVMvBqwNFr5cXg7CXNnWZWxrOONLg8VGdFB8oB+EG2Qw4MLgTOe+A==" }, "System.Collections": { "type": "Transitive", @@ -1556,10 +1557,10 @@ "marain.tenancy.client": { "type": "Project", "dependencies": { - "CacheCow.Client": "2.8.3", + "CacheCow.Client": "2.9.0", "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.3", + "Corvus.Identity.MicrosoftRest": "3.0.0", "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } @@ -1567,7 +1568,7 @@ "marain.tenancy.clienttenantprovider": { "type": "Project", "dependencies": { - "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", + "Corvus.Tenancy.Abstractions": "3.0.0", "Marain.Tenancy.Client": "1.0.0", "Microsoft.AspNetCore.WebUtilities": "2.2.0" } diff --git a/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj b/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj index d4f6ca6b..d0268283 100644 --- a/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj +++ b/Solutions/Marain.Tenancy.Client/Marain.Tenancy.Client.csproj @@ -24,10 +24,10 @@ - + - + diff --git a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj index 6050d1b8..2814e397 100644 --- a/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj +++ b/Solutions/Marain.Tenancy.ClientTenantProvider/Marain.Tenancy.ClientTenantProvider.csproj @@ -17,7 +17,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json index 7a4ef92f..e9accdb8 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json +++ b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json @@ -78,32 +78,30 @@ }, "Azure.Core": { "type": "Transitive", - "resolved": "1.19.0", - "contentHash": "lcDjG635DPE4fU5tqSueVMmzrx0QrIfPuY0+y6evHN5GanQ0GB+/4nuMHMmoNPwEow6OUPkJu4cZQxfHJQXPdA==", + "resolved": "1.20.0", + "contentHash": "q7xigZIBjLjSKJA/Y+VygmJ2iZGiEyNuicN5iRX9oJL7451SulZm/CQ7qd8YCeL5TgNCNYCIrTIqRaams95zHA==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "1.0.0", - "System.Buffers": "4.5.1", "System.Diagnostics.DiagnosticSource": "4.6.0", - "System.Memory": "4.5.4", "System.Memory.Data": "1.0.2", "System.Numerics.Vectors": "4.5.0", "System.Text.Encodings.Web": "4.7.2", "System.Text.Json": "4.6.0", - "System.Threading.Tasks.Extensions": "4.5.2" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Azure.Identity": { "type": "Transitive", - "resolved": "1.4.1", - "contentHash": "yuxWej20CUtK2HUU4jm9Vft1wPw2NWKpwS9Zr0hJyph0dp7vgihlzlujR26UdhmvgdMdswsFRZL+k0HcaS07tw==", + "resolved": "1.5.0", + "contentHash": "VfF88dqrgKXZNOS/y4XrX/jmIfP3pkY+hBUzBNpoKml1nR+QshX6XlXWyToLtWV80TDQ1CmUVCJksktDg5+j1w==", "dependencies": { - "Azure.Core": "1.17.0", + "Azure.Core": "1.20.0", "Microsoft.Identity.Client": "4.30.1", "Microsoft.Identity.Client.Extensions.Msal": "2.18.4", "System.Memory": "4.5.4", "System.Security.Cryptography.ProtectedData": "4.5.0", "System.Text.Json": "4.6.0", - "System.Threading.Tasks.Extensions": "4.5.2" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Azure.Security.KeyVault.Secrets": { @@ -174,18 +172,19 @@ }, "Corvus.Identity.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-identity-configuration.3", - "contentHash": "wLZih7d7jz6WoDjVHMrLzxM72GqF88g3n7JOGLpPbTbu+Q7Qekc9sSSM8PBFjVyURaQwuk/Xq/cyj3hKIFDRkQ==" + "resolved": "3.0.0", + "contentHash": "fGYhKMz/n1Ejv77r+0bmzdC9EW3sCfZ3P8dky6rrOEGK4Kijd9yjTwoFEaG9ZHPXu5C7r2O2VqpesgIDkn5iQA==" }, "Corvus.Identity.Azure": { "type": "Transitive", - "resolved": "3.0.0-identity-configuration.3", - "contentHash": "r3d24icyK7g07cvaiIymJxwL5S6te77sHFBFZb5XRGRqUzsLePBbccmW4G2x3zb1efvduObR0Uh32tqmiDZy8A==", + "resolved": "3.0.0", + "contentHash": "TYNTb4CD0pyn9WX4gC8TFGTU0v4inAkVEEG9xCyASgpp0ahMlL8RUfgQAwKZqr6yJ+tHpdjlx02mHJeSWidSiA==", "dependencies": { - "Azure.Identity": "1.4.1", + "Azure.Identity": "1.5.0", "Azure.Security.KeyVault.Secrets": "4.2.0", - "Corvus.Identity.Abstractions": "3.0.0-identity-configuration.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" + "Corvus.Identity.Abstractions": "3.0.0", + "Microsoft.Extensions.Caching.Memory": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0" } }, "Corvus.Json.Abstractions": { @@ -203,40 +202,39 @@ }, "Corvus.Storage.Azure.BlobStorage": { "type": "Transitive", - "resolved": "3.0.0-1-refactor-from-tenancy.10", - "contentHash": "xzy+Z5ZzpJ4GEh2MxQ4IlufXtosjwcY1Tk0Xg8SyQ2ktVHLWbly2emkEqiESFjVLUoM3sNVqd46eqflP6eXkqw==", + "resolved": "1.0.0", + "contentHash": "jskZtDcYc5DJySAMwKkbcMKW5zJvaVOZdRfCmRoruk8yJvGxgJ92MhsdXmUSBOgvq7zC0CkOS0bF18WAgt6Tnw==", "dependencies": { "Azure.Storage.Blobs": "12.10.0", - "Corvus.Storage.Common": "3.0.0-1-refactor-from-tenancy.10" + "Corvus.Storage.Common": "1.0.0" } }, "Corvus.Storage.Azure.BlobStorage.Tenancy": { "type": "Transitive", - "resolved": "3.0.0-alpha.3", - "contentHash": "aQ/WtonoXdEtJbnx5H9++LyOQscxdsOLR7B6u4SIWYsNqq3Lsxb9GNmVN2OVh3TaaMPoLCKVUEUUKd2Sp/t/Rg==", + "resolved": "3.0.0", + "contentHash": "20CJow+8yGU74wvZaSyxt3TiGxrxEPbqTohNvWIW50kCG+MOLbaN1PaKszcwgX5yCLb3sCo8C/LqCKO0E47Ckg==", "dependencies": { - "Corvus.Storage.Azure.BlobStorage": "3.0.0-1-refactor-from-tenancy.10", - "Corvus.Tenancy.Abstractions": "3.0.0-alpha.3" + "Corvus.Storage.Azure.BlobStorage": "1.0.0", + "Corvus.Tenancy.Abstractions": "3.0.0" } }, "Corvus.Storage.Common": { "type": "Transitive", - "resolved": "3.0.0-1-refactor-from-tenancy.10", - "contentHash": "bDirPOYtbvitnSB9efYfiwfJsc/mI9ObP6qa5zAQvwzWHxUPGqY5o82AWKRk/7ADmWw26B1kzmyZGFWF4eY8jw==", + "resolved": "1.0.0", + "contentHash": "JF5H73X+s9MvJODJZ69ajbLBqPOUpBLaPYkEUO5SIsSvu+suRoOrkqmDnc8EKUFOutdq5jC9PsfLBbV0v6eaNw==", "dependencies": { - "Azure.Security.KeyVault.Secrets": "4.2.0", - "Corvus.Identity.Azure": "3.0.0-identity-configuration.3", - "Microsoft.Extensions.Configuration.Binder": "3.1.21" + "Corvus.Identity.Azure": "3.0.0", + "Microsoft.Extensions.Configuration.Binder": "3.1.22" } }, "Corvus.Tenancy.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-v3-blob.11", - "contentHash": "bRhFGCHioBAMbGxPLmfIXKYWq9Tx18gMPZ5aISVgVoRErxt9TNIOkLhQG3WkjayX22bA9zWSm9vg4qG3DIsRPg==", + "resolved": "3.0.0", + "contentHash": "pDCUxkUHTCE0fywCBmNnTjoBofrY5wo3IMfEvuCws2T6gi823UpwHWqWOJLhc8xxw8Br4tX1FWuSOVx2DFAHyA==", "dependencies": { "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Menes.Abstractions": { @@ -274,8 +272,8 @@ }, "Microsoft.ApplicationInsights": { "type": "Transitive", - "resolved": "2.19.0", - "contentHash": "QMs/5PVRyVv5T5G+UCtCCzSXjVR3WdcgeZqNhwtHCE+5k9S6mc+8pRE5WpsUsjgqwgNYES82bfQ6PsSu4YVPAA==", + "resolved": "2.20.0", + "contentHash": "mb+EC5j06Msn5HhKrhrsMAst6JxvYUnphQMGY2cixCabgGAO3q79Y8o/p1Zce1Azgd1IVkRKAMzAV4vDCbXOqA==", "dependencies": { "System.Diagnostics.DiagnosticSource": "5.0.0" } @@ -388,8 +386,8 @@ }, "Microsoft.AspNetCore.JsonPatch": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "SUiwg0XQ5NtmnELHXSdX4mAwawFnAOwSx2Zz6NIhQnEN1tZDoAWEHc8dS/S7y8cE52+9bHj+XbYZuLGF7OrQPA==", + "resolved": "6.0.1", + "contentHash": "vLgQbgudEQfGNaGyAvm+jlfLHu5Ynav8/RnhwM0QaKFjVW2crEOGm7tRHHjM5iofF8VZnEYfyvUvyK82dBej1w==", "dependencies": { "Microsoft.CSharp": "4.7.0", "Newtonsoft.Json": "13.0.1" @@ -611,6 +609,26 @@ "System.Runtime.InteropServices.RuntimeInformation": "4.0.0" } }, + "Microsoft.Extensions.Caching.Abstractions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "bcz5sSFJbganH0+YrfvIjJDIcKNW7TL07C4d1eTmXy/wOt52iz4LVogJb6pazs7W0+74j0YpXFErvp++Aq5Bsw==", + "dependencies": { + "Microsoft.Extensions.Primitives": "6.0.0" + } + }, + "Microsoft.Extensions.Caching.Memory": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Ve3BlCzhAlVp5IgO3+8dacAhZk1A0GlIlFNkAcfR2TfAibLKWIt5DhVJZfu4YtW+XZ89OjYf/agMcgjDtPxdGA==", + "dependencies": { + "Microsoft.Extensions.Caching.Abstractions": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" + } + }, "Microsoft.Extensions.Configuration": { "type": "Transitive", "resolved": "6.0.0", @@ -1065,8 +1083,8 @@ }, "System.Buffers": { "type": "Transitive", - "resolved": "4.5.1", - "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + "resolved": "4.5.0", + "contentHash": "pL2ChpaRRWI/p4LXyy4RgeWlYF2sgfj/pnVMvBqwNFr5cXg7CXNnWZWxrOONLg8VGdFB8oB+EG2Qw4MLgTOe+A==" }, "System.Collections": { "type": "Transitive", @@ -1914,9 +1932,9 @@ "marain.tenancy.openapi.service": { "type": "Project", "dependencies": { - "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", + "Corvus.Tenancy.Abstractions": "3.0.0", "Menes.Abstractions": "3.0.0-vnext.4", - "Microsoft.ApplicationInsights": "2.19.0", + "Microsoft.ApplicationInsights": "2.20.0", "Microsoft.AspNetCore.JsonPatch": "6.0.0", "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "6.0.0" @@ -1925,7 +1943,7 @@ "marain.tenancy.storage.azure.blobstorage": { "type": "Project", "dependencies": { - "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-alpha.3", + "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0", "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0" } } diff --git a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj index fbda2873..8d52b519 100644 --- a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj +++ b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj @@ -25,13 +25,13 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.csproj b/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.csproj index b1f85357..d9d882e9 100644 --- a/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.csproj +++ b/Solutions/Marain.Tenancy.Specs/Marain.Tenancy.Specs.csproj @@ -41,7 +41,7 @@ - + diff --git a/Solutions/Marain.Tenancy.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Specs/packages.lock.json index 17cfb427..8c1d0759 100644 --- a/Solutions/Marain.Tenancy.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Specs/packages.lock.json @@ -4,14 +4,14 @@ "net6.0": { "Corvus.Testing.AzureFunctions.SpecFlow.NUnit": { "type": "Direct", - "requested": "[1.4.6, )", - "resolved": "1.4.6", - "contentHash": "/8bUlkeVbPRcdtPCdvPfa00HtJbcZtXj89dk6biXK1s2shCntbQQWW9N3t31hARMFOen6F/ViHVWW4Ok+Yh6Pw==", + "requested": "[1.4.7, )", + "resolved": "1.4.7", + "contentHash": "u3SWrAnIlr54LIogoRJNDuEuE0bQ7UpYGmsaXEDWUopMxAFuOdw1nerNoQbumtMrLtOU4ETBnC7plJhVsvAGVg==", "dependencies": { - "Corvus.Testing.AzureFunctions.SpecFlow": "1.4.6", - "Microsoft.NET.Test.Sdk": "[16.10.0, 17.0.0)", + "Corvus.Testing.AzureFunctions.SpecFlow": "1.4.7", + "Microsoft.NET.Test.Sdk": "16.11.0", "Moq": "4.16.1", - "SpecFlow.NUnit.Runners": "3.9.22", + "SpecFlow.NUnit.Runners": "3.9.40", "coverlet.msbuild": "3.1.0" } }, @@ -50,32 +50,30 @@ }, "Azure.Core": { "type": "Transitive", - "resolved": "1.17.0", - "contentHash": "ByJGsP7zqeMG+QFLEpd0ILzWVlRtB1ZWwgkqNWEN2KV0axRyWZDm6uPsKtsfBkNeiPtr4fUW0NSZez69TBSGrA==", + "resolved": "1.20.0", + "contentHash": "q7xigZIBjLjSKJA/Y+VygmJ2iZGiEyNuicN5iRX9oJL7451SulZm/CQ7qd8YCeL5TgNCNYCIrTIqRaams95zHA==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "1.0.0", - "System.Buffers": "4.5.1", "System.Diagnostics.DiagnosticSource": "4.6.0", - "System.Memory": "4.5.4", "System.Memory.Data": "1.0.2", "System.Numerics.Vectors": "4.5.0", "System.Text.Encodings.Web": "4.7.2", "System.Text.Json": "4.6.0", - "System.Threading.Tasks.Extensions": "4.5.2" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Azure.Identity": { "type": "Transitive", - "resolved": "1.4.1", - "contentHash": "yuxWej20CUtK2HUU4jm9Vft1wPw2NWKpwS9Zr0hJyph0dp7vgihlzlujR26UdhmvgdMdswsFRZL+k0HcaS07tw==", + "resolved": "1.5.0", + "contentHash": "VfF88dqrgKXZNOS/y4XrX/jmIfP3pkY+hBUzBNpoKml1nR+QshX6XlXWyToLtWV80TDQ1CmUVCJksktDg5+j1w==", "dependencies": { - "Azure.Core": "1.17.0", + "Azure.Core": "1.20.0", "Microsoft.Identity.Client": "4.30.1", "Microsoft.Identity.Client.Extensions.Msal": "2.18.4", "System.Memory": "4.5.4", "System.Security.Cryptography.ProtectedData": "4.5.0", "System.Text.Json": "4.6.0", - "System.Threading.Tasks.Extensions": "4.5.2" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Azure.Security.KeyVault.Secrets": { @@ -96,19 +94,19 @@ }, "CacheCow.Client": { "type": "Transitive", - "resolved": "2.8.3", - "contentHash": "hatqwAMz+SPi5I0M7iRu5/d/44oimH7UjwWRGCTRCkWC1MszuZx+C1Geys1SG76vaYy+aXSzwMOnuG7R+JCxAg==", + "resolved": "2.9.0", + "contentHash": "Ae625OchaUKohRc3OqQOXs1J1tO9g3naVtiwtaQNx2wGJuncZUAY7uLYREVQm1qWtGks9dMtXzCcd3ADUohDoQ==", "dependencies": { - "CacheCow.Common": "2.8.3", + "CacheCow.Common": "2.9.0", "Microsoft.AspNet.WebApi.Client": "5.2.5", - "Microsoft.Extensions.Caching.Memory": "2.0.1", + "Microsoft.Extensions.Caching.Memory": "5.0.0", "Newtonsoft.Json": "11.0.1" } }, "CacheCow.Common": { "type": "Transitive", - "resolved": "2.8.3", - "contentHash": "eJF4/Tn2sVza/7c4RJG8CoBTO/nzdyuesDmL8OE28kN8BML47/6A9/UQk1QEpogG7tLgOfEylrSR8rLRYMPn+Q==", + "resolved": "2.9.0", + "contentHash": "ZIga1BwXYWazY+v+Q8OjvLqhjPVZnAlEZy+8bHJLTxE7q/Ks2CFEFgw+ugO24R4gVsiffyBHSC1sFx/C4agXgA==", "dependencies": { "Microsoft.AspNet.WebApi.Client": "5.2.5", "Newtonsoft.Json": "11.0.1" @@ -171,27 +169,28 @@ }, "Corvus.Identity.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-alpha.3", - "contentHash": "9ejidQMzyEnEmjRn7fWIqbcYPnO79eeyGDf+2vCDRT4SxclwLQ97IIt0LMZSeqnqhdlm6lqZojJB0B84e+jR+Q==" + "resolved": "3.0.0", + "contentHash": "fGYhKMz/n1Ejv77r+0bmzdC9EW3sCfZ3P8dky6rrOEGK4Kijd9yjTwoFEaG9ZHPXu5C7r2O2VqpesgIDkn5iQA==" }, "Corvus.Identity.Azure": { "type": "Transitive", - "resolved": "3.0.0-alpha.3", - "contentHash": "MYFzUYDF1kACA18Vb+5+sfQ5fv58pAAipfq7BHM/5tDs5xcfrGErcitFS3fbPTCVrSAW62E9hEpsiuXNPzc7TA==", + "resolved": "3.0.0", + "contentHash": "TYNTb4CD0pyn9WX4gC8TFGTU0v4inAkVEEG9xCyASgpp0ahMlL8RUfgQAwKZqr6yJ+tHpdjlx02mHJeSWidSiA==", "dependencies": { - "Azure.Identity": "1.4.1", + "Azure.Identity": "1.5.0", "Azure.Security.KeyVault.Secrets": "4.2.0", - "Corvus.Identity.Abstractions": "3.0.0-alpha.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" + "Corvus.Identity.Abstractions": "3.0.0", + "Microsoft.Extensions.Caching.Memory": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0" } }, "Corvus.Identity.MicrosoftRest": { "type": "Transitive", - "resolved": "3.0.0-alpha.3", - "contentHash": "aOHqhlUH57XB+m1m103eyKs7m4XZ83LkkV2eHUu799XX8MdAwGRhuOme34u6PeZRj0hy35qcfJMx8H7MQ11/oA==", + "resolved": "3.0.0", + "contentHash": "vo0093/bxEASSxC7TFJ6ZPKo9Paj2bIwREic0iTzrjiO4K6JI+oKMW58zPwciEZ2gJJYvov0mx68LmIpibSZSw==", "dependencies": { - "Corvus.Identity.Azure": "3.0.0-alpha.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Corvus.Identity.Azure": "3.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } }, @@ -210,45 +209,45 @@ }, "Corvus.Tenancy.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-v3-blob.11", - "contentHash": "bRhFGCHioBAMbGxPLmfIXKYWq9Tx18gMPZ5aISVgVoRErxt9TNIOkLhQG3WkjayX22bA9zWSm9vg4qG3DIsRPg==", + "resolved": "3.0.0", + "contentHash": "pDCUxkUHTCE0fywCBmNnTjoBofrY5wo3IMfEvuCws2T6gi823UpwHWqWOJLhc8xxw8Br4tX1FWuSOVx2DFAHyA==", "dependencies": { "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Corvus.Testing.AzureFunctions": { "type": "Transitive", - "resolved": "1.4.6", - "contentHash": "dOoUYwj72I23Egq+FVd5kq+hP2zgw1VdJX1FHoz0ls5n7eBTt9YXHe4rsjNvEZzmQMN1cDv7zoBXX1jGiIB1dg==", + "resolved": "1.4.7", + "contentHash": "Q/qDg0sJ80B/phIrj8/XMcMQgFifpfb27VVb7WyUjZNrJ/uNG8nDj1m5OXyU2tkv7YSgcfiP/6WZk2fraYqM7Q==", "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "3.1.20", + "Microsoft.Extensions.Logging.Abstractions": "3.1.21", "System.Management": "4.7.0" } }, "Corvus.Testing.AzureFunctions.SpecFlow": { "type": "Transitive", - "resolved": "1.4.6", - "contentHash": "kNwjluoe+fTid58d2YOGCgYbw3eWRqItC8HQ5N4rGsl4ZjuG1IOeFP/zjCG96NllRRVDRYoNguEQIregT04bnQ==", + "resolved": "1.4.7", + "contentHash": "0UBYNU+Cbj4XYpUm3RLR8UjNfCO4IGsjps+uD1Cvg4nGib0db8qQOqcgnNj9wq9nacYY+ZYZWO/64xUlXrRFrg==", "dependencies": { - "Corvus.Testing.AzureFunctions": "1.4.6", - "Corvus.Testing.SpecFlow": "1.4.6", - "Microsoft.Extensions.Logging.Console": "3.1.20", + "Corvus.Testing.AzureFunctions": "1.4.7", + "Corvus.Testing.SpecFlow": "1.4.7", + "Microsoft.Extensions.Logging.Console": "3.1.21", "NUnit": "3.13.2", - "SpecFlow": "3.9.22" + "SpecFlow": "3.9.40" } }, "Corvus.Testing.SpecFlow": { "type": "Transitive", - "resolved": "1.4.6", - "contentHash": "EmakRYEWtLqOXJXV8vOq4bOikivszKcclnRClM65IULefSCY1Cm+pP5wvJusetZWRQ7xXjvI9Hzp25T1MJmVBQ==", + "resolved": "1.4.7", + "contentHash": "qGqOQt/9x95MOmUyA57JgNmdWRF1lgKjYEjU9IXw3ElMYs5S93I0qHiqBdQCIDq8qHxkXgo6cnDIJsrBLCrReQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.DependencyInjection": "3.1.20", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.DependencyInjection": "3.1.21", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", "NUnit": "3.13.2", - "SpecFlow": "3.9.22", + "SpecFlow": "3.9.40", "System.Management": "4.7.0" } }, @@ -257,27 +256,11 @@ "resolved": "3.1.0", "contentHash": "xOv5HZagq0I6uF4vt8NVVpwcA2W/uGmNcbLStao2eMk98RQH5NFPQuouh2nWWPSZrNIhGG/iYbBn2pO4s5i+ig==" }, - "Cucumber.Messages": { - "type": "Transitive", - "resolved": "6.0.1", - "contentHash": "R/2XAU6Zwdnlgga/YLYxwbKf4ai0JYyeX25l85t0nNgagR2aP8hnqrLtJjgswuXVa2WlQdjXUfJqUX8YTjzlXw==", - "dependencies": { - "Google.Protobuf": "3.7.0" - } - }, "Gherkin": { "type": "Transitive", "resolved": "19.0.3", "contentHash": "kq9feqMojMj9aABrHb/ABEPaH2Y4dSclseSahAru6qxCeqVQNLLTgw/6vZMauzI1yBUL2fz03ub5yEd5btLfvg==" }, - "Google.Protobuf": { - "type": "Transitive", - "resolved": "3.7.0", - "contentHash": "OvssyqQTrpJgdH4fjztsCV9AhUo9jgGpDbZ5XAAqC+X6MIUsifHk8Woeom1HXlHdqo/XebiEMpYySE9AxybJ9g==", - "dependencies": { - "NETStandard.Library": "1.6.1" - } - }, "Menes.Abstractions": { "type": "Transitive", "resolved": "3.0.0-vnext.4", @@ -313,8 +296,8 @@ }, "Microsoft.ApplicationInsights": { "type": "Transitive", - "resolved": "2.19.0", - "contentHash": "QMs/5PVRyVv5T5G+UCtCCzSXjVR3WdcgeZqNhwtHCE+5k9S6mc+8pRE5WpsUsjgqwgNYES82bfQ6PsSu4YVPAA==", + "resolved": "2.20.0", + "contentHash": "mb+EC5j06Msn5HhKrhrsMAst6JxvYUnphQMGY2cixCabgGAO3q79Y8o/p1Zce1Azgd1IVkRKAMzAV4vDCbXOqA==", "dependencies": { "System.Diagnostics.DiagnosticSource": "5.0.0" } @@ -330,8 +313,8 @@ }, "Microsoft.AspNetCore.JsonPatch": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "SUiwg0XQ5NtmnELHXSdX4mAwawFnAOwSx2Zz6NIhQnEN1tZDoAWEHc8dS/S7y8cE52+9bHj+XbYZuLGF7OrQPA==", + "resolved": "6.0.1", + "contentHash": "vLgQbgudEQfGNaGyAvm+jlfLHu5Ynav8/RnhwM0QaKFjVW2crEOGm7tRHHjM5iofF8VZnEYfyvUvyK82dBej1w==", "dependencies": { "Microsoft.CSharp": "4.7.0", "Newtonsoft.Json": "13.0.1" @@ -380,8 +363,8 @@ }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "16.10.0", - "contentHash": "7g0UjAwhEi2OBBv8SDV3wZ6J103cQyZbKVgDy59fnNdlbv0XpUCfdBZiSW5yVK/d2jp6faCdGh7VnI/F2JZO+Q==" + "resolved": "16.11.0", + "contentHash": "wf6lpAeCqP0KFfbDVtfL50lr7jY1gq0+0oSphyksfLOEygMDXqnaxHK5LPFtMEhYSEtgXdNyXNnEddOqQQUdlQ==" }, "Microsoft.CSharp": { "type": "Transitive", @@ -420,20 +403,22 @@ }, "Microsoft.Extensions.Caching.Abstractions": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "NobDNbehAbMYUApMXLd9XSt9UznGCgPW9PW4Ybe6S5jKqkd5RcTnaKm0FODcgyx+7B1hIGx7dZwa1bVdiSbHAg==", + "resolved": "6.0.0", + "contentHash": "bcz5sSFJbganH0+YrfvIjJDIcKNW7TL07C4d1eTmXy/wOt52iz4LVogJb6pazs7W0+74j0YpXFErvp++Aq5Bsw==", "dependencies": { - "Microsoft.Extensions.Primitives": "2.0.0" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Caching.Memory": { "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "GVtJD0uhoLOkXBfYZAIRDexEr2qg0QHbUo3CIjmtoGpFWHuGHTvjGqRlybMKIYTpt0BxKpXMn4fqhS4ff10llA==", + "resolved": "6.0.0", + "contentHash": "Ve3BlCzhAlVp5IgO3+8dacAhZk1A0GlIlFNkAcfR2TfAibLKWIt5DhVJZfu4YtW+XZ89OjYf/agMcgjDtPxdGA==", "dependencies": { - "Microsoft.Extensions.Caching.Abstractions": "2.0.1", - "Microsoft.Extensions.DependencyInjection.Abstractions": "2.0.0", - "Microsoft.Extensions.Options": "2.0.1" + "Microsoft.Extensions.Caching.Abstractions": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Configuration.Abstractions": { @@ -466,10 +451,10 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "JAV97hx4y7qJ5mnjnUOSd+xDnMj2+51c8KVirhuU+rOW1LUnsmjhin86Tep6Q5tOHmNPOmmo6OHEFCdbZj5+zw==", + "resolved": "3.1.21", + "contentHash": "js24vxT9kzGfH7nc/EL9Yi2s5jQilFTxIYHIpX/oIEINVRW4qlnQXsfzsbXE5Y0BAG5TTidnfZ+IyOEsW9XTVA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { @@ -514,37 +499,37 @@ }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "/CuUfjdPd0X6upL/783pzJTSGLm1XTHlonKcRYi5oGVHuN0ESHRjWwmBvrAPf8TXXL901K9oyxJ9mtG9pTmF8Q==", + "resolved": "3.1.21", + "contentHash": "5D0RMBkH4eliNeR2a3VFV4stIer/CsFTeAGo2Uv1dm2X9Ttz8n0lbc7gl8+NogTiKfGm1RqoLF0HtH/1V4wxmw==", "dependencies": { - "Microsoft.Extensions.Configuration.Binder": "3.1.20", - "Microsoft.Extensions.DependencyInjection": "3.1.20", - "Microsoft.Extensions.Logging.Abstractions": "3.1.20", - "Microsoft.Extensions.Options": "3.1.20" + "Microsoft.Extensions.Configuration.Binder": "3.1.21", + "Microsoft.Extensions.DependencyInjection": "3.1.21", + "Microsoft.Extensions.Logging.Abstractions": "3.1.21", + "Microsoft.Extensions.Options": "3.1.21" } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "pejtJ+FM3tRm9Ssy9VO1PMkxlpkwbO+iQmK/Ot9DqgW3zjeLSQg3bEPI6klU70yoRSDwpiI8E71RdzU+vn/bTQ==" + "resolved": "6.0.0", + "contentHash": "/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==" }, "Microsoft.Extensions.Logging.Configuration": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "+k33hBevAq2hZi4tHnsQwtZDXAkD79MTntOvX5ID6kMgU6piqthMLMoK5uMJAh7vec8ORMhwSIkhjYaQ7wx4gw==", + "resolved": "3.1.21", + "contentHash": "E2rKFPOPAiDdPszCN0VWOpRoqZ0gBfIXkX5K9l93ZgK4z7RyqYDD/gqpF33bc0OZTjGovgItrZ/zHawazplMrA==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.20", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.20" + "Microsoft.Extensions.Logging": "3.1.21", + "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.21" } }, "Microsoft.Extensions.Logging.Console": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "v9GpjBR3YBNSnbNj1C4hQmRofUDpya1CgQwZo3IuXbun2JbSmHs1sVxuMyEh8sdU7Bo8gGyA3zdtEwE+16oiVA==", + "resolved": "3.1.21", + "contentHash": "wLKHCHAhQxBTwwznLySdLnJEmpo/l9+LeqEOrMNkHXfDu+Cx0cVX1U/m1PV2JJonpwEqeChE311OCLF+MZv1iA==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.Logging": "3.1.20", - "Microsoft.Extensions.Logging.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.Logging": "3.1.21", + "Microsoft.Extensions.Logging.Configuration": "3.1.21" } }, "Microsoft.Extensions.Options": { @@ -601,11 +586,11 @@ }, "Microsoft.NET.Test.Sdk": { "type": "Transitive", - "resolved": "16.10.0", - "contentHash": "/9x6TV1SUi+rtKi8UYa7ml7SEWhb0A5FuyeF0nwwUKVjdk5WaWuLPjntHVWoDuYP25KBruoxWxs7WdhDMjWxXw==", + "resolved": "16.11.0", + "contentHash": "f4mbG1SUSkNWF5p7B3Y8ZxMsvKhxCmpZhdl+w6tMtLSUGE7Izi1syU6TkmKOvB2BV66pdbENConFAISOix4ohQ==", "dependencies": { - "Microsoft.CodeCoverage": "16.10.0", - "Microsoft.TestPlatform.TestHost": "16.10.0" + "Microsoft.CodeCoverage": "16.11.0", + "Microsoft.TestPlatform.TestHost": "16.11.0" } }, "Microsoft.NETCore.Platforms": { @@ -642,8 +627,8 @@ }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", - "resolved": "16.10.0", - "contentHash": "DYp9eKg3zffZuePhgdUrh5tHkt1YOaSraVH87r4WXDOjag1/n08aFl1vRhWP8y2RoBLTHdcZRTDOhQyYMxAYNg==", + "resolved": "16.11.0", + "contentHash": "EiknJx9N9Z30gs7R+HHhki7fA8EiiM3pwD1vkw3bFsBC8kdVq/O7mHf1hrg5aJp+ASO6BoOzQueD2ysfTOy/Bg==", "dependencies": { "NuGet.Frameworks": "5.0.0", "System.Reflection.Metadata": "1.6.0" @@ -651,10 +636,10 @@ }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", - "resolved": "16.10.0", - "contentHash": "KAlB2QQRwznIH02WNl9eAuUP6/tn4IbAw4EXrvV1POTUjxuv4Dqg0u3Nn5lC9T3WIHupCHfsTcJMgsJYdi31Ig==", + "resolved": "16.11.0", + "contentHash": "/Q+R0EcCJE8JaYCk+bGReicw/xrB0HhecrYrUcLbn95BnAlaTJrZhoLkUhvtKTAVtqX/AIKWXYtutiU/Q6QUgg==", "dependencies": { - "Microsoft.TestPlatform.ObjectModel": "16.10.0", + "Microsoft.TestPlatform.ObjectModel": "16.11.0", "Newtonsoft.Json": "9.0.1" } }, @@ -888,11 +873,10 @@ }, "SpecFlow": { "type": "Transitive", - "resolved": "3.9.22", - "contentHash": "A3wZUoJaJjkll/Qvun8SJo7W869kO+1hm/FNkidNdnfbmOJA4Q8f0J80pr5wqIkKaYMQTRVvt18Y6HisgEZbUw==", + "resolved": "3.9.40", + "contentHash": "ru7twstJSKrTv3XfcxyttzrdZ/FvXOF5cYN/x/2js755wVk1zpSPUPa/ml3lSZmPNkS5OAOuSt1JLEa5hhDhdw==", "dependencies": { "BoDi": "1.5.0", - "Cucumber.Messages": "[6.0.1, 7.0.0)", "Gherkin": "19.0.3", "Microsoft.Extensions.DependencyModel": "1.0.3", "SpecFlow.Internal.Json": "1.0.8", @@ -908,30 +892,30 @@ }, "SpecFlow.NUnit": { "type": "Transitive", - "resolved": "3.9.22", - "contentHash": "o0d1zHMf9NcXLxXhG2NllWDnJCItKtDbpKyL5Kltf9AUYam7opvm3uFYG03WePnoPU9qgD+KLOM9IjNDZ4quaw==", + "resolved": "3.9.40", + "contentHash": "+brbJAe0LLzmXh2L78kOJc2fa5EH/7cugmbnfZQdBeWCzL6iFDWFl3MHZ0xx/2BQyu6N/xokqw53Rl30LIo7lw==", "dependencies": { "NUnit": "3.13.1", - "SpecFlow": "[3.9.22]", - "SpecFlow.Tools.MsBuild.Generation": "[3.9.22]" + "SpecFlow": "[3.9.40]", + "SpecFlow.Tools.MsBuild.Generation": "[3.9.40]" } }, "SpecFlow.NUnit.Runners": { "type": "Transitive", - "resolved": "3.9.22", - "contentHash": "cVQ49DWTyEqDYhiZjZSItkH0ALEVUBWvh7BOK5DCMzzsooid0EqNXWyrlzHk8OkzOmMDHs5JRmwqwe0biHZ5AA==", + "resolved": "3.9.40", + "contentHash": "vScntUGHtokExBWweUG9XOkjTum1B14lP4KU9T2rNW+gIGJBG99YmnR3/NMy4YMfASg5VkGJLx4icpZDYJENsQ==", "dependencies": { "NUnit.Console": "3.12.0", "NUnit3TestAdapter": "3.17.0", - "SpecFlow.NUnit": "[3.9.22]" + "SpecFlow.NUnit": "[3.9.40]" } }, "SpecFlow.Tools.MsBuild.Generation": { "type": "Transitive", - "resolved": "3.9.22", - "contentHash": "JrX8QY9mN+X5RUsjS2GY6l+eOAZ6S/sWiS6yi2+RxyyrvPmskQH7TYCm69dcNDefncXg/wZk3g/SE3VtjfdcVg==", + "resolved": "3.9.40", + "contentHash": "DFClKzQH0ijUBiZNpas8sQ66EdGwVSS18UtC1hVIM7PiT0F+xzKs4VX5hsz+ZY/RKyQEfY9HELUAC8AoZicxSg==", "dependencies": { - "SpecFlow": "[3.9.22]" + "SpecFlow": "[3.9.40]" } }, "System.AppContext": { @@ -944,8 +928,8 @@ }, "System.Buffers": { "type": "Transitive", - "resolved": "4.5.1", - "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + "resolved": "4.5.0", + "contentHash": "pL2ChpaRRWI/p4LXyy4RgeWlYF2sgfj/pnVMvBqwNFr5cXg7CXNnWZWxrOONLg8VGdFB8oB+EG2Qw4MLgTOe+A==" }, "System.CodeDom": { "type": "Transitive", @@ -1880,10 +1864,10 @@ "marain.tenancy.client": { "type": "Project", "dependencies": { - "CacheCow.Client": "2.8.3", + "CacheCow.Client": "2.9.0", "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Corvus.Identity.MicrosoftRest": "3.0.0-alpha.3", + "Corvus.Identity.MicrosoftRest": "3.0.0", "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", "Microsoft.Rest.ClientRuntime": "2.3.23" } @@ -1891,7 +1875,7 @@ "marain.tenancy.clienttenantprovider": { "type": "Project", "dependencies": { - "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", + "Corvus.Tenancy.Abstractions": "3.0.0", "Marain.Tenancy.Client": "1.0.0", "Microsoft.AspNetCore.WebUtilities": "2.2.0" } @@ -1906,9 +1890,9 @@ "marain.tenancy.openapi.service": { "type": "Project", "dependencies": { - "Corvus.Tenancy.Abstractions": "3.0.0-v3-blob.11", + "Corvus.Tenancy.Abstractions": "3.0.0", "Menes.Abstractions": "3.0.0-vnext.4", - "Microsoft.ApplicationInsights": "2.19.0", + "Microsoft.ApplicationInsights": "2.20.0", "Microsoft.AspNetCore.JsonPatch": "6.0.0", "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "6.0.0" diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs index d438f095..0507049d 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupDirectToStorage.cs @@ -31,13 +31,13 @@ internal class TenancyContainerSetupDirectToStorage : ITenancyContainerSetup { private static readonly Lazy Sha1 = new (() => SHA1.Create()); private readonly BlobContainerConfiguration configuration; - private readonly IBlobContainerSourceByConfiguration blobContainerSource; + private readonly IBlobContainerSourceFromDynamicConfiguration blobContainerSource; private readonly IPropertyBagFactory propertyBagFactory; private readonly JsonSerializer jsonSerializer; public TenancyContainerSetupDirectToStorage( BlobContainerConfiguration configuration, - IBlobContainerSourceByConfiguration blobContainerSource, + IBlobContainerSourceFromDynamicConfiguration blobContainerSource, IJsonSerializerSettingsProvider serializerSettingsProvider, IPropertyBagFactory propertyBagFactory) { @@ -139,7 +139,9 @@ private async Task GetBlobServiceClientAsync() // directly with the storage API to validate that it works when the storage account // wasn't previously populated by the current Corvus and Marain APIs. BlobContainerClient rootTenantContainerFromConfig = await this.blobContainerSource.GetStorageContextAsync( - this.configuration.ForContainer("dummy")); +#pragma warning disable SA1101 // Prefix local calls with this - StyleCop doesn't recognize records, or the with syntax yet + this.configuration with { Container = "dummy" }); +#pragma warning restore SA1101 // Prefix local calls with this return rootTenantContainerFromConfig.GetParentBlobServiceClient(); } } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs index 565a6064..c5bb6dfc 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenancyContainerSetupViaApi.cs @@ -25,12 +25,12 @@ internal class TenancyContainerSetupViaApi : ITenancyContainerSetup // Deferred tenant store fetching - it's important we don't try to use this before // we need it because it's not available until after the DI container has been built. private readonly Func getTenantStore; - private readonly IBlobContainerSourceByConfiguration blobContainerSource; + private readonly IBlobContainerSourceFromDynamicConfiguration blobContainerSource; public TenancyContainerSetupViaApi( BlobContainerConfiguration configuration, Func getTenantStore, - IBlobContainerSourceByConfiguration blobContainerSource) + IBlobContainerSourceFromDynamicConfiguration blobContainerSource) { this.configuration = configuration; this.getTenantStore = getTenantStore; @@ -136,7 +136,9 @@ private async Task GetBlobServiceClientAsync() // directly with the storage API to validate that it works when the storage account // wasn't previously populated by the current Corvus and Marain APIs. BlobContainerClient rootTenantContainerFromConfig = await this.blobContainerSource.GetStorageContextAsync( - this.configuration.ForContainer("dummy")); +#pragma warning disable SA1101 // Prefix local calls with this - StyleCop doesn't recognize records, or the with syntax yet + this.configuration with { Container = "dummy" }); +#pragma warning restore SA1101 // Prefix local calls with this return rootTenantContainerFromConfig.GetParentBlobServiceClient(); } } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs index 61cba2a5..868b7170 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs @@ -32,10 +32,10 @@ public TenantSetupSteps(TenantProperties tenantProperties) SetupModes.ViaApiPropagateRootConfigAsV2 or SetupModes.ViaApiPropagateRootConfigAsV3 => new TenancyContainerSetupViaApi( this.DiContainer.RootBlobStorageConfiguration, () => this.TenantStore, - this.DiContainer.ServiceProvider.GetRequiredService()), + this.DiContainer.ServiceProvider.GetRequiredService()), SetupModes.DirectToStoragePropagateRootConfigAsV2 or SetupModes.DirectToStoragePropagateRootConfigAsV3 => new TenancyContainerSetupDirectToStorage( this.DiContainer.RootBlobStorageConfiguration, - this.DiContainer.ServiceProvider.GetRequiredService(), + this.DiContainer.ServiceProvider.GetRequiredService(), this.DiContainer.ServiceProvider.GetRequiredService(), this.DiContainer.ServiceProvider.GetRequiredService()), _ => throw new InvalidOperationException($"Unknown setup mode: {this.SetupMode}"), diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj index ce9a7f1b..42ce1480 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Marain.Tenancy.Storage.Azure.BlobStorage.Specs.csproj @@ -39,7 +39,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json index 399a74e3..e37b57c7 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/packages.lock.json @@ -4,14 +4,14 @@ "net6.0": { "Corvus.Testing.AzureFunctions.SpecFlow.NUnit": { "type": "Direct", - "requested": "[1.4.6, )", - "resolved": "1.4.6", - "contentHash": "/8bUlkeVbPRcdtPCdvPfa00HtJbcZtXj89dk6biXK1s2shCntbQQWW9N3t31hARMFOen6F/ViHVWW4Ok+Yh6Pw==", + "requested": "[1.4.7, )", + "resolved": "1.4.7", + "contentHash": "u3SWrAnIlr54LIogoRJNDuEuE0bQ7UpYGmsaXEDWUopMxAFuOdw1nerNoQbumtMrLtOU4ETBnC7plJhVsvAGVg==", "dependencies": { - "Corvus.Testing.AzureFunctions.SpecFlow": "1.4.6", - "Microsoft.NET.Test.Sdk": "[16.10.0, 17.0.0)", + "Corvus.Testing.AzureFunctions.SpecFlow": "1.4.7", + "Microsoft.NET.Test.Sdk": "16.11.0", "Moq": "4.16.1", - "SpecFlow.NUnit.Runners": "3.9.22", + "SpecFlow.NUnit.Runners": "3.9.40", "coverlet.msbuild": "3.1.0" } }, @@ -83,32 +83,30 @@ }, "Azure.Core": { "type": "Transitive", - "resolved": "1.19.0", - "contentHash": "lcDjG635DPE4fU5tqSueVMmzrx0QrIfPuY0+y6evHN5GanQ0GB+/4nuMHMmoNPwEow6OUPkJu4cZQxfHJQXPdA==", + "resolved": "1.20.0", + "contentHash": "q7xigZIBjLjSKJA/Y+VygmJ2iZGiEyNuicN5iRX9oJL7451SulZm/CQ7qd8YCeL5TgNCNYCIrTIqRaams95zHA==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "1.0.0", - "System.Buffers": "4.5.1", "System.Diagnostics.DiagnosticSource": "4.6.0", - "System.Memory": "4.5.4", "System.Memory.Data": "1.0.2", "System.Numerics.Vectors": "4.5.0", "System.Text.Encodings.Web": "4.7.2", "System.Text.Json": "4.6.0", - "System.Threading.Tasks.Extensions": "4.5.2" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Azure.Identity": { "type": "Transitive", - "resolved": "1.4.1", - "contentHash": "yuxWej20CUtK2HUU4jm9Vft1wPw2NWKpwS9Zr0hJyph0dp7vgihlzlujR26UdhmvgdMdswsFRZL+k0HcaS07tw==", + "resolved": "1.5.0", + "contentHash": "VfF88dqrgKXZNOS/y4XrX/jmIfP3pkY+hBUzBNpoKml1nR+QshX6XlXWyToLtWV80TDQ1CmUVCJksktDg5+j1w==", "dependencies": { - "Azure.Core": "1.17.0", + "Azure.Core": "1.20.0", "Microsoft.Identity.Client": "4.30.1", "Microsoft.Identity.Client.Extensions.Msal": "2.18.4", "System.Memory": "4.5.4", "System.Security.Cryptography.ProtectedData": "4.5.0", "System.Text.Json": "4.6.0", - "System.Threading.Tasks.Extensions": "4.5.2" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Azure.Security.KeyVault.Secrets": { @@ -201,18 +199,19 @@ }, "Corvus.Identity.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-identity-configuration.3", - "contentHash": "wLZih7d7jz6WoDjVHMrLzxM72GqF88g3n7JOGLpPbTbu+Q7Qekc9sSSM8PBFjVyURaQwuk/Xq/cyj3hKIFDRkQ==" + "resolved": "3.0.0", + "contentHash": "fGYhKMz/n1Ejv77r+0bmzdC9EW3sCfZ3P8dky6rrOEGK4Kijd9yjTwoFEaG9ZHPXu5C7r2O2VqpesgIDkn5iQA==" }, "Corvus.Identity.Azure": { "type": "Transitive", - "resolved": "3.0.0-identity-configuration.3", - "contentHash": "r3d24icyK7g07cvaiIymJxwL5S6te77sHFBFZb5XRGRqUzsLePBbccmW4G2x3zb1efvduObR0Uh32tqmiDZy8A==", + "resolved": "3.0.0", + "contentHash": "TYNTb4CD0pyn9WX4gC8TFGTU0v4inAkVEEG9xCyASgpp0ahMlL8RUfgQAwKZqr6yJ+tHpdjlx02mHJeSWidSiA==", "dependencies": { - "Azure.Identity": "1.4.1", + "Azure.Identity": "1.5.0", "Azure.Security.KeyVault.Secrets": "4.2.0", - "Corvus.Identity.Abstractions": "3.0.0-identity-configuration.3", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" + "Corvus.Identity.Abstractions": "3.0.0", + "Microsoft.Extensions.Caching.Memory": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0" } }, "Corvus.Json.Abstractions": { @@ -222,73 +221,72 @@ }, "Corvus.Storage.Azure.BlobStorage": { "type": "Transitive", - "resolved": "3.0.0-1-refactor-from-tenancy.10", - "contentHash": "xzy+Z5ZzpJ4GEh2MxQ4IlufXtosjwcY1Tk0Xg8SyQ2ktVHLWbly2emkEqiESFjVLUoM3sNVqd46eqflP6eXkqw==", + "resolved": "1.0.0", + "contentHash": "jskZtDcYc5DJySAMwKkbcMKW5zJvaVOZdRfCmRoruk8yJvGxgJ92MhsdXmUSBOgvq7zC0CkOS0bF18WAgt6Tnw==", "dependencies": { "Azure.Storage.Blobs": "12.10.0", - "Corvus.Storage.Common": "3.0.0-1-refactor-from-tenancy.10" + "Corvus.Storage.Common": "1.0.0" } }, "Corvus.Storage.Azure.BlobStorage.Tenancy": { "type": "Transitive", - "resolved": "3.0.0-alpha.3", - "contentHash": "aQ/WtonoXdEtJbnx5H9++LyOQscxdsOLR7B6u4SIWYsNqq3Lsxb9GNmVN2OVh3TaaMPoLCKVUEUUKd2Sp/t/Rg==", + "resolved": "3.0.0", + "contentHash": "20CJow+8yGU74wvZaSyxt3TiGxrxEPbqTohNvWIW50kCG+MOLbaN1PaKszcwgX5yCLb3sCo8C/LqCKO0E47Ckg==", "dependencies": { - "Corvus.Storage.Azure.BlobStorage": "3.0.0-1-refactor-from-tenancy.10", - "Corvus.Tenancy.Abstractions": "3.0.0-alpha.3" + "Corvus.Storage.Azure.BlobStorage": "1.0.0", + "Corvus.Tenancy.Abstractions": "3.0.0" } }, "Corvus.Storage.Common": { "type": "Transitive", - "resolved": "3.0.0-1-refactor-from-tenancy.10", - "contentHash": "bDirPOYtbvitnSB9efYfiwfJsc/mI9ObP6qa5zAQvwzWHxUPGqY5o82AWKRk/7ADmWw26B1kzmyZGFWF4eY8jw==", + "resolved": "1.0.0", + "contentHash": "JF5H73X+s9MvJODJZ69ajbLBqPOUpBLaPYkEUO5SIsSvu+suRoOrkqmDnc8EKUFOutdq5jC9PsfLBbV0v6eaNw==", "dependencies": { - "Azure.Security.KeyVault.Secrets": "4.2.0", - "Corvus.Identity.Azure": "3.0.0-identity-configuration.3", - "Microsoft.Extensions.Configuration.Binder": "3.1.21" + "Corvus.Identity.Azure": "3.0.0", + "Microsoft.Extensions.Configuration.Binder": "3.1.22" } }, "Corvus.Tenancy.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-alpha.3", - "contentHash": "YsPXYMqVXydyZp9I28bwFZV9cjA5XUJIHInw8iN/WVHUegPYr0rrP38PltqnPLn6cLnInEA9Ge4NMUM9EUFa3A==", + "resolved": "3.0.0", + "contentHash": "pDCUxkUHTCE0fywCBmNnTjoBofrY5wo3IMfEvuCws2T6gi823UpwHWqWOJLhc8xxw8Br4tX1FWuSOVx2DFAHyA==", "dependencies": { "Corvus.ContentHandling.Json": "2.0.11", "Corvus.Extensions": "1.1.4", - "Microsoft.Extensions.Primitives": "3.1.21" + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Corvus.Testing.AzureFunctions": { "type": "Transitive", - "resolved": "1.4.6", - "contentHash": "dOoUYwj72I23Egq+FVd5kq+hP2zgw1VdJX1FHoz0ls5n7eBTt9YXHe4rsjNvEZzmQMN1cDv7zoBXX1jGiIB1dg==", + "resolved": "1.4.7", + "contentHash": "Q/qDg0sJ80B/phIrj8/XMcMQgFifpfb27VVb7WyUjZNrJ/uNG8nDj1m5OXyU2tkv7YSgcfiP/6WZk2fraYqM7Q==", "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "3.1.20", + "Microsoft.Extensions.Logging.Abstractions": "3.1.21", "System.Management": "4.7.0" } }, "Corvus.Testing.AzureFunctions.SpecFlow": { "type": "Transitive", - "resolved": "1.4.6", - "contentHash": "kNwjluoe+fTid58d2YOGCgYbw3eWRqItC8HQ5N4rGsl4ZjuG1IOeFP/zjCG96NllRRVDRYoNguEQIregT04bnQ==", + "resolved": "1.4.7", + "contentHash": "0UBYNU+Cbj4XYpUm3RLR8UjNfCO4IGsjps+uD1Cvg4nGib0db8qQOqcgnNj9wq9nacYY+ZYZWO/64xUlXrRFrg==", "dependencies": { - "Corvus.Testing.AzureFunctions": "1.4.6", - "Corvus.Testing.SpecFlow": "1.4.6", - "Microsoft.Extensions.Logging.Console": "3.1.20", + "Corvus.Testing.AzureFunctions": "1.4.7", + "Corvus.Testing.SpecFlow": "1.4.7", + "Microsoft.Extensions.Logging.Console": "3.1.21", "NUnit": "3.13.2", - "SpecFlow": "3.9.22" + "SpecFlow": "3.9.40" } }, "Corvus.Testing.SpecFlow": { "type": "Transitive", - "resolved": "1.4.6", - "contentHash": "EmakRYEWtLqOXJXV8vOq4bOikivszKcclnRClM65IULefSCY1Cm+pP5wvJusetZWRQ7xXjvI9Hzp25T1MJmVBQ==", + "resolved": "1.4.7", + "contentHash": "qGqOQt/9x95MOmUyA57JgNmdWRF1lgKjYEjU9IXw3ElMYs5S93I0qHiqBdQCIDq8qHxkXgo6cnDIJsrBLCrReQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.DependencyInjection": "3.1.20", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.DependencyInjection": "3.1.21", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", "NUnit": "3.13.2", - "SpecFlow": "3.9.22", + "SpecFlow": "3.9.40", "System.Management": "4.7.0" } }, @@ -297,27 +295,11 @@ "resolved": "3.1.0", "contentHash": "xOv5HZagq0I6uF4vt8NVVpwcA2W/uGmNcbLStao2eMk98RQH5NFPQuouh2nWWPSZrNIhGG/iYbBn2pO4s5i+ig==" }, - "Cucumber.Messages": { - "type": "Transitive", - "resolved": "6.0.1", - "contentHash": "R/2XAU6Zwdnlgga/YLYxwbKf4ai0JYyeX25l85t0nNgagR2aP8hnqrLtJjgswuXVa2WlQdjXUfJqUX8YTjzlXw==", - "dependencies": { - "Google.Protobuf": "3.7.0" - } - }, "Gherkin": { "type": "Transitive", "resolved": "19.0.3", "contentHash": "kq9feqMojMj9aABrHb/ABEPaH2Y4dSclseSahAru6qxCeqVQNLLTgw/6vZMauzI1yBUL2fz03ub5yEd5btLfvg==" }, - "Google.Protobuf": { - "type": "Transitive", - "resolved": "3.7.0", - "contentHash": "OvssyqQTrpJgdH4fjztsCV9AhUo9jgGpDbZ5XAAqC+X6MIUsifHk8Woeom1HXlHdqo/XebiEMpYySE9AxybJ9g==", - "dependencies": { - "NETStandard.Library": "1.6.1" - } - }, "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", "resolved": "1.0.0", @@ -357,8 +339,8 @@ }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "16.10.0", - "contentHash": "7g0UjAwhEi2OBBv8SDV3wZ6J103cQyZbKVgDy59fnNdlbv0XpUCfdBZiSW5yVK/d2jp6faCdGh7VnI/F2JZO+Q==" + "resolved": "16.11.0", + "contentHash": "wf6lpAeCqP0KFfbDVtfL50lr7jY1gq0+0oSphyksfLOEygMDXqnaxHK5LPFtMEhYSEtgXdNyXNnEddOqQQUdlQ==" }, "Microsoft.DotNet.InternalAbstractions": { "type": "Transitive", @@ -390,6 +372,26 @@ "System.Runtime.InteropServices.RuntimeInformation": "4.0.0" } }, + "Microsoft.Extensions.Caching.Abstractions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "bcz5sSFJbganH0+YrfvIjJDIcKNW7TL07C4d1eTmXy/wOt52iz4LVogJb6pazs7W0+74j0YpXFErvp++Aq5Bsw==", + "dependencies": { + "Microsoft.Extensions.Primitives": "6.0.0" + } + }, + "Microsoft.Extensions.Caching.Memory": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Ve3BlCzhAlVp5IgO3+8dacAhZk1A0GlIlFNkAcfR2TfAibLKWIt5DhVJZfu4YtW+XZ89OjYf/agMcgjDtPxdGA==", + "dependencies": { + "Microsoft.Extensions.Caching.Abstractions": "6.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Microsoft.Extensions.Options": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" + } + }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", "resolved": "6.0.0", @@ -412,10 +414,10 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "JAV97hx4y7qJ5mnjnUOSd+xDnMj2+51c8KVirhuU+rOW1LUnsmjhin86Tep6Q5tOHmNPOmmo6OHEFCdbZj5+zw==", + "resolved": "3.1.21", + "contentHash": "js24vxT9kzGfH7nc/EL9Yi2s5jQilFTxIYHIpX/oIEINVRW4qlnQXsfzsbXE5Y0BAG5TTidnfZ+IyOEsW9XTVA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { @@ -460,57 +462,57 @@ }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "/CuUfjdPd0X6upL/783pzJTSGLm1XTHlonKcRYi5oGVHuN0ESHRjWwmBvrAPf8TXXL901K9oyxJ9mtG9pTmF8Q==", + "resolved": "3.1.21", + "contentHash": "5D0RMBkH4eliNeR2a3VFV4stIer/CsFTeAGo2Uv1dm2X9Ttz8n0lbc7gl8+NogTiKfGm1RqoLF0HtH/1V4wxmw==", "dependencies": { - "Microsoft.Extensions.Configuration.Binder": "3.1.20", - "Microsoft.Extensions.DependencyInjection": "3.1.20", - "Microsoft.Extensions.Logging.Abstractions": "3.1.20", - "Microsoft.Extensions.Options": "3.1.20" + "Microsoft.Extensions.Configuration.Binder": "3.1.21", + "Microsoft.Extensions.DependencyInjection": "3.1.21", + "Microsoft.Extensions.Logging.Abstractions": "3.1.21", + "Microsoft.Extensions.Options": "3.1.21" } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "pejtJ+FM3tRm9Ssy9VO1PMkxlpkwbO+iQmK/Ot9DqgW3zjeLSQg3bEPI6klU70yoRSDwpiI8E71RdzU+vn/bTQ==" + "resolved": "6.0.0", + "contentHash": "/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==" }, "Microsoft.Extensions.Logging.Configuration": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "+k33hBevAq2hZi4tHnsQwtZDXAkD79MTntOvX5ID6kMgU6piqthMLMoK5uMJAh7vec8ORMhwSIkhjYaQ7wx4gw==", + "resolved": "3.1.21", + "contentHash": "E2rKFPOPAiDdPszCN0VWOpRoqZ0gBfIXkX5K9l93ZgK4z7RyqYDD/gqpF33bc0OZTjGovgItrZ/zHawazplMrA==", "dependencies": { - "Microsoft.Extensions.Logging": "3.1.20", - "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.20" + "Microsoft.Extensions.Logging": "3.1.21", + "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.21" } }, "Microsoft.Extensions.Logging.Console": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "v9GpjBR3YBNSnbNj1C4hQmRofUDpya1CgQwZo3IuXbun2JbSmHs1sVxuMyEh8sdU7Bo8gGyA3zdtEwE+16oiVA==", + "resolved": "3.1.21", + "contentHash": "wLKHCHAhQxBTwwznLySdLnJEmpo/l9+LeqEOrMNkHXfDu+Cx0cVX1U/m1PV2JJonpwEqeChE311OCLF+MZv1iA==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.Logging": "3.1.20", - "Microsoft.Extensions.Logging.Configuration": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.Logging": "3.1.21", + "Microsoft.Extensions.Logging.Configuration": "3.1.21" } }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "K5h3xUrYP8mbGZeGAm/vcWjol2wBh2V1vV+Vz02DCKlZ/99Y8ecKJwdpH+elfdqcEFXy76jk+I1nBsmhPKeCgw==", + "resolved": "6.0.0", + "contentHash": "dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", - "Microsoft.Extensions.Primitives": "3.1.20" + "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", + "Microsoft.Extensions.Primitives": "6.0.0" } }, "Microsoft.Extensions.Options.ConfigurationExtensions": { "type": "Transitive", - "resolved": "3.1.20", - "contentHash": "vmh27AY00NDg6+4P5NbLnhKsrNMBtfcFAoE0Pim7yNAB46ev44vu2O5a3AINUoRl9Kovik72Wgn8qA4IpQu+vg==", + "resolved": "3.1.21", + "contentHash": "8SXTqWPYOYdM0O51/cB7wzVsqFemCGMbcHb82Ix5bmsHO8stcb7YKXERiQ18JSigVogb828gCTK8gMfiSGO4ug==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "3.1.20", - "Microsoft.Extensions.Configuration.Binder": "3.1.20", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", - "Microsoft.Extensions.Options": "3.1.20" + "Microsoft.Extensions.Configuration.Abstractions": "3.1.21", + "Microsoft.Extensions.Configuration.Binder": "3.1.21", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21", + "Microsoft.Extensions.Options": "3.1.21" } }, "Microsoft.Extensions.Primitives": { @@ -537,11 +539,11 @@ }, "Microsoft.NET.Test.Sdk": { "type": "Transitive", - "resolved": "16.10.0", - "contentHash": "/9x6TV1SUi+rtKi8UYa7ml7SEWhb0A5FuyeF0nwwUKVjdk5WaWuLPjntHVWoDuYP25KBruoxWxs7WdhDMjWxXw==", + "resolved": "16.11.0", + "contentHash": "f4mbG1SUSkNWF5p7B3Y8ZxMsvKhxCmpZhdl+w6tMtLSUGE7Izi1syU6TkmKOvB2BV66pdbENConFAISOix4ohQ==", "dependencies": { - "Microsoft.CodeCoverage": "16.10.0", - "Microsoft.TestPlatform.TestHost": "16.10.0" + "Microsoft.CodeCoverage": "16.11.0", + "Microsoft.TestPlatform.TestHost": "16.11.0" } }, "Microsoft.NETCore.Platforms": { @@ -570,8 +572,8 @@ }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", - "resolved": "16.10.0", - "contentHash": "DYp9eKg3zffZuePhgdUrh5tHkt1YOaSraVH87r4WXDOjag1/n08aFl1vRhWP8y2RoBLTHdcZRTDOhQyYMxAYNg==", + "resolved": "16.11.0", + "contentHash": "EiknJx9N9Z30gs7R+HHhki7fA8EiiM3pwD1vkw3bFsBC8kdVq/O7mHf1hrg5aJp+ASO6BoOzQueD2ysfTOy/Bg==", "dependencies": { "NuGet.Frameworks": "5.0.0", "System.Reflection.Metadata": "1.6.0" @@ -579,10 +581,10 @@ }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", - "resolved": "16.10.0", - "contentHash": "KAlB2QQRwznIH02WNl9eAuUP6/tn4IbAw4EXrvV1POTUjxuv4Dqg0u3Nn5lC9T3WIHupCHfsTcJMgsJYdi31Ig==", + "resolved": "16.11.0", + "contentHash": "/Q+R0EcCJE8JaYCk+bGReicw/xrB0HhecrYrUcLbn95BnAlaTJrZhoLkUhvtKTAVtqX/AIKWXYtutiU/Q6QUgg==", "dependencies": { - "Microsoft.TestPlatform.ObjectModel": "16.10.0", + "Microsoft.TestPlatform.ObjectModel": "16.11.0", "Newtonsoft.Json": "9.0.1" } }, @@ -799,11 +801,10 @@ }, "SpecFlow": { "type": "Transitive", - "resolved": "3.9.22", - "contentHash": "A3wZUoJaJjkll/Qvun8SJo7W869kO+1hm/FNkidNdnfbmOJA4Q8f0J80pr5wqIkKaYMQTRVvt18Y6HisgEZbUw==", + "resolved": "3.9.40", + "contentHash": "ru7twstJSKrTv3XfcxyttzrdZ/FvXOF5cYN/x/2js755wVk1zpSPUPa/ml3lSZmPNkS5OAOuSt1JLEa5hhDhdw==", "dependencies": { "BoDi": "1.5.0", - "Cucumber.Messages": "[6.0.1, 7.0.0)", "Gherkin": "19.0.3", "Microsoft.Extensions.DependencyModel": "1.0.3", "SpecFlow.Internal.Json": "1.0.8", @@ -819,30 +820,30 @@ }, "SpecFlow.NUnit": { "type": "Transitive", - "resolved": "3.9.22", - "contentHash": "o0d1zHMf9NcXLxXhG2NllWDnJCItKtDbpKyL5Kltf9AUYam7opvm3uFYG03WePnoPU9qgD+KLOM9IjNDZ4quaw==", + "resolved": "3.9.40", + "contentHash": "+brbJAe0LLzmXh2L78kOJc2fa5EH/7cugmbnfZQdBeWCzL6iFDWFl3MHZ0xx/2BQyu6N/xokqw53Rl30LIo7lw==", "dependencies": { "NUnit": "3.13.1", - "SpecFlow": "[3.9.22]", - "SpecFlow.Tools.MsBuild.Generation": "[3.9.22]" + "SpecFlow": "[3.9.40]", + "SpecFlow.Tools.MsBuild.Generation": "[3.9.40]" } }, "SpecFlow.NUnit.Runners": { "type": "Transitive", - "resolved": "3.9.22", - "contentHash": "cVQ49DWTyEqDYhiZjZSItkH0ALEVUBWvh7BOK5DCMzzsooid0EqNXWyrlzHk8OkzOmMDHs5JRmwqwe0biHZ5AA==", + "resolved": "3.9.40", + "contentHash": "vScntUGHtokExBWweUG9XOkjTum1B14lP4KU9T2rNW+gIGJBG99YmnR3/NMy4YMfASg5VkGJLx4icpZDYJENsQ==", "dependencies": { "NUnit.Console": "3.12.0", "NUnit3TestAdapter": "3.17.0", - "SpecFlow.NUnit": "[3.9.22]" + "SpecFlow.NUnit": "[3.9.40]" } }, "SpecFlow.Tools.MsBuild.Generation": { "type": "Transitive", - "resolved": "3.9.22", - "contentHash": "JrX8QY9mN+X5RUsjS2GY6l+eOAZ6S/sWiS6yi2+RxyyrvPmskQH7TYCm69dcNDefncXg/wZk3g/SE3VtjfdcVg==", + "resolved": "3.9.40", + "contentHash": "DFClKzQH0ijUBiZNpas8sQ66EdGwVSS18UtC1hVIM7PiT0F+xzKs4VX5hsz+ZY/RKyQEfY9HELUAC8AoZicxSg==", "dependencies": { - "SpecFlow": "[3.9.22]" + "SpecFlow": "[3.9.40]" } }, "System.AppContext": { @@ -853,11 +854,6 @@ "System.Runtime": "4.1.0" } }, - "System.Buffers": { - "type": "Transitive", - "resolved": "4.5.1", - "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" - }, "System.CodeDom": { "type": "Transitive", "resolved": "4.7.0", @@ -1783,7 +1779,7 @@ "marain.tenancy.storage.azure.blobstorage": { "type": "Project", "dependencies": { - "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0-alpha.3", + "Corvus.Storage.Azure.BlobStorage.Tenancy": "3.0.0", "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0" } } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj index e6dcb701..ce8ec9b1 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain.Tenancy.Storage.Azure.BlobStorage.csproj @@ -16,7 +16,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Microsoft/Extensions/DependencyInjection/TenancyBlobStorageServiceCollectionExtensions.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Microsoft/Extensions/DependencyInjection/TenancyBlobStorageServiceCollectionExtensions.cs index f1bf9995..8bd13500 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Microsoft/Extensions/DependencyInjection/TenancyBlobStorageServiceCollectionExtensions.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Microsoft/Extensions/DependencyInjection/TenancyBlobStorageServiceCollectionExtensions.cs @@ -65,19 +65,8 @@ public static IServiceCollection AddTenantStoreOnAzureBlobStorage( BlobContainerConfiguration rootStorageConfiguration, bool propagateRootTenancyStorageConfigAsV2 = false) { - services.AddAzureBlobStorageClient(); - - // TODO: this next one is temporary. - // Corvus.Storage.Azure.BlobStorage.Tenancy should offer some successor to - // AddTenantCloudBlobContainerFactory, but since it currently only offers the - // transitional API (there is not yet an implementation of a native-v3 API) - // that hasn't been written yet, and so we need to call this bootstrapper - // in the Corvus.Tenancy.Internal namespace. - services.AddRequiredTenancyServices(); - - // TODO: This probably should also be called by Corvus.Storage.Azure.BlobStorage.Tenancy - services.AddAzureBlobStorageClient(); - + services.AddAzureBlobStorageClientSourceFromDynamicConfiguration(); + services.AddTenantBlobContainerFactory(); services.AddBlobContainerV2ToV3Transition(); services.AddSingleton(new AzureBlobStorageTenantStoreConfiguration( rootStorageConfiguration, From 1c30264afd1804ed28613c52aa98297492adc1e6 Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Fri, 17 Dec 2021 17:12:58 +0000 Subject: [PATCH 08/10] Add more tenant blob store tests (#364) * Add more tenant blob store tests * Removed preview ref from pipeline * Fix test problems around well-known container recreation --- .../Bindings/TenantProperties.cs | 3 + .../Bindings/TenantSetupSteps.cs | 21 ++++-- .../Bindings/TenantStepsBase.cs | 2 + .../Features/CreateTenant.feature | 39 ++++++----- .../Features/DeleteTenant.feature | 46 +++++++++++-- .../Features/RenameTenant.feature | 31 +++++++-- .../StepDefinitions/CreateTenantSteps.cs | 20 +++--- .../StepDefinitions/DeleteTenantSteps.cs | 66 ++++++++++++++++++- .../StepDefinitions/GetTenantSteps.cs | 17 ++++- .../StepDefinitions/RenameTenantSteps.cs | 60 ++++++++++++++++- .../AzureBlobStorageTenantStore.cs | 10 +++ azure-pipelines.yml | 1 - 12 files changed, 272 insertions(+), 44 deletions(-) diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantProperties.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantProperties.cs index c8071655..b42111a6 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantProperties.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantProperties.cs @@ -4,6 +4,7 @@ namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings { + using System; using System.Collections.Generic; using Corvus.Tenancy; @@ -17,6 +18,8 @@ public TenantProperties(ScenarioDiContainer diContainer) public Dictionary Tenants { get; } = new Dictionary(); + public Dictionary WellKnownGuids { get; } = new (); + public HashSet TenantsToDelete { get; } = new HashSet(); public HashSet WellKnownTenantsToDelete { get; } = new HashSet(); diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs index 868b7170..2955dbe7 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantSetupSteps.cs @@ -5,7 +5,9 @@ namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings { using System; + using System.Collections.Generic; using System.Linq; + using System.Security; using System.Threading.Tasks; using Corvus.Extensions.Json; @@ -72,10 +74,20 @@ public async Task GivenTheRootTenantHasAChildTenantWithPropertiesCalled( this.AddTenantToDelete(newTenant.Id); } - [Given("the root tenant has a well-known child tenant called '([^']*)' with a Guid of '([^']*)' labelled '([^']*)'")] + [Given("a well-known tenant Guid labelled '([^']*)'")] + public void GivenAWell_KnownTenantGuidLabelled(string label) + { + // We need "well-known" ids to be different each time we run the test, because + // otherwise, we fall foul of Azure Storage's inability to create a container + // with the same name as a container you recently deleted. + this.WellKnownGuids.Add(label, Guid.NewGuid()); + } + + [Given(@"the root tenant has a well-known \(from the Guid labelled '([^']*)'\) child tenant called '([^']*)' labelled '([^']*)'")] public async Task GivenTheRootTenantHasAWellKnownChildTenantCalled( - string tenantName, Guid wellKnownId, string tenantLabel) + string wellKnownGuidLabel, string tenantName, string tenantLabel) { + Guid wellKnownId = this.WellKnownGuids[wellKnownGuidLabel]; ITenant newTenant = await this.containerSetup.EnsureWellKnownChildTenantExistsAsync( RootTenant.RootTenantId, wellKnownId, tenantName, this.PropagateRootTenancyStorageConfigAsV2); this.Tenants.Add(tenantLabel, newTenant); @@ -94,10 +106,11 @@ public async Task GivenTheRootTenantHasAChildTenantCalled( this.AddTenantToDelete(newTenant.Id); } - [Given("the tenant labelled '([^']*)' has a well-known child tenant called '([^']*)' with a Guid of '([^']*)' labelled '([^']*)'")] + [Given(@"the tenant labelled '([^']*)' has a well-known \(from the Guid labelled '([^']*)'\) child tenant called '([^']*)' labelled '([^']*)'")] public async Task GivenTheRootTenantHasAChildTenantCalled( - string parentTenantLabel, string tenantName, Guid wellKnownId, string newTenantLabel) + string parentTenantLabel, string wellKnownGuidLabel, string tenantName, string newTenantLabel) { + Guid wellKnownId = this.WellKnownGuids[wellKnownGuidLabel]; ITenant parent = this.Tenants[parentTenantLabel]; ITenant newTenant = await this.containerSetup.EnsureWellKnownChildTenantExistsAsync( parent.Id, wellKnownId, tenantName, this.PropagateRootTenancyStorageConfigAsV2); diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantStepsBase.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantStepsBase.cs index f5644e17..9ddc8009 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantStepsBase.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Bindings/TenantStepsBase.cs @@ -29,6 +29,8 @@ public TenantStepsBase(TenantProperties tenantProperties) public HashSet TenantsToDelete => this.tenantProperties.TenantsToDelete; + public Dictionary WellKnownGuids => this.tenantProperties.WellKnownGuids; + public HashSet WellKnownTenantsToDelete => this.tenantProperties.WellKnownTenantsToDelete; public ITenantStore TenantStore => this.DiContainer.TenantStore; diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature index 956dcd7e..b318ed80 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/CreateTenant.feature @@ -14,10 +14,11 @@ Scenario: Create a child of the root tenant And the tenant labelled 'ChildTenant' should have storage configuration equivalent to the root Scenario: Create a child of the root tenant with a well known Id - When I create a well known child tenant of the root tenant called 'ChildTenant1' with a Guid of 'F446F305-993B-49A4-B5FA-010EE2AF0FA2' labelled 'ChildTenant' + Given a well-known tenant Guid labelled 'WellKnown1' + When I create a well known (from the Guid labelled 'WellKnown1') child tenant of the root tenant called 'ChildTenant1' labelled 'ChildTenant' And I get the tenant with the id from label 'ChildTenant' labelled 'Result' Then the tenant details labelled 'ChildTenant' should match the tenant details labelled 'Result' - And the tenant details labelled 'ChildTenant' should have tenant Id '05f346f43b99a449b5fa010ee2af0fa2' + And the tenant details labelled 'ChildTenant' should have tenant Id that is the hash of the Guid labelled 'WellKnown1' And the tenant labelled 'ChildTenant' should have storage configuration equivalent to the root Scenario: Create a child of a child of the root tenant @@ -28,28 +29,36 @@ Scenario: Create a child of a child of the root tenant And the tenant labelled 'Tenant2' should have storage configuration equivalent to the root Scenario: Create a child of a child with well known Ids - Given the root tenant has a well-known child tenant called 'ChildTenant1' with a Guid of 'EE17B20B-B372-4493-8145-9DD95516B9AF' labelled 'Tenant1' - When I create a well known child of the tenant labelled 'Tenant1' named 'ChildTenant2' with a Guid of 'DD045C05-E7FB-4214-8878-F9E7CA9B0F5F' labelled 'Tenant2' + Given a well-known tenant Guid labelled 'WellKnown1' + And a well-known tenant Guid labelled 'WellKnown2' + And the root tenant has a well-known (from the Guid labelled 'WellKnown1') child tenant called 'ChildTenant1' labelled 'Tenant1' + When I create a well known (from the Guid labelled 'WellKnown2') child of the tenant labelled 'Tenant1' named 'ChildTenant2' labelled 'Tenant2' And I get the tenant with the id from label 'Tenant2' labelled 'Result' Then the tenant details labelled 'Tenant2' should match the tenant details labelled 'Result' - And the tenant details labelled 'Tenant1' should have tenant Id '0bb217ee72b3934481459dd95516b9af' - And the tenant details labelled 'Tenant2' should have tenant Id '0bb217ee72b3934481459dd95516b9af055c04ddfbe714428878f9e7ca9b0f5f' + And the tenant details labelled 'Tenant1' should have tenant Id that is the hash of the Guid labelled 'WellKnown1' + And the tenant details labelled 'Tenant2' should have tenant Id that is the concatenated hashes of the Guids labelled 'WellKnown1' and 'WellKnown2' And the tenant labelled 'Tenant2' should have storage configuration equivalent to the root Scenario: Creating a child of a child with a well known Id that is already in use by a child of the same parent throws an ArgumentException - Given the root tenant has a well-known child tenant called 'ChildTenant1' with a Guid of 'ABE7C6C9-8494-4797-B52E-5C7B3EF1CE56' labelled 'Tenant1' - And the tenant labelled 'Tenant1' has a well-known child tenant called 'ChildTenant2' with a Guid of 'DD045C05-E7FB-4214-8878-F9E7CA9B0F5F' labelled 'Tenant2' - When I try to create a well known child of the tenant labelled 'Tenant1' named 'ChildTenant3' with a Guid of 'DD045C05-E7FB-4214-8878-F9E7CA9B0F5F' + Given a well-known tenant Guid labelled 'WellKnown1' + And a well-known tenant Guid labelled 'WellKnown2' + And the root tenant has a well-known (from the Guid labelled 'WellKnown1') child tenant called 'ChildTenant1' labelled 'Tenant1' + And the tenant labelled 'Tenant1' has a well-known (from the Guid labelled 'WellKnown2') child tenant called 'ChildTenant2' labelled 'Tenant2' + When I try to create a well known child (from the Guid labelled 'WellKnown2') of the tenant labelled 'Tenant1' named 'ChildTenant3' Then CreateWellKnownChildTenantAsync thould throw an ArgumentException Scenario: Creating children that have the same well known Ids under different parents succeeds - Given the root tenant has a well-known child tenant called 'ChildTenant1' with a Guid of '2A182D6E-FF13-4A73-87AF-0B58D8243603' labelled 'Parent1' - And the root tenant has a well-known child tenant called 'ChildTenant2' with a Guid of '086D75A1-DA07-4C90-BEA7-857A6C126280' labelled 'Parent2' - And the tenant labelled 'Parent1' has a well-known child tenant called 'ChildTenant3' with a Guid of '2A182D6E-FF13-4A73-87AF-0B58D8243603' labelled 'ChildOfParent1' - When I create a well known child of the tenant labelled 'Parent2' named 'ChildTenant4' with a Guid of '2A182D6E-FF13-4A73-87AF-0B58D8243603' labelled 'ChildOfParent2' + Given a well-known tenant Guid labelled 'WellKnown1' + And a well-known tenant Guid labelled 'WellKnown2' + And a well-known tenant Guid labelled 'WellKnown3' + And a well-known tenant Guid labelled 'WellKnown4' + And the root tenant has a well-known (from the Guid labelled 'WellKnown1') child tenant called 'ChildTenant1' labelled 'Parent1' + And the root tenant has a well-known (from the Guid labelled 'WellKnown2') child tenant called 'ChildTenant2' labelled 'Parent2' + And the tenant labelled 'Parent1' has a well-known (from the Guid labelled 'WellKnown3') child tenant called 'ChildTenant3' labelled 'ChildOfParent1' + When I create a well known (from the Guid labelled 'WellKnown4') child of the tenant labelled 'Parent2' named 'ChildTenant4' labelled 'ChildOfParent2' And I get the tenant with the id from label 'ChildOfParent1' labelled 'Result1' And I get the tenant with the id from label 'ChildOfParent2' labelled 'Result2' - Then the tenant details labelled 'Result1' should have tenant Id '6e2d182a13ff734a87af0b58d82436036e2d182a13ff734a87af0b58d8243603' - And the tenant details labelled 'Result2' should have tenant Id 'a1756d0807da904cbea7857a6c1262806e2d182a13ff734a87af0b58d8243603' + Then the tenant details labelled 'Result1' should have tenant Id that is the concatenated hashes of the Guids labelled 'WellKnown1' and 'WellKnown3' + And the tenant details labelled 'Result2' should have tenant Id that is the concatenated hashes of the Guids labelled 'WellKnown2' and 'WellKnown4' And the tenant labelled 'Result1' should have storage configuration equivalent to the root And the tenant labelled 'Result2' should have storage configuration equivalent to the root diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature index 15e0c505..f29d6836 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/DeleteTenant.feature @@ -20,9 +20,43 @@ Scenario: Delete a child | ChildTenant4 | | ChildTenant5 | -# TODO: -# Attempt to delete non-existent tenant -# Attempt to delete child for which parent is non-existent -# Attempt to delete a non-empty parent -# Delete child of a child? -# What happens if we try to delete the root? \ No newline at end of file +Scenario: Delete a child of a child + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ParentTenant' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant2' labelled 'ChildTenant2' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant3' labelled 'ChildTenant3' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant4' labelled 'ChildTenant4' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant5' labelled 'ChildTenant5' + And the tenant labelled 'ChildTenant2' has a child tenant called 'ChildTenant6' labelled 'ChildTenant6' + And the tenant labelled 'ChildTenant3' has a child tenant called 'ChildTenant7' labelled 'ChildTenant7' + And the tenant labelled 'ChildTenant3' has a child tenant called 'ChildTenant8' labelled 'ChildTenant8' + And the tenant labelled 'ChildTenant3' has a child tenant called 'ChildTenant9' labelled 'ChildTenant9' + When I delete the tenant with the id from label 'ChildTenant8' + And I get the children of the tenant with the label 'ChildTenant3' with maxItems 20 + Then the ids of all the children across all pages should match these tenant ids + | TenantName | + | ChildTenant7 | + | ChildTenant9 | + +Scenario: Delete a non-existent child of root + When I attempt to delete a tenant with the id that looks like a child of the root tenant but which does not exist + Then the attempt to delete a tenant should throw a TenantNotFoundException + +Scenario: Delete a non-existent child of non-existent child of root + When I attempt to delete a tenant with the id that looks like a child of a child of the root tenant, where neither exists + Then the attempt to delete a tenant should throw a TenantNotFoundException + +Scenario: Delete a non-existent child of existing parent + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ParentTenant' + When I attempt to delete a tenant with the id that looks like a child of 'ParentTenant' but which does not exist + Then the attempt to delete a tenant should throw a TenantNotFoundException + +Scenario: Delete root tenant + When I attempt to delete the root tenant + Then the attempt to delete a tenant should throw an ArgumentException + +Scenario: Delete a non-empty parent + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ParentTenant' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant2' labelled 'ChildTenant2' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant3' labelled 'ChildTenant3' + When I attempt to delete the tenant with the id from label 'ParentTenant' + Then the attempt to delete a tenant should throw an ArgumentException diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature index 2a17757d..50b74965 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/Features/RenameTenant.feature @@ -15,8 +15,29 @@ Scenario: Rename a child tenant And the tenant labelled 'UpdateResult' should have the name 'NewName' And the tenant labelled 'GetResult' should have the name 'NewName' -# TODO: -# Try to rename a non-existent tenant -# Try to rename a child for which parent is non-existent -# Rename child of child? -# What if we try to rename the root? \ No newline at end of file +Scenario: Rename a child of a child + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ParentTenant' + And the tenant labelled 'ParentTenant' has a child tenant called 'ChildTenant2' labelled 'ChildTenant2' + When I change the name of the tenant labelled 'ChildTenant2' to 'NewName' and label the returned tenant 'UpdateResult' + And I get the tenant with the id from label 'ChildTenant2' labelled 'GetResult' + Then the tenant labelled 'UpdateResult' should have the same ID as the tenant labelled 'ChildTenant2' + And the tenant labelled 'GetResult' should have the same ID as the tenant labelled 'ChildTenant2' + And the tenant labelled 'UpdateResult' should have the name 'NewName' + And the tenant labelled 'GetResult' should have the name 'NewName' + +Scenario: Rename a non-existent child of root tenant + When I attempt to change the name of a tenant with the id that looks like a child of the root tenant but which does not exist + Then the attempt to change the name of a tenant should throw a TenantNotFoundException + +Scenario: Rename a non-existent child of non-existent child of root + When I attempt to change the name of a tenant with the id that looks like a child of a child of the root tenant, where neither exists + Then the attempt to change the name of a tenant should throw a TenantNotFoundException + +Scenario: Rename a non-existent child of existing parent + Given the root tenant has a child tenant called 'ChildTenant1' labelled 'ParentTenant' + When I attempt to change the name of a tenant with the id that looks like a child of 'ParentTenant' but which does not exist + Then the attempt to change the name of a tenant should throw a TenantNotFoundException + +Scenario: Rename root tenant + When I attempt to change the name of the root tenant + Then the attempt to change the name of a tenant should throw an ArgumentException diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/CreateTenantSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/CreateTenantSteps.cs index 03f95435..817c0856 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/CreateTenantSteps.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/CreateTenantSteps.cs @@ -43,10 +43,12 @@ public async Task GivenICreateAChildOfTheRootTenantCalledWithTheDetailsAvailable this.AddTenantToDelete(newTenant.Id); } - [When(@"I create a well known child tenant of the root tenant called '([^']*)' with a Guid of '([^']*)' labelled '([^']*)'")] + [When(@"I create a well known \(from the Guid labelled '([^']*)'\) child tenant of the root tenant called '([^']*)' labelled '([^']*)'")] public async Task GivenICreateAWellKnownChildOfTheRootTenantCalledWithTheDetailsAvailableAsAsync( - string tenantName, Guid wellKnownGuid, string newTenantLabel) + string wellKnownGuidLabel, string tenantName, string newTenantLabel) { + Guid wellKnownGuid = this.WellKnownGuids[wellKnownGuidLabel]; + // This is called in scenarios where we want the tenant creation to go through the // tenant store under test even when the setup mode is direct-to-store, because we're // validating that the information returned from the store works when we use it again @@ -70,26 +72,28 @@ public async Task GivenICreateAChildOfAChildOfTheRootTenantAsync( this.AddTenantToDelete(newTenant.Id); } - [When(@"I create a well known child of the tenant labelled '([^']*)' named '([^']*)' with a Guid of '([^']*)' labelled '([^']*)'")] + [When(@"I create a well known \(from the Guid labelled '([^']*)'\) child of the tenant labelled '([^']*)' named '([^']*)' labelled '([^']*)'")] public async Task GivenICreateAWellKnownChildOfAChildOfATenantAsync( - string parentTenantLabel, string newTenantName, Guid wellKnownId, string newTenantLabel) + string wellKnownGuidLabel, string parentTenantLabel, string newTenantName, string newTenantLabel) { + Guid wellKnownGuid = this.WellKnownGuids[wellKnownGuidLabel]; ITenant parent = this.Tenants[parentTenantLabel]; ITenant newTenant = await this.TenantStore.CreateWellKnownChildTenantAsync( - parent.Id, wellKnownId, newTenantName); + parent.Id, wellKnownGuid, newTenantName); this.Tenants.Add(newTenantLabel, newTenant); this.AddWellKnownTenantToDelete(newTenant.Id); } - [When(@"I try to create a well known child of the tenant labelled '([^']*)' named '([^']*)' with a Guid of '([^']*)'")] + [When(@"I try to create a well known child \(from the Guid labelled '([^']*)'\) of the tenant labelled '([^']*)' named '([^']*)'")] public async Task GivenITryToCreateAWellKnownChildOfAChildOfATenantAsync( - string parentTenantLabel, string newTenantName, Guid wellKnownId) + string wellKnownGuidLabel, string parentTenantLabel, string newTenantName) { + Guid wellKnownGuid = this.WellKnownGuids[wellKnownGuidLabel]; ITenant parent = this.Tenants[parentTenantLabel]; try { ITenant newTenant = await this.TenantStore.CreateWellKnownChildTenantAsync( - parent.Id, wellKnownId, newTenantName); + parent.Id, wellKnownGuid, newTenantName); } catch (Exception x) { diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/DeleteTenantSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/DeleteTenantSteps.cs index 79b66bc4..d1bfc576 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/DeleteTenantSteps.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/DeleteTenantSteps.cs @@ -4,28 +4,92 @@ namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.StepDefinitions { + using System; using System.Threading.Tasks; using Corvus.Tenancy; + using Corvus.Tenancy.Exceptions; using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings; + using NUnit.Framework; + using TechTalk.SpecFlow; [Binding] public class DeleteTenantSteps : TenantStepsBase { + private Exception? deletionException; + public DeleteTenantSteps(TenantProperties tenantProperties) : base(tenantProperties) { } - [When(@"I delete the tenant with the id from label '([^']*)'")] + [When("I delete the tenant with the id from label '([^']*)'")] public async Task GivenIDeleteATenant(string tenantLabel) { ITenant existingTenant = this.Tenants[tenantLabel]; await this.TenantStore.DeleteTenantAsync(existingTenant.Id); this.TenantNoLongerRequiresDeletion(existingTenant.Id); } + + [When("I attempt to delete a tenant with the id that looks like a child of the root tenant but which does not exist")] + public async Task WhenIAttemptToDeleteATenantWithTheIdThatLooksLikeAChildOfTheRootTenantButWhichDoesNotExist() + { + await this.AttemptToDelete(TenantExtensions.CreateChildId(RootTenant.RootTenantId, Guid.NewGuid())); + } + + [When("I attempt to delete a tenant with the id that looks like a child of a child of the root tenant, where neither exists")] + public async Task WhenIAttemptToDeleteATenantWithTheIdThatLooksLikeAChildOfAChildOfTheRootTenantWhereNeitherExistsAsync() + { + string nonExistentParent = TenantExtensions.CreateChildId(RootTenant.RootTenantId, Guid.NewGuid()); + await this.AttemptToDelete(TenantExtensions.CreateChildId(nonExistentParent, Guid.NewGuid())); + } + + [When("I attempt to delete a tenant with the id that looks like a child of '([^']*)' but which does not exist")] + public async Task WhenIAttemptToDeleteATenantWithTheIdThatLooksLikeAChildOfButWhichDoesNotExistAsync(string parentTenantLabel) + { + ITenant parent = this.Tenants[parentTenantLabel]; + await this.AttemptToDelete(TenantExtensions.CreateChildId(parent.Id, Guid.NewGuid())); + } + + [When("I attempt to delete the root tenant")] + public async Task WhenIAttemptToDeleteTheRootTenantAsync() + { + await this.AttemptToDelete(RootTenant.RootTenantId); + } + + [When("I attempt to delete the tenant with the id from label '([^']*)'")] + public async Task WhenIAttemptToDeleteTheTenantWithTheIdFromLabelAsync(string parentTenantLabel) + { + ITenant parentTenant = this.Tenants[parentTenantLabel]; + await this.AttemptToDelete(parentTenant.Id); + } + + [Then("the attempt to delete a tenant should throw a TenantNotFoundException")] + public void ThenTheAttemptToDeleteATenantShouldThrowATenantNotFoundException() + { + Assert.IsInstanceOf(this.deletionException); + } + + [Then("the attempt to delete a tenant should throw an ArgumentException")] + public void ThenTheAttemptToDeleteATenantShouldThrowAnArgumentException() + { + Assert.IsInstanceOf(this.deletionException); + } + + private async Task AttemptToDelete(string tenantId) + { + try + { + await this.TenantStore.DeleteTenantAsync(tenantId); + this.TenantNoLongerRequiresDeletion(tenantId); + } + catch (Exception x) + { + this.deletionException = x; + } + } } } \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/GetTenantSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/GetTenantSteps.cs index 6f5e0635..a0976dd4 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/GetTenantSteps.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/GetTenantSteps.cs @@ -108,9 +108,22 @@ public void ThenTenantShouldMatchingTheDetails(string detailsToInspect, string d tenantToInspect.ETag.Should().Be(tenantToCompareWith.ETag); } - [Then(@"the tenant details labelled '([^']*)' should have tenant Id '([^']*)'")] - public void ThenGetTenantShouldHaveTheTenantId(string detailsToInspect, string expectedId) + [Then(@"the tenant details labelled '([^']*)' should have tenant Id that is the hash of the Guid labelled '([^']*)'")] + public void ThenGetTenantShouldHaveTheTenantId(string detailsToInspect, string wellKnownGuidLabel) { + Guid wellKnownGuid = this.WellKnownGuids[wellKnownGuidLabel]; + string expectedId = TenantExtensions.EncodeGuid(wellKnownGuid); + ITenant tenantToInspect = this.Tenants[detailsToInspect]; + tenantToInspect.Id.Should().Be(expectedId); + } + + [Then(@"the tenant details labelled '([^']*)' should have tenant Id that is the concatenated hashes of the Guids labelled '([^']*)' and '([^']*)'")] + public void ThenTheTenantDetailsLabelledShouldHaveTenantIdThatIsTheConcatenatedHashesOfTheGuidsLabelledAnd( + string detailsToInspect, string wellKnownGuidLabel1, string wellKnownGuidLabel2) + { + Guid wellKnownGuid1 = this.WellKnownGuids[wellKnownGuidLabel1]; + Guid wellKnownGuid2 = this.WellKnownGuids[wellKnownGuidLabel2]; + string expectedId = TenantExtensions.EncodeGuid(wellKnownGuid1) + TenantExtensions.EncodeGuid(wellKnownGuid2); ITenant tenantToInspect = this.Tenants[detailsToInspect]; tenantToInspect.Id.Should().Be(expectedId); } diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/RenameTenantSteps.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/RenameTenantSteps.cs index 110d89d4..881ba6d1 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/RenameTenantSteps.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage.Specs/StepDefinitions/RenameTenantSteps.cs @@ -4,23 +4,29 @@ namespace Marain.Tenancy.Storage.Azure.BlobStorage.Specs.StepDefinitions { + using System; using System.Threading.Tasks; using Corvus.Tenancy; + using Corvus.Tenancy.Exceptions; using Marain.Tenancy.Storage.Azure.BlobStorage.Specs.Bindings; + using NUnit.Framework; + using TechTalk.SpecFlow; [Binding] public class RenameTenantSteps : TenantStepsBase { + private Exception? renameException; + public RenameTenantSteps(TenantProperties tenantProperties) : base(tenantProperties) { } - [When(@"I change the name of the tenant labelled '([^']*)' to '([^']*)' and label the returned tenant '([^']*)'")] + [When("I change the name of the tenant labelled '([^']*)' to '([^']*)' and label the returned tenant '([^']*)'")] public async Task GivenIChangeATenantNameAsync( string existingTenantLabel, string tenantNewName, string returnedTenantLabel) { @@ -30,5 +36,55 @@ public async Task GivenIChangeATenantNameAsync( name: tenantNewName); this.Tenants.Add(returnedTenantLabel, updatedTenant); } - } + + [When("I attempt to change the name of a tenant with the id that looks like a child of the root tenant but which does not exist")] + public async Task WhenIAttemptToChangeTheNameOfATenantWithTheIdThatLooksLikeAChildOfTheRootTenantButWhichDoesNotExistAsync() + { + await this.AttemptToRename(TenantExtensions.CreateChildId(RootTenant.RootTenantId, Guid.NewGuid())); + } + + [When("I attempt to change the name of a tenant with the id that looks like a child of a child of the root tenant, where neither exists")] + public async Task WhenIAttemptToChangeTheNameOfATenantWithTheIdThatLooksLikeAChildOfAChildOfTheRootTenantWhereNeitherExistsAsync() + { + string nonExistentParent = TenantExtensions.CreateChildId(RootTenant.RootTenantId, Guid.NewGuid()); + await this.AttemptToRename(TenantExtensions.CreateChildId(nonExistentParent, Guid.NewGuid())); + } + + [When("I attempt to change the name of a tenant with the id that looks like a child of '([^']*)' but which does not exist")] + public async Task WhenIAttemptToChangeTheNameOfATenantWithTheIdThatLooksLikeAChildOfButWhichDoesNotExistAsync(string parentTenantLabel) + { + ITenant parent = this.Tenants[parentTenantLabel]; + await this.AttemptToRename(TenantExtensions.CreateChildId(parent.Id, Guid.NewGuid())); + } + + [When("I attempt to change the name of the root tenant")] + public async Task WhenIAttemptToChangeTheNameOfTheRootTenantAsync() + { + await this.AttemptToRename(RootTenant.RootTenantId); + } + + [Then("the attempt to change the name of a tenant should throw a TenantNotFoundException")] + public void ThenTheAttemptToChangeTheNameOfATenantShouldThrowATenantNotFoundException() + { + Assert.IsInstanceOf(this.renameException); + } + + [Then("the attempt to change the name of a tenant should throw an ArgumentException")] + public void ThenTheAttemptToChangeTheNameOfATenantShouldThrowAnArgumentException() + { + Assert.IsInstanceOf(this.renameException); + } + + private async Task AttemptToRename(string tenantId) + { + try + { + await this.TenantStore.UpdateTenantAsync(tenantId, name: "NewName"); + } + catch (Exception x) + { + this.renameException = x; + } + } + } } \ No newline at end of file diff --git a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs index fdfc2d53..bd4b173a 100644 --- a/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs +++ b/Solutions/Marain.Tenancy.Storage.Azure.BlobStorage/Marain/Tenancy/Storage/Azure/BlobStorage/AzureBlobStorageTenantStore.cs @@ -190,6 +190,16 @@ public async Task DeleteTenantAsync(string tenantId) (_, BlobContainerClient tenantContainer) = await this.GetContainerAndTenantForChildTenantsOfAsync(tenantId).ConfigureAwait(false); + // Check it's not empty first. + AsyncPageable pageable = tenantContainer.GetBlobsAsync( + prefix: LiveTenantsPrefix); + IAsyncEnumerable> pages = pageable.AsPages(pageSizeHint: 1); + await using IAsyncEnumerator> page = pages.GetAsyncEnumerator(); + if (await page.MoveNextAsync() && page.Current.Values.Count > 0) + { + throw new ArgumentException($"Cannot delete tenant {tenantId} because it has children"); + } + BlockBlobClient blob = GetLiveTenantBlockBlobReference(tenantId, parentContainer); Response response = await blob.DownloadContentAsync().ConfigureAwait(false); using var blobContent = response.Value.Content.ToStream(); diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 19d93a63..69f7102a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -14,7 +14,6 @@ resources: type: github name: endjin/Endjin.RecommendedPractices.AzureDevopsPipelines.GitHub endpoint: marain-github - ref: refs/heads/feature/scripted-build jobs: - template: templates/build.and.release.scripted.yml@recommended_practices From 183092c1f278caa252c90c5ae9816a55a866a0dd Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Fri, 17 Dec 2021 17:30:42 +0000 Subject: [PATCH 09/10] Add v2.0 release notes (#368) --- docs/ReleaseNotes/Marain.Tenancy.v2.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 docs/ReleaseNotes/Marain.Tenancy.v2.md diff --git a/docs/ReleaseNotes/Marain.Tenancy.v2.md b/docs/ReleaseNotes/Marain.Tenancy.v2.md new file mode 100644 index 00000000..7f1a0a4c --- /dev/null +++ b/docs/ReleaseNotes/Marain.Tenancy.v2.md @@ -0,0 +1,9 @@ +# Release notes for Marain.Tenancy v3. + +## v2.0 + +Targets .NET 6.0 only. +The function host runs on Functions v4. +This has been updated to use the Corvus.Tenancy v3, Corvus.Storage v1, and Corvus.Identity v3. (This in turn means we're now using the new-style (Azure.Core) Azure Client SDK—no more dependencies on deprecated client libraries.) + +There are no changes at the web API level, so existing client code should continue to work unaltered against tenancy services using this new version. \ No newline at end of file From 1ef4ec0fd2245d2237acffda6b436ff7c26be7e1 Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Fri, 17 Dec 2021 19:57:31 +0000 Subject: [PATCH 10/10] Update to non-preview Menes (#370) --- .../packages.lock.json | 42 ++++++------ .../Marain.Tenancy.Hosting.AspNetCore.csproj | 2 +- .../Marain.Tenancy.OpenApi.Service.csproj | 2 +- .../Marain.Tenancy.Specs/packages.lock.json | 66 +++++++++---------- 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json index e9accdb8..d4d4fa32 100644 --- a/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json +++ b/Solutions/Marain.Tenancy.Host.Functions/packages.lock.json @@ -162,11 +162,11 @@ }, "Corvus.Extensions.Newtonsoft.Json": { "type": "Transitive", - "resolved": "2.0.5", - "contentHash": "d9g6XjfyU5z2gffGNuOD4veWzCEUibioxvYyQkiwOmt+0SL5M0j4C6TNE6015LzEVYtnjLHXM+3op3NUqLtK7g==", + "resolved": "2.0.6", + "contentHash": "6yXJ7xbflSB3c0G7hdNExwlhbEChMRcSn6fX4k8ghhWyADrDSY6jJp9Ce6guxo1c4gVjZwgCVIDhA3JgO8KyHA==", "dependencies": { - "Corvus.Json.Abstractions": "2.0.5", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.18", + "Corvus.Json.Abstractions": "2.0.6", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", "Newtonsoft.Json": "11.0.2" } }, @@ -189,8 +189,8 @@ }, "Corvus.Json.Abstractions": { "type": "Transitive", - "resolved": "2.0.5", - "contentHash": "fUuuUwktUoCQNwR2+bvi2AcOPzJkU51o8Js37vCTdXBg4aDLQZaFIuyO9Dg9Sm9NW1hVhK5nBFkBaqbmF5rutg==" + "resolved": "2.0.6", + "contentHash": "ixx72ttlP/Ck+UMWyfiRWVBFKU5XjJySMG33ZWofJp9yy65VF3uOJyGPujr3OedUMo6Uq9umftmHRqhOmUyQ8g==" }, "Corvus.Monitoring.Instrumentation.Abstractions": { "type": "Transitive", @@ -239,15 +239,15 @@ }, "Menes.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-vnext.4", - "contentHash": "nUerpY8sRmgB9N9Bbyf/qe1hcDyvRPCrhHZpzlgftR4TcFf2S4OG/2Lbfs3UfcFokpG58hYXuWVPwGSNEEkBEQ==", + "resolved": "3.0.0", + "contentHash": "puLN8wrfuMCFmwOMvaJNsegbTcr0UlocejkZbNXuULfaDcNBLB7rQvLVqt6TVWjIWrw94RaJoD6+wg8aY0EITg==", "dependencies": { - "Corvus.ContentHandling": "2.0.8", - "Corvus.Extensions": "1.1.3", - "Corvus.Extensions.Newtonsoft.Json": "2.0.4", - "Corvus.Monitoring.Instrumentation.Abstractions": "1.3.0", + "Corvus.ContentHandling": "2.0.11", + "Corvus.Extensions": "1.1.4", + "Corvus.Extensions.Newtonsoft.Json": "2.0.6", + "Corvus.Monitoring.Instrumentation.Abstractions": "1.3.2", "Microsoft.CSharp": "4.7.0", - "Microsoft.Extensions.Logging": "3.1.16", + "Microsoft.Extensions.Logging": "3.1.22", "Microsoft.OpenApi.Readers": "1.2.3", "System.Interactive": "4.1.1", "System.Text.Encodings.Web": "4.7.2", @@ -256,18 +256,18 @@ }, "Menes.Hosting": { "type": "Transitive", - "resolved": "3.0.0-vnext.4", - "contentHash": "WactTL+8zqUA1j94FEWFxtaaFIHutJk93/XaGh0qT1aXQiHVH7w6dlvyHhZNcOkoLxMC29kjtFQP7XT7yuRXug==", + "resolved": "3.0.0", + "contentHash": "VQYzTjmxAnMRMw3hsiS+tWYPJg3GYavRxu9Fqi//p9m0oBIBIgohmFRqfanPSBZiYfzOtrI/gOVNuhigWovplg==", "dependencies": { - "Menes.Abstractions": "3.0.0-vnext.4" + "Menes.Abstractions": "3.0.0" } }, "Menes.Hosting.AspNetCore": { "type": "Transitive", - "resolved": "3.0.0-vnext.4", - "contentHash": "QXmIh1CiafSaaxC9iEH81P3xngxeYk5Sd7v6aXa0hixUnJBFWbPa7MFJYFnhoiYF82t92aWsaIGfhTJEalvoVQ==", + "resolved": "3.0.0", + "contentHash": "8GlsYJeDqhlWrxYcXyvBehe8OFEkK4bwUAt4Ll+UbHpuVioYUvvtt2unhoo07oTqbjbMzNQUotMpreZSGMqQ6w==", "dependencies": { - "Menes.Hosting": "3.0.0-vnext.4" + "Menes.Hosting": "3.0.0" } }, "Microsoft.ApplicationInsights": { @@ -1926,14 +1926,14 @@ "type": "Project", "dependencies": { "Marain.Tenancy.OpenApi.Service": "1.0.0", - "Menes.Hosting.AspNetCore": "3.0.0-vnext.4" + "Menes.Hosting.AspNetCore": "3.0.0" } }, "marain.tenancy.openapi.service": { "type": "Project", "dependencies": { "Corvus.Tenancy.Abstractions": "3.0.0", - "Menes.Abstractions": "3.0.0-vnext.4", + "Menes.Abstractions": "3.0.0", "Microsoft.ApplicationInsights": "2.20.0", "Microsoft.AspNetCore.JsonPatch": "6.0.0", "Microsoft.Extensions.Configuration.Abstractions": "6.0.0", diff --git a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj index 9db70673..df550ba8 100644 --- a/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj +++ b/Solutions/Marain.Tenancy.Hosting.AspNetCore/Marain.Tenancy.Hosting.AspNetCore.csproj @@ -18,7 +18,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj index 8d52b519..6c2b48d3 100644 --- a/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj +++ b/Solutions/Marain.Tenancy.OpenApi.Service/Marain.Tenancy.OpenApi.Service.csproj @@ -30,7 +30,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Solutions/Marain.Tenancy.Specs/packages.lock.json b/Solutions/Marain.Tenancy.Specs/packages.lock.json index 8c1d0759..7b152401 100644 --- a/Solutions/Marain.Tenancy.Specs/packages.lock.json +++ b/Solutions/Marain.Tenancy.Specs/packages.lock.json @@ -159,11 +159,11 @@ }, "Corvus.Extensions.Newtonsoft.Json": { "type": "Transitive", - "resolved": "2.0.5", - "contentHash": "d9g6XjfyU5z2gffGNuOD4veWzCEUibioxvYyQkiwOmt+0SL5M0j4C6TNE6015LzEVYtnjLHXM+3op3NUqLtK7g==", + "resolved": "2.0.6", + "contentHash": "6yXJ7xbflSB3c0G7hdNExwlhbEChMRcSn6fX4k8ghhWyADrDSY6jJp9Ce6guxo1c4gVjZwgCVIDhA3JgO8KyHA==", "dependencies": { - "Corvus.Json.Abstractions": "2.0.5", - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.18", + "Corvus.Json.Abstractions": "2.0.6", + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20", "Newtonsoft.Json": "11.0.2" } }, @@ -196,15 +196,15 @@ }, "Corvus.Json.Abstractions": { "type": "Transitive", - "resolved": "2.0.5", - "contentHash": "fUuuUwktUoCQNwR2+bvi2AcOPzJkU51o8Js37vCTdXBg4aDLQZaFIuyO9Dg9Sm9NW1hVhK5nBFkBaqbmF5rutg==" + "resolved": "2.0.6", + "contentHash": "ixx72ttlP/Ck+UMWyfiRWVBFKU5XjJySMG33ZWofJp9yy65VF3uOJyGPujr3OedUMo6Uq9umftmHRqhOmUyQ8g==" }, "Corvus.Monitoring.Instrumentation.Abstractions": { "type": "Transitive", - "resolved": "1.3.0", - "contentHash": "fhULZvrr4d6imDMzohP1t2QPEZ5jRyNDIwMX2kQySSECSLn27Hf83FaRKStMD5PoZjc5QLLtpnrTsLRu8WHxeA==", + "resolved": "1.3.2", + "contentHash": "IEnBaceaj7kJYF96xBusLOQs3GBYaN4TywNzdsNf3Ol7g4NxpCilVSY+mBw1aLbDGm3WapZ2KfaHW7Wo3iWI/w==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.16" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.20" } }, "Corvus.Tenancy.Abstractions": { @@ -263,15 +263,15 @@ }, "Menes.Abstractions": { "type": "Transitive", - "resolved": "3.0.0-vnext.4", - "contentHash": "nUerpY8sRmgB9N9Bbyf/qe1hcDyvRPCrhHZpzlgftR4TcFf2S4OG/2Lbfs3UfcFokpG58hYXuWVPwGSNEEkBEQ==", + "resolved": "3.0.0", + "contentHash": "puLN8wrfuMCFmwOMvaJNsegbTcr0UlocejkZbNXuULfaDcNBLB7rQvLVqt6TVWjIWrw94RaJoD6+wg8aY0EITg==", "dependencies": { - "Corvus.ContentHandling": "2.0.8", - "Corvus.Extensions": "1.1.3", - "Corvus.Extensions.Newtonsoft.Json": "2.0.4", - "Corvus.Monitoring.Instrumentation.Abstractions": "1.3.0", + "Corvus.ContentHandling": "2.0.11", + "Corvus.Extensions": "1.1.4", + "Corvus.Extensions.Newtonsoft.Json": "2.0.6", + "Corvus.Monitoring.Instrumentation.Abstractions": "1.3.2", "Microsoft.CSharp": "4.7.0", - "Microsoft.Extensions.Logging": "3.1.16", + "Microsoft.Extensions.Logging": "3.1.22", "Microsoft.OpenApi.Readers": "1.2.3", "System.Interactive": "4.1.1", "System.Text.Encodings.Web": "4.7.2", @@ -280,18 +280,18 @@ }, "Menes.Hosting": { "type": "Transitive", - "resolved": "3.0.0-vnext.4", - "contentHash": "WactTL+8zqUA1j94FEWFxtaaFIHutJk93/XaGh0qT1aXQiHVH7w6dlvyHhZNcOkoLxMC29kjtFQP7XT7yuRXug==", + "resolved": "3.0.0", + "contentHash": "VQYzTjmxAnMRMw3hsiS+tWYPJg3GYavRxu9Fqi//p9m0oBIBIgohmFRqfanPSBZiYfzOtrI/gOVNuhigWovplg==", "dependencies": { - "Menes.Abstractions": "3.0.0-vnext.4" + "Menes.Abstractions": "3.0.0" } }, "Menes.Hosting.AspNetCore": { "type": "Transitive", - "resolved": "3.0.0-vnext.4", - "contentHash": "QXmIh1CiafSaaxC9iEH81P3xngxeYk5Sd7v6aXa0hixUnJBFWbPa7MFJYFnhoiYF82t92aWsaIGfhTJEalvoVQ==", + "resolved": "3.0.0", + "contentHash": "8GlsYJeDqhlWrxYcXyvBehe8OFEkK4bwUAt4Ll+UbHpuVioYUvvtt2unhoo07oTqbjbMzNQUotMpreZSGMqQ6w==", "dependencies": { - "Menes.Hosting": "3.0.0-vnext.4" + "Menes.Hosting": "3.0.0" } }, "Microsoft.ApplicationInsights": { @@ -451,10 +451,10 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "js24vxT9kzGfH7nc/EL9Yi2s5jQilFTxIYHIpX/oIEINVRW4qlnQXsfzsbXE5Y0BAG5TTidnfZ+IyOEsW9XTVA==", + "resolved": "3.1.22", + "contentHash": "QrzfKU8te2X0ykM8XY9YzLvzTGO8qOMq45/Y2sy5gZryQqYe9CxEr0ulwG0idpL+ByK7luX7djmtT8Nv1mMaZw==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.21" + "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.22" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { @@ -499,13 +499,13 @@ }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "3.1.21", - "contentHash": "5D0RMBkH4eliNeR2a3VFV4stIer/CsFTeAGo2Uv1dm2X9Ttz8n0lbc7gl8+NogTiKfGm1RqoLF0HtH/1V4wxmw==", + "resolved": "3.1.22", + "contentHash": "XgHXT5JWsfv9xg0pM/UTgtRhfcv05SieQLMHImVOGNFK6jutVmNYOilKYL9oFlmk8bSeyifYTVacigJ3FgFB3A==", "dependencies": { - "Microsoft.Extensions.Configuration.Binder": "3.1.21", - "Microsoft.Extensions.DependencyInjection": "3.1.21", - "Microsoft.Extensions.Logging.Abstractions": "3.1.21", - "Microsoft.Extensions.Options": "3.1.21" + "Microsoft.Extensions.Configuration.Binder": "3.1.22", + "Microsoft.Extensions.DependencyInjection": "3.1.22", + "Microsoft.Extensions.Logging.Abstractions": "3.1.22", + "Microsoft.Extensions.Options": "3.1.22" } }, "Microsoft.Extensions.Logging.Abstractions": { @@ -1884,14 +1884,14 @@ "type": "Project", "dependencies": { "Marain.Tenancy.OpenApi.Service": "1.0.0", - "Menes.Hosting.AspNetCore": "3.0.0-vnext.4" + "Menes.Hosting.AspNetCore": "3.0.0" } }, "marain.tenancy.openapi.service": { "type": "Project", "dependencies": { "Corvus.Tenancy.Abstractions": "3.0.0", - "Menes.Abstractions": "3.0.0-vnext.4", + "Menes.Abstractions": "3.0.0", "Microsoft.ApplicationInsights": "2.20.0", "Microsoft.AspNetCore.JsonPatch": "6.0.0", "Microsoft.Extensions.Configuration.Abstractions": "6.0.0",