diff --git a/.github/workflows/build-and-stage.yml b/.github/workflows/build-and-stage.yml index dcb12920..66f19155 100644 --- a/.github/workflows/build-and-stage.yml +++ b/.github/workflows/build-and-stage.yml @@ -20,6 +20,7 @@ env: DOCFX_SOURCE_BRANCH_NAME: ${{ github.base_ref || github.ref_name }} STEELTOE_V2_VERSION: 2.5.5 STEELTOE_V3_VERSION: 3.2.6 + STEELTOE_V4_VERSION: main SITE_IMAGE_VERSION: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || github.run_id }} jobs: @@ -41,12 +42,13 @@ jobs: with: filters: | docfx-layer-changed: - - .github/workflows/build-and-stage.yml - 'docfx/**' metadata-layer-changed: - .github/workflows/build-and-stage.yml - Dockerfile-metadata - - '/api-*.*' + - 'api/**' + - 'articles/**' + - 'guides/**' - build-metadata.sh - docfx.json - name: Declare image versions @@ -65,23 +67,25 @@ jobs: echo "metadata-image-version=${{ env.STEELTOE_VERSIONS }}" >> "$GITHUB_OUTPUT" fi env: - STEELTOE_VERSIONS: ${{ env.STEELTOE_V2_VERSION }}-${{ env.STEELTOE_V3_VERSION }} + STEELTOE_VERSIONS: ${{ env.STEELTOE_V2_VERSION }}-${{ env.STEELTOE_V3_VERSION }}-${{ env.STEELTOE_V4_VERSION }} shell: bash build-push-docfx: name: Build and push docfx layer needs: change-detection - if: ${{ needs.change-detection.outputs.docfx-layer-changed }} runs-on: ubuntu-latest steps: - name: Checkout + if: ${{ needs.change-detection.outputs.docfx-layer-changed == 'true' }} uses: actions/checkout@v4 - name: Set DocFX version to use + if: ${{ needs.change-detection.outputs.docfx-layer-changed == 'true' }} run: echo v${{ env.DOCFX_VERSION }} > docfx/version shell: bash - name: Login to container registry + if: ${{ needs.change-detection.outputs.docfx-layer-changed == 'true' }} uses: docker/login-action@v3 with: registry: "${{ vars.DOCKER_REGISTRY }}" @@ -89,15 +93,17 @@ jobs: password: "${{ secrets.DOCKER_PASSWORD }}" - name: Build image + if: ${{ needs.change-detection.outputs.docfx-layer-changed == 'true' }} run: docker build docfx --file "docfx/Dockerfile" -t ${{ vars.DOCKER_REGISTRY }}/docfx:${{ needs.change-detection.outputs.docfx-image-version }} - name: Push image + if: ${{ needs.change-detection.outputs.docfx-layer-changed == 'true' }} run: docker push ${{ vars.DOCKER_REGISTRY }}/docfx --all-tags build-push-metadata: name: Build and push API docs layer needs: [ change-detection, build-push-docfx ] - if: ${{ needs.change-detection.outputs.metadata-layer-changed }} + if: ${{ needs.change-detection.outputs.metadata-layer-changed == 'true' }} runs-on: ubuntu-latest steps: - name: Checkout @@ -107,6 +113,7 @@ jobs: run: |- echo '2:'${{ env.STEELTOE_V2_VERSION }} > metadata.conf echo '3:'${{ env.STEELTOE_V3_VERSION }} >> metadata.conf + echo '4:'${{ env.STEELTOE_V4_VERSION }} >> metadata.conf shell: bash - name: Login to container registry diff --git a/.github/workflows/stage-prod-swap.yml b/.github/workflows/stage-prod-swap.yml index 053ddcbf..515058a9 100644 --- a/.github/workflows/stage-prod-swap.yml +++ b/.github/workflows/stage-prod-swap.yml @@ -36,4 +36,4 @@ jobs: run: | az webapp config appsettings set --resource-group steeltoe --name docs-steeltoe --slot Staging --settings mainsite_host=https://staging.steeltoe.io az webapp restart --resource-group steeltoe --name docs-steeltoe --slot Staging - \ No newline at end of file + diff --git a/.markdownlint.json b/.markdownlint.json index 866ab22e..6168c36d 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -1,4 +1,4 @@ { "MD013": false, "MD033": { "allowed_elements": ["img"] } -} \ No newline at end of file +} diff --git a/README.md b/README.md index 7b28639b..f06365c8 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,7 @@ Let's talk about something really cool... ## Creating a new API document -Create a new markdown file in the `api` directory. Name the file something URL safe. In the `api` directory there are `v2` and `v3` directories. Within each of those are directories for each component. Place your content accordingly. To include the document in the Table of Contents, add it to `api/(version)/toc.yml`. -An example API document: +Similar to the blog post, you're going to create a new markdown file, but in the `api` folder. The name needs to be URL-safe. Notice in the api folder, there is a `v2`, `v3` and `v4` subfolder. Within each of those are folders for each component. Place your content accordingly. To include the file in the table of contents, add it in `api/(version)/toc.yml`. Notice in the example below that the `topicHref` values are not absolute paths. DocFX will calculate everything at build time. An example API doc: @@ -123,7 +122,7 @@ For working on any non-trivial changes, there are several ways to build and run The easiest way to build and run the site is this command: `docfx build --serve --port 8082`. -### Build API docs for Steeltoe 2 and 3 +### Build API docs for Steeltoe 2, 3 and 4 Building the API docs is not required for the site to run locally. @@ -132,9 +131,11 @@ If needed, these commands will download the Steeltoe source code and generate AP ```bash git clone https://github.com/SteeltoeOSS/Steeltoe sources/v2 -b release/2.5 git clone https://github.com/SteeltoeOSS/Steeltoe sources/v3 -b release/3.2 +git clone https://github.com/SteeltoeOSS/Steeltoe sources/v4 -b release/main git clean -fX api docfx metadata api-v2.json docfx metadata api-v3.json +docfx metadata api-v4.json docfx metadata api-all.json ``` diff --git a/api-all.json b/api-all.json index 91d655ae..e7caf1fb 100644 --- a/api-all.json +++ b/api-all.json @@ -37,6 +37,25 @@ "TargetFramework": "net6.0" }, "version": "3.all" + }, + { + "src": [ + { + "files": [ + "src/**/*.csproj" + ], + "exclude": [ "**/bin/**", "**/obj/**", "**/test/**" ], + "src": "sources/v4" + } + ], + "dest": "api/browser/v4/all", + "disableGitFeatures": false, + "disableDefaultFilter": false, + "filter": "api-filter.yml", + "properties": { + "TargetFramework": "net6.0" + }, + "version": "4.all" } ] } diff --git a/api-v4.json b/api-v4.json new file mode 100644 index 00000000..0843591d --- /dev/null +++ b/api-v4.json @@ -0,0 +1,156 @@ +{ + "metadata": [ + { + "src": [ + { + "files": [ + "**/*.csproj" + ], + "exclude": [ "**/bin/**", "**/obj/**" ], + "src": "sources/v4/src/Bootstrap/src" + } + ], + "dest": "api/browser/v4/bootstrap", + "disableGitFeatures": false, + "disableDefaultFilter": false, + "filter": "api-filter.yml", + "properties": { + "TargetFramework": "net6.0" + }, + "version": "4.x" + }, + { + "src": [ + { + "files": [ + "**/*.csproj" + ], + "exclude": [ "**/bin/**", "**/obj/**" ], + "src": "sources/v4/src/Common/src" + } + ], + "dest": "api/browser/v4/common", + "disableGitFeatures": false, + "disableDefaultFilter": false, + "filter": "api-filter.yml", + "properties": { + "TargetFramework": "net6.0" + }, + "version": "4.x" + }, + { + "src": [ + { + "files": [ + "**/*.csproj" + ], + "exclude": [ "**/bin/**", "**/obj/**" ], + "src": "sources/v4/src/Configuration/src" + } + ], + "dest": "api/browser/v4/configuration", + "disableGitFeatures": false, + "disableDefaultFilter": false, + "filter": "api-filter.yml", + "properties": { + "TargetFramework": "net6.0" + }, + "version": "4.x" + }, + { + "src": [ + { + "files": [ + "**/*.csproj" + ], + "exclude": [ "**/bin/**", "**/obj/**" ], + "src": "sources/v4/src/Connectors/src" + } + ], + "dest": "api/browser/v4/connectors", + "disableGitFeatures": false, + "disableDefaultFilter": false, + "filter": "api-filter.yml", + "properties": { + "TargetFramework": "net6.0" + }, + "version": "4.x" + }, + { + "src": [ + { + "files": [ + "**/*.csproj" + ], + "exclude": [ "**/bin/**", "**/obj/**" ], + "src": "sources/v4/src/Discovery/src" + } + ], + "dest": "api/browser/v4/discovery", + "disableGitFeatures": false, + "disableDefaultFilter": false, + "filter": "api-filter.yml", + "properties": { + "TargetFramework": "net6.0" + }, + "version": "4.x" + }, + { + "src": [ + { + "files": [ + "**/*.csproj" + ], + "exclude": [ "**/bin/**", "**/obj/**" ], + "src": "sources/v4/src/Logging/src" + } + ], + "dest": "api/browser/v4/logging", + "disableGitFeatures": false, + "disableDefaultFilter": false, + "filter": "api-filter.yml", + "properties": { + "TargetFramework": "net6.0" + }, + "version": "4.x" + }, + { + "src": [ + { + "files": [ + "**/*.csproj" + ], + "exclude": [ "**/bin/**", "**/obj/**" ], + "src": "sources/v4/src/Management/src" + } + ], + "dest": "api/browser/v4/management", + "disableGitFeatures": false, + "disableDefaultFilter": false, + "filter": "api-filter.yml", + "properties": { + "TargetFramework": "net6.0" + }, + "version": "4.x" + }, + { + "src": [ + { + "files": [ + "**/*.csproj" + ], + "exclude": [ "**/bin/**", "**/obj/**" ], + "src": "sources/v4/src/Security/src" + } + ], + "dest": "api/browser/v4/security", + "disableGitFeatures": false, + "disableDefaultFilter": false, + "filter": "api-filter.yml", + "properties": { + "TargetFramework": "net6.0" + }, + "version": "4.x" + } + ] +} diff --git a/api/browser/v3/all/index.md b/api/browser/v3/all/index.md index 4964a8f3..b2997e31 100644 --- a/api/browser/v3/all/index.md +++ b/api/browser/v3/all/index.md @@ -81,4 +81,4 @@ Authentication and DataProtection libraries which simplify interacting with Cred Contains streaming support for RabbitMQ. -[view](/api/browser/v3/stream/Steeltoe.Stream.Extensions.html) \ No newline at end of file +[view](/api/browser/v3/stream/Steeltoe.Stream.Extensions.html) diff --git a/api/browser/v4/all/index.md b/api/browser/v4/all/index.md new file mode 100644 index 00000000..8cb3b7f5 --- /dev/null +++ b/api/browser/v4/all/index.md @@ -0,0 +1,60 @@ +--- +_disableToc: false +_disableAffix: false +_disableGitFeatures: true + +title: Steeltoe Namespaces +uid: api/browser/v4/all/index +--- + +# Steeltoe Namespaces + +## Steeltoe.Bootstrap.AutoConfiguration + +Extension methods on host builders that automatically activate Steeltoe features, based on the assemblies referenced by your app. + +[view](/api/browser/v4/bootstrap/Steeltoe.Bootstrap.AutoConfiguration.html) + +## Steeltoe.Common + +Various general-purpose facilities, often used by higher-level Steeltoe components. + +[view](/api/browser/v4/common/Steeltoe.Common.html) + +## Steeltoe.Configuration + +[Custom configuration providers](https://docs.microsoft.com/aspnet/core/fundamentals/configuration/#custom-config-providers) for use with Microsoft's [application configuration](https://docs.microsoft.com/aspnet/core/fundamentals/configuration/) for accessing configuration settings for an application. + +[view](/api/browser/v4/configuration/Steeltoe.Configuration.html) + +## Steeltoe.Connectors + +Connectors simplify the process of connecting to backing services (databases, message brokers and distributed caches) and setting up connection health monitoring. + +[view](/api/browser/v4/connectors/Steeltoe.Connectors.html) + +## Steeltoe.Discovery + +Service discovery entails registration with service registries and load-balanced instance lookups. + +[view](/api/browser/v4/discovery/Steeltoe.Discovery.HttpClients.html) + +## Steeltoe.Logging + +Enables changing the minimum log levels at runtime, without restarting the app. + +Currently supports the Microsoft Console Logger and Serilog. + +[view](/api/browser/v4/logging/Steeltoe.Logging.html) + +## Steeltoe.Management + +Management tools to help manage and monitor your applications in production. + +[view](/api/browser/v4/management/Steeltoe.Management.Endpoint.html) + +## Steeltoe.Security + +Authentication, authorization and Data Protection support for secure services on CloudFoundry. + +[view](/api/browser/v4/security/Steeltoe.Security.Authentication.JwtBearer.html) diff --git a/api/v2/circuitbreaker/hystrix.md b/api/v2/circuitbreaker/hystrix.md index bd3131cb..5a2253a4 100644 --- a/api/v2/circuitbreaker/hystrix.md +++ b/api/v2/circuitbreaker/hystrix.md @@ -37,7 +37,7 @@ To use the Steeltoe framework: * Use Hystrix Command(s) and/or Collapser(s) to invoke dependent services * Add and Use the Hystrix metrics stream service ->NOTE: Most of the code in the following sections is based on using Hystrix in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/master/CircuitBreaker) for example code you can use. +>NOTE: Most of the code in the following sections is based on using Hystrix in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/2.x/CircuitBreaker) for example code you can use. ### Add NuGet References @@ -157,7 +157,7 @@ All Hystrix command settings should be prefixed with `hystrix:command:`. `hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds=750` -To configure the settings for a command in code, use `HystrixCommandOptions` from the `Steeltoe.CircuitBreaker.HystrixBase` package. +To configure the settings for a command in code, use `HystrixCommandOptions` from the `Steeltoe.CircuitBreaker.HystrixBase` package. All configured command-specific settings, as described earlier in #4, should be prefixed with `hystrix:command:HYSTRIX_COMMAND_KEY:`, where `HYSTRIX_COMMAND_KEY` is the `name` of the command. The following example configures the timeout for the Hystrix command with a name of `sample` to be 750 milliseconds: diff --git a/api/v2/configuration/cloud-foundry-provider.md b/api/v2/configuration/cloud-foundry-provider.md index 29c058a2..d41143fa 100644 --- a/api/v2/configuration/cloud-foundry-provider.md +++ b/api/v2/configuration/cloud-foundry-provider.md @@ -23,7 +23,7 @@ In order to use the Steeltoe Cloud Foundry provider you need to do the following 1. Configure Cloud Foundry options classes by binding configuration data to the classes. 1. Inject and use the Cloud Foundry Options to access Cloud Foundry configuration data. ->NOTE: Most of the example code in the following sections is based on using Steeltoe in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/master/Configuration) for example code you can use. +>NOTE: Most of the example code in the following sections is based on using Steeltoe in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/2.x/Configuration) for example code you can use. ### Add NuGet Reference @@ -179,11 +179,11 @@ public class HomeController : Controller #### ConfigureCloudFoundryService -As an alternative to using `CloudFoundryServicesOptions` to access Cloud Foundry service data you can also use `ConfigureCloudFoundryService()` or `ConfigureCloudFoundryServices()` to easily gain access to service data. +As an alternative to using `CloudFoundryServicesOptions` to access Cloud Foundry service data you can also use `ConfigureCloudFoundryService()` or `ConfigureCloudFoundryServices()` to easily gain access to service data. These methods allow you to define an Option class which represents a particular type of Cloud Foundry service binding and then use either method to select that data from `VCAP_SERVICES` and bind the data to it. -To do this, you first need to create a Options class that derives from `AbstractServiceOptions`. That class must match the data provided in `VCAP_SERVICES`. +To do this, you first need to create a Options class that derives from `AbstractServiceOptions`. That class must match the data provided in `VCAP_SERVICES`. Here is an example that illustrates how to do this for a MySql service binding on PCF: @@ -210,7 +210,7 @@ public class MySqlCredentials Next in your `Startup` class you can use either `ConfigureCloudFoundryService()` or `ConfigureCloudFoundryServices()` to bind the service data from `VCAP_SERVICES` to your `TOption`. There are multiple ways to do this depending on your needs. -You can use `ConfigureCloudFoundryService()` method to select a specific Cloud Foundry service binding from `VCAP_SERVICES` by specifying a service name. Or you can use `ConfigureCloudFoundryServices()` to bind to all services of a particular type by specifying a Cloud Foundry service label. +You can use `ConfigureCloudFoundryService()` method to select a specific Cloud Foundry service binding from `VCAP_SERVICES` by specifying a service name. Or you can use `ConfigureCloudFoundryServices()` to bind to all services of a particular type by specifying a Cloud Foundry service label. Here are some examples: diff --git a/api/v2/configuration/config-server-provider.md b/api/v2/configuration/config-server-provider.md index 5a57aab6..973abc58 100644 --- a/api/v2/configuration/config-server-provider.md +++ b/api/v2/configuration/config-server-provider.md @@ -14,12 +14,12 @@ The Steeltoe Config Server provider supports the following .NET application type In addition to the Quick Start below, there are several other Steeltoe sample applications that you can refer to when needing help in understanding how to use this provider: -* [AspDotNetCore/Simple](https://github.com/SteeltoeOSS/Samples/tree/master/Configuration/src/AspDotNetCore/Simple): ASP.NET Core sample app showing how to use the open source Config Server. -* [AspDotNet4/Simple](https://github.com/SteeltoeOSS/Samples/tree/master/Configuration/src/AspDotNet4/Simple): Same as AspDotNetCore/Simple but built for ASP.NET 4.x -* [AspDotNet4/SimpleCloudFoundry](https://github.com/SteeltoeOSS/Samples/tree/master/Configuration/src/AspDotNet4/SimpleCloudFoundry): Same as the Quick Start sample mentioned later but built for ASP.NET 4.x. -* [AspDotNet4/AutofacCloudFoundry](https://github.com/SteeltoeOSS/Samples/tree/master/Configuration/src/AspDotNet4/AutofacCloudFoundry): Same as AspDotNet4/SimpleCloudFoundry but built using the Autofac IOC container. -* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/master/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a micro-services based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. -* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/master/FreddysBBQ): A polyglot microservices-based sample app showing inter-operability between Java and .NET on Cloud Foundry. It is secured with OAuth2 Security Services and using Spring Cloud Services. +* [AspDotNetCore/Simple](https://github.com/SteeltoeOSS/Samples/tree/2.x/Configuration/src/AspDotNetCore/Simple): ASP.NET Core sample app showing how to use the open source Config Server. +* [AspDotNet4/Simple](https://github.com/SteeltoeOSS/Samples/tree/2.x/Configuration/src/AspDotNet4/Simple): Same as AspDotNetCore/Simple but built for ASP.NET 4.x +* [AspDotNet4/SimpleCloudFoundry](https://github.com/SteeltoeOSS/Samples/tree/2.x/Configuration/src/AspDotNet4/SimpleCloudFoundry): Same as the Quick Start sample mentioned later but built for ASP.NET 4.x. +* [AspDotNet4/AutofacCloudFoundry](https://github.com/SteeltoeOSS/Samples/tree/2.x/Configuration/src/AspDotNet4/AutofacCloudFoundry): Same as AspDotNet4/SimpleCloudFoundry but built using the Autofac IOC container. +* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/2.x/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a micro-services based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. +* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/2.x/FreddysBBQ): A polyglot microservices-based sample app showing inter-operability between Java and .NET on Cloud Foundry. It is secured with OAuth2 Security Services and using Spring Cloud Services. >IMPORTANT: The `Pivotal.Extensions.Configuration.ConfigServer*` packages have been deprecated in Steeltoe 2.2 and are not included in future releases. All functionality provided in those packages has been pushed into the corresponding `Steeltoe.Extensions.Configuration.ConfigServer*` packages. diff --git a/api/v2/configuration/index.md b/api/v2/configuration/index.md index 2a9b56e1..9ee9f5ab 100644 --- a/api/v2/configuration/index.md +++ b/api/v2/configuration/index.md @@ -20,4 +20,4 @@ Steeltoe adds four additional configuration providers to the preceding list: * Placeholder resolvers * RandomValue generator -The following sections provide more more detail on each of these new providers. +The following sections provide more detail on each of these new providers. diff --git a/api/v2/configuration/placeholder-provider.md b/api/v2/configuration/placeholder-provider.md index 3043a451..1fce5158 100644 --- a/api/v2/configuration/placeholder-provider.md +++ b/api/v2/configuration/placeholder-provider.md @@ -23,7 +23,7 @@ In order to use the Steeltoe Placeholder resolver provider you need to do the fo 1. Optionally, configure Options classes by binding configuration data to the classes. 1. Inject and use the Options classes or access configuration data directly. ->NOTE: Most of the example code in the following sections is based on using Steeltoe in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/master/Configuration) for example code you can use. +>NOTE: Most of the example code in the following sections is based on using Steeltoe in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/2.x/Configuration) for example code you can use. ### Add NuGet Reference @@ -46,7 +46,7 @@ To add this type of NuGet to your project, add a `PackageReference` resembling t ### Add Configuration Provider -In order to have placeholders resolved when accessing your configuration data, you need to add the Placeholder resolver provider to the `ConfigurationBuilder`. +In order to have placeholders resolved when accessing your configuration data, you need to add the Placeholder resolver provider to the `ConfigurationBuilder`. There are four different ways in which you can do this. diff --git a/api/v2/configuration/random-value-provider.md b/api/v2/configuration/random-value-provider.md index bde0cd3b..17be62dc 100644 --- a/api/v2/configuration/random-value-provider.md +++ b/api/v2/configuration/random-value-provider.md @@ -1,6 +1,6 @@ # RandomValue Provider -Sometimes you might find the need to generate random values as part of your applications configuration values. +Sometimes you might find the need to generate random values as part of your applications configuration values. The Steeltoe RandomValue generator is a configuration provider which you can use to do just that. It can produce integers, longs, uuids or strings as shown in the following examples: @@ -47,7 +47,7 @@ In order to use the Steeltoe RandomValue provider you need to do the following: 1. Add the provider to the Configuration Builder. 1. Access random values from the `IConfiguration`. ->NOTE: Most of the example code in the following sections is based on using Steeltoe in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/master/Configuration) for example code you can use. +>NOTE: Most of the example code in the following sections is based on using Steeltoe in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/2.x/Configuration) for example code you can use. ### Add NuGet Reference @@ -65,7 +65,7 @@ To do this add a `PackageReference` resembling the following: ### Add Configuration Provider -In order to have the ability to generate random values from the configuration, you need to add the RandomValue generatore provider to the `ConfigurationBuilder`. +In order to have the ability to generate random values from the configuration, you need to add the RandomValue generatore provider to the `ConfigurationBuilder`. The following example shows how to add to this: diff --git a/api/v2/connectors/mysql.md b/api/v2/connectors/mysql.md index 5db7fc7b..8a081aa1 100644 --- a/api/v2/connectors/mysql.md +++ b/api/v2/connectors/mysql.md @@ -9,11 +9,11 @@ Currently, the connector supports the following providers: Here are several Steeltoe sample applications to help you understand how to use this connector: -* [AspDotNet4/MySql4](https://github.com/SteeltoeOSS/Samples/tree/master/Connectors/src/AspDotNet4/MySql4): Same as the next Quick Start but built for ASP.NET 4.x. -* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/master/MusicStore): A sample app showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a micro-services based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. -* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/master/FreddysBBQ): A polyglot (Java and .NET) micro-services based sample application showing interoperability between Java and .NET based micro-services running on Cloud Foundry, secured with OAuth2 Security Services, and using Spring Cloud Services. +* [AspDotNet4/MySql4](https://github.com/SteeltoeOSS/Samples/tree/2.x/Connectors/src/AspDotNet4/MySql4): Same as the next Quick Start but built for ASP.NET 4.x. +* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/2.x/MusicStore): A sample app showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a micro-services based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. +* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/2.x/FreddysBBQ): A polyglot (Java and .NET) micro-services based sample application showing interoperability between Java and .NET based micro-services running on Cloud Foundry, secured with OAuth2 Security Services, and using Spring Cloud Services. -This connector provides a `IHealthContributor` which you can use in conjunction with the [Steeltoe Management Health](/../management/health.html) check endpoint. +This connector provides a `IHealthContributor` which you can use in conjunction with the [Steeltoe Management Health](../management/health.md) check endpoint. ## Usage diff --git a/api/v2/connectors/postgresql.md b/api/v2/connectors/postgresql.md index 1d0ec3bc..735002d2 100644 --- a/api/v2/connectors/postgresql.md +++ b/api/v2/connectors/postgresql.md @@ -4,7 +4,7 @@ This connector simplifies using PostgreSQL in an application running on Cloud Fo Currently, the connector supports the [Npgsql](https://www.npgsql.org/) provider. -This connector provides a `IHealthContributor` which you can use in conjunction with the [Steeltoe Management Health](/../management/health.html) check endpoint. +This connector provides a `IHealthContributor` which you can use in conjunction with the [Steeltoe Management Health](../management/health.md) check endpoint. ## Usage diff --git a/api/v2/connectors/rabbitmq.md b/api/v2/connectors/rabbitmq.md index 9b796c25..e2f701d8 100644 --- a/api/v2/connectors/rabbitmq.md +++ b/api/v2/connectors/rabbitmq.md @@ -2,7 +2,7 @@ This connector simplifies using the [RabbitMQ Client](https://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html) in an application running on Cloud Foundry. We recommend following that tutorial, because you need to know how to use it before proceeding to use the connector. -This connector provides a `IHealthContributor` which you can use in conjunction with the [Steeltoe Management Health](/../management/health.html) check endpoint. +This connector provides a `IHealthContributor` which you can use in conjunction with the [Steeltoe Management Health](../management/health.md) check endpoint. ## Usage diff --git a/api/v2/connectors/redis.md b/api/v2/connectors/redis.md index edb76ea3..bfc375c5 100644 --- a/api/v2/connectors/redis.md +++ b/api/v2/connectors/redis.md @@ -5,10 +5,10 @@ Here are some Steeltoe sample applications are available to help you understand how to use this connector: * [AspDotNet4/Redis4](https://github.com/SteeltoeOSS/Samples/tree/dev/Connectors/src/AspDotNet4/Redis4): Same as the next Quick Start but built for ASP.NET 4.x. -* [DataProtection](https://github.com/SteeltoeOSS/Samples/tree/master/Security/src/RedisDataProtectionKeyStore): A sample application showing how to use the Steeltoe DataProtection Key Storage Provider for Redis. -* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/master/MusicStore): A sample application showing how to use all of the Steeltoe components together in an ASP.NET Core application. This is a micro-services based application built from the ASP.NET Core reference app MusicStore provided by Microsoft. +* [DataProtection](https://github.com/SteeltoeOSS/Samples/tree/2.x/Security/src/RedisDataProtectionKeyStore): A sample application showing how to use the Steeltoe DataProtection Key Storage Provider for Redis. +* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/2.x/MusicStore): A sample application showing how to use all of the Steeltoe components together in an ASP.NET Core application. This is a micro-services based application built from the ASP.NET Core reference app MusicStore provided by Microsoft. -This connector provides a `IHealthContributor` which you can use in conjunction with the [Steeltoe Management Health](/../management/health.html) check endpoint. +This connector provides a `IHealthContributor` which you can use in conjunction with the [Steeltoe Management Health](../management/health.md) check endpoint. ## Usage diff --git a/api/v2/developer-tools/cli.md b/api/v2/developer-tools/cli.md index cd855a65..1624ee6c 100644 --- a/api/v2/developer-tools/cli.md +++ b/api/v2/developer-tools/cli.md @@ -1,4 +1,4 @@ -# Steeltoe CLI +# Steeltoe CLI Steeltoe CLI simplifies the process of running and deploying Steeltoe applications. With this tooling you can, with minimal commands, run your application locally while also being able to easily deploy to Kubernetes or Cloud Foundry. There are 3 basic steps when using Steeltoe Tooling: diff --git a/api/v2/developer-tools/index.md b/api/v2/developer-tools/index.md index b1c9a17b..a2867750 100644 --- a/api/v2/developer-tools/index.md +++ b/api/v2/developer-tools/index.md @@ -1,9 +1,9 @@ # Developer Tools -## Steeltoe CLI +## Steeltoe CLI Steeltoe CLI simplifies the process of running and deploying Steeltoe applications. With this tooling you can, with minimal commands, run your application locally while also being able to easily deploy to Kubernetes or Cloud Foundry. ## Initializr The Steeltoe Initializr project is an application generator meant to get cloud-native .NET developers going very quickly. -Check out our [Getting Started Guide for Initializr](https://steeltoe.io/initializr) \ No newline at end of file +Check out our [Getting Started Guide for Initializr](https://steeltoe.io/initializr) diff --git a/api/v2/discovery/hashicorp-consul.md b/api/v2/discovery/hashicorp-consul.md index 13dc3057..3f6e238b 100644 --- a/api/v2/discovery/hashicorp-consul.md +++ b/api/v2/discovery/hashicorp-consul.md @@ -24,11 +24,11 @@ In order to use the Steeltoe Discovery client, you need to do the following: * Add and Use the Discovery client service in the application. * Use an injected `IDiscoveryClient` to lookup services. ->NOTE: Most of the example code in the following sections is based on using Discovery in a ASP.NET Core application. If you are developing a ASP.NET 4.x application or a console-based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/master/Discovery) for example code you can use. +>NOTE: Most of the example code in the following sections is based on using Discovery in a ASP.NET Core application. If you are developing a ASP.NET 4.x application or a console-based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/2.x/Discovery) for example code you can use. ### Consul Settings -To get the Steeltoe Discovery client to properly communicate with the Consul server, you need to provide a few configuration settings to the client. There are two sections you may need to configure. +To get the Steeltoe Discovery client to properly communicate with the Consul server, you need to provide a few configuration settings to the client. There are two sections you may need to configure. The first pertains to configuring the information needed to connect to the Consul server. All of these settings should start with `consul:` diff --git a/api/v2/discovery/netflix-eureka.md b/api/v2/discovery/netflix-eureka.md index 3e2894e0..ed1f77b2 100644 --- a/api/v2/discovery/netflix-eureka.md +++ b/api/v2/discovery/netflix-eureka.md @@ -10,10 +10,10 @@ The Eureka client implementation supports the following .NET application types: Here are several Steeltoe sample applications when looking for help in understanding how to use this client: -* [AspDotNet4/Fortune-Teller-Service4](https://github.com/SteeltoeOSS/Samples/tree/master/Discovery/src/AspDotNet4/Fortune-Teller-Service4): Same as the Quick Start next but built for ASP.NET 4.x and using the Autofac IOC container. -* [AspDotNet4/Fortune-Teller-UI4](https://github.com/SteeltoeOSS/Samples/tree/master/Discovery/src/AspDotNet4/Fortune-Teller-UI4): Same as the Quick Start next but built for ASP.NET 4.x and using the Autofac IOC container -* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/master/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a microservices-based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. -* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/master/FreddysBBQ): A polyglot microservices-based sample application showing interoperability between Java and .NET on Cloud Foundry. It is secured with OAuth2 Security Services and using Spring Cloud Services. +* [AspDotNet4/Fortune-Teller-Service4](https://github.com/SteeltoeOSS/Samples/tree/2.x/Discovery/src/AspDotNet4/Fortune-Teller-Service4): Same as the Quick Start next but built for ASP.NET 4.x and using the Autofac IOC container. +* [AspDotNet4/Fortune-Teller-UI4](https://github.com/SteeltoeOSS/Samples/tree/2.x/Discovery/src/AspDotNet4/Fortune-Teller-UI4): Same as the Quick Start next but built for ASP.NET 4.x and using the Autofac IOC container +* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/2.x/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a microservices-based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. +* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/2.x/FreddysBBQ): A polyglot microservices-based sample application showing interoperability between Java and .NET on Cloud Foundry. It is secured with OAuth2 Security Services and using Spring Cloud Services. ## Usage @@ -31,7 +31,7 @@ In order to use the Steeltoe Discovery client, you need to do the following: * Add and Use the Discovery client service in the application. * Use an injected `IDiscoveryClient` to lookup services. ->NOTE: Most of the example code in the following sections is based on using Discovery in a ASP.NET Core application. If you are developing a ASP.NET 4.x application or a console-based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/master/Discovery) for example code you can use. +>NOTE: Most of the example code in the following sections is based on using Discovery in a ASP.NET Core application. If you are developing a ASP.NET 4.x application or a console-based app, see the [other samples](https://github.com/SteeltoeOSS/Samples/tree/2.x/Discovery) for example code you can use. ### Eureka Settings diff --git a/api/v2/logging/index.md b/api/v2/logging/index.md index 734731b8..220a0af9 100644 --- a/api/v2/logging/index.md +++ b/api/v2/logging/index.md @@ -2,4 +2,4 @@ Steeltoe adds a Logging provider to the set of available logging packages in order to support the Steeltoe Management Logger endpoint. -When used with the Steeltoe Logger Management endpoint, this package enables dynamically changing the logging levels for running applications with the [TAS Apps Manager](https://docs.pivotal.io/pivotalcf/2-0/console/index.html) on Cloud Foundry. \ No newline at end of file +When used with the Steeltoe Logger Management endpoint, this package enables dynamically changing the logging levels for running applications with the [TAS Apps Manager](https://docs.pivotal.io/pivotalcf/2-0/console/index.html) on Cloud Foundry. diff --git a/api/v2/management/health.md b/api/v2/management/health.md index bb2def20..9ac06f78 100644 --- a/api/v2/management/health.md +++ b/api/v2/management/health.md @@ -5,7 +5,7 @@ The Steeltoe health management endpoint can be used to check and return the stat |Name|Description| |---|---| |`never`|Details are never shown.| -|`whenauthorized`|Details are only shown to authorized users. | +|`whenauthorized`|Details are only shown to authorized users. | |`always`|Details are always shown.| The default value is `always`. Authorized roles can be configured using `management:endpoints:health:claim or management:endpoints:health:role`. A user is considered to be authorized when they are in the given role or have the specified claim. For example: @@ -202,7 +202,7 @@ public void ConfigureServices(IServiceCollection services) var connectionString = cm.Get().ConnectionString; // Add microsoft community health checks from xabaril - services.AddHealthChecks().AddMySql(connectionString); + services.AddHealthChecks().AddMySql(connectionString); // Add in a MySql connection (this method also adds an IHealthContributor for it) services.AddMySqlConnection(Configuration); // will now use community health check instead of Steeltoe health check @@ -218,7 +218,7 @@ public void ConfigureServices(IServiceCollection services) ``` >NOTE: AddMySqlConnection will default to the ASP.NET Core health check if found in the service container. This behavior can be toggled off by passing AddMySqlConnection(Configuration, addSteeltoeHealthChecks: true) which will add both health checks. Be warned that this will make the Health check endpoint slower by calling multiple health checks for the same service. - + ```csharp public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { diff --git a/api/v2/management/hypermedia.md b/api/v2/management/hypermedia.md index 811d3c97..f12931a3 100644 --- a/api/v2/management/hypermedia.md +++ b/api/v2/management/hypermedia.md @@ -4,8 +4,8 @@ The purpose of this endpoint is to provide hypermedia for all the management end ## Base Context Path -This actuator also creates a base context path from which the endpoints can be accessed. The hypermedia actuator enables the following functionality: - +This actuator also creates a base context path from which the endpoints can be accessed. The hypermedia actuator enables the following functionality: + * Exposes an endpoint that can be queried to return the IDs of and links to all of the enabled management endpoints in the application. * Adds extension methods that simplify adding all of the Steeltoe management endpoints with HTTP access to the application. diff --git a/api/v2/management/info.md b/api/v2/management/info.md index c8a3368d..acf18d8e 100644 --- a/api/v2/management/info.md +++ b/api/v2/management/info.md @@ -13,7 +13,7 @@ The following table describes the `IInfoContributor` implementations provided by | `AppSettingsInfoContributor`|Exposes any values under the key `info` (for example, `info:foo:bar=foobar`) that is in your apps configuration (for example, `appsettings.json`)| | `GitInfoContributor`|Exposes git information (if a git.properties file is available)| -For an example of how to use the above `GitInfoContributor` within MSBuild using [GitInfo](https://github.com/kzu/GitInfo), see the [Steeltoe management sample](https://github.com/SteeltoeOSS/Samples/tree/master/Management/src/AspDotNetCore/CloudFoundry) and the [CloudFoundry.csproj](https://github.com/SteeltoeOSS/Samples/blob/master/Management/src/AspDotNetCore/CloudFoundry/CloudFoundry.csproj) file. +For an example of how to use the above `GitInfoContributor` within MSBuild using [GitInfo](https://github.com/kzu/GitInfo), see the [Steeltoe management sample](https://github.com/SteeltoeOSS/Samples/tree/2.x/Management/src/AspDotNetCore/CloudFoundry) and the [CloudFoundry.csproj](https://github.com/SteeltoeOSS/Samples/blob/2.x/Management/src/AspDotNetCore/CloudFoundry/CloudFoundry.csproj) file. If you wish to provide custom information for your application, create a class that implements the `IInfoContributor` interface and then add that to the `InfoEndpoint`. Details on how to add a contributor to the endpoint is provided below. diff --git a/api/v2/management/loggers.md b/api/v2/management/loggers.md index d5cb08d3..2e2f8b98 100644 --- a/api/v2/management/loggers.md +++ b/api/v2/management/loggers.md @@ -23,7 +23,7 @@ The default path to the Loggers endpoint is computed by combining the global `pa The coding steps you take to enable HTTP access to the Loggers endpoint together with how to use the Steeltoe Logging provider, differs depending on the type of .NET application your are developing. The sections which follow describe the steps needed for each of the supported application types. ->NOTE: The Steeltoe logging provider is a wrapper around the [Microsoft Console Logging](https://github.com/aspnet/Logging) provider from Microsoft. This wrapper allows querying defined loggers and modifying the levels dynamically at runtime. +>NOTE: The Steeltoe logging provider is a wrapper around the [Microsoft Console Logging](https://github.com/aspnet/Logging) provider from Microsoft. This wrapper allows querying defined loggers and modifying the levels dynamically at runtime. ### ASP.NET Core App diff --git a/api/v2/management/prometheus.md b/api/v2/management/prometheus.md index a3807bb0..1b5f9969 100644 --- a/api/v2/management/prometheus.md +++ b/api/v2/management/prometheus.md @@ -51,7 +51,7 @@ PM>Install-Package Steeltoe.Management.EndpointCore -Version 2.5.2 The [Metrics Forwarder for TAS](https://docs.pivotal.io/metrics-forwarder/) is no longer supported on Tanzu Application Service (TAS) v2.5 and later. To emit custom metrics on PAS v2.5 or later, use the Metric Registrar. For more information about enabling and configuring the Metric Registrar, see [Configuring the Metric Registrar](https://docs.pivotal.io/platform/application-service/2-8/metric-registrar/index.html). -To register your endpoint for metrics collection install the metrics-registrar plugin and use it to register your endpoint. +To register your endpoint for metrics collection install the metrics-registrar plugin and use it to register your endpoint. `cf install-plugin -r CF-Community "metric-registrar"` @@ -74,7 +74,7 @@ scrape_configs: static_configs: - targets: ['host.docker.internal:8000'] ``` -Running Prometheus server with this configuration will allow you view metrics in the built-in UI. Other visualization tools such as [Grafana](https://grafana.com/docs/grafana/latest/features/datasources/prometheus/) can then be configured to use Prometheus as a datasource. +Running Prometheus server with this configuration will allow you view metrics in the built-in UI. Other visualization tools such as [Grafana](https://grafana.com/docs/grafana/latest/features/datasources/prometheus/) can then be configured to use Prometheus as a datasource. ```docker docker run -d --name=prometheus -p 9090:9090 -v /prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus --config.file=/etc/prometheus/prometheus.yml diff --git a/api/v2/security/credhub-api-client.md b/api/v2/security/credhub-api-client.md index c2c3fdcb..56d907e7 100644 --- a/api/v2/security/credhub-api-client.md +++ b/api/v2/security/credhub-api-client.md @@ -195,7 +195,7 @@ You can use `await _credHub.FindAllPathsAsync()` to retrieve a list of all known #### Interpolate -One of the more powerful features of CredHub is the `Interpolate` endpoint. With one request, you may retrieve N number of credentials that have been stored in CredHub. To use it from .NET, call `await _credHub.InterpolateServiceDataAsync(serviceData)`, where `serviceData` is the string representation of `VCAP_SERVICES`. `CredHubClient` returns the interpolated `VCAP_SERVICES` data as a string. +One of the more powerful features of CredHub is the `Interpolate` endpoint. With one request, you may retrieve N number of credentials that have been stored in CredHub. To use it from .NET, call `await _credHub.InterpolateServiceDataAsync(serviceData)`, where `serviceData` is the string representation of `VCAP_SERVICES`. `CredHubClient` returns the interpolated `VCAP_SERVICES` data as a string. The following example shows a typical request object for the `Interpolate` endpoint: @@ -370,4 +370,4 @@ You can delete a permission associated with a credential. The following example ```csharp bool response = await _credHub.DeletePermissionAsync("/example-password", "uaa-user:credhub_client"); -``` \ No newline at end of file +``` diff --git a/api/v2/security/jwt-authentication-in-asp.NET-WCF.md b/api/v2/security/jwt-authentication-in-asp.NET-WCF.md index 9d8f12cf..347d0705 100644 --- a/api/v2/security/jwt-authentication-in-asp.NET-WCF.md +++ b/api/v2/security/jwt-authentication-in-asp.NET-WCF.md @@ -145,4 +145,4 @@ To pass a user's token (instead of the application's) to the backing service, fi // apply the behavior, including the user's token sRef.Endpoint.EndpointBehaviors.Add(new JwtHeaderEndpointBehavior(new CloudFoundryOptions(ApplicationConfig.Configuration), token)); string serviceResponse = await sRef.GetDataAsync(); -``` \ No newline at end of file +``` diff --git a/api/v2/security/sso-oauth2.md b/api/v2/security/sso-oauth2.md index ddac7ba6..e366fbe1 100644 --- a/api/v2/security/sso-oauth2.md +++ b/api/v2/security/sso-oauth2.md @@ -73,7 +73,7 @@ The Steeltoe OAuth2 security provider options are based on [`Microsoft.AspNetCor ### Cloud Foundry -As mentioned earlier, there are two OAuth-compatible services available on Cloud Foundry. We recommend you read the offical documentation ([UAA Server](https://github.com/cloudfoundry/uaa) and [TAS SSO](https://docs.pivotal.io/p-identity/1-5/getting-started.html)) or follow the instructions included in the samples for [UAA Server](https://github.com/SteeltoeOSS/Samples/blob/master/Security/src/AspDotNetCore/CloudFoundrySingleSignon/README.md) and [TAS SSO](https://github.com/SteeltoeOSS/Samples/blob/master/Security/src/AspDotNetCore/CloudFoundrySingleSignon/README-SSO.md) to quickly learn how to create and bind OAuth2 services. +As mentioned earlier, there are two OAuth-compatible services available on Cloud Foundry. We recommend you read the offical documentation ([UAA Server](https://github.com/cloudfoundry/uaa) and [TAS SSO](https://docs.pivotal.io/p-identity/1-5/getting-started.html)) or follow the instructions included in the samples for [UAA Server](https://github.com/SteeltoeOSS/Samples/blob/2.x/Security/src/AspDotNetCore/CloudFoundrySingleSignon/README.md) and [TAS SSO](https://github.com/SteeltoeOSS/Samples/blob/2.x/Security/src/AspDotNetCore/CloudFoundrySingleSignon/README-SSO.md) to quickly learn how to create and bind OAuth2 services. Regardless of which provider you choose, once the service is bound to your application, the settings are available in `VCAP_SERVICES`. diff --git a/api/v2/security/sso-open-id.md b/api/v2/security/sso-open-id.md index 878c42c7..4a9ee6ff 100644 --- a/api/v2/security/sso-open-id.md +++ b/api/v2/security/sso-open-id.md @@ -79,7 +79,7 @@ This full list of settings can also be configured, though `AuthDomain`, `ClientI #### Cloud Foundry -As mentioned earlier, there are two ways to use OAuth2 services on Cloud Foundry. We recommend you read the offical documentation ([UAA Server](https://github.com/cloudfoundry/uaa) and [TAS SSO](https://docs.pivotal.io/p-identity/1-5/getting-started.html)) or follow the instructions included in the samples for [UAA Server](https://github.com/SteeltoeOSS/Samples/blob/master/Security/src/AspDotNet4/CloudFoundrySingleSignon/README.md) and [TAS SSO](https://github.com/SteeltoeOSS/Samples/blob/master/Security/src/AspDotNet4/CloudFoundrySingleSignon/README-SSO.md) to quickly learn how to create and bind OAuth2 services. +As mentioned earlier, there are two ways to use OAuth2 services on Cloud Foundry. We recommend you read the offical documentation ([UAA Server](https://github.com/cloudfoundry/uaa) and [TAS SSO](https://docs.pivotal.io/p-identity/1-5/getting-started.html)) or follow the instructions included in the samples for [UAA Server](https://github.com/SteeltoeOSS/Samples/blob/2.x/Security/src/AspDotNet4/CloudFoundrySingleSignon/README.md) and [TAS SSO](https://github.com/SteeltoeOSS/Samples/blob/2.x/Security/src/AspDotNet4/CloudFoundrySingleSignon/README-SSO.md) to quickly learn how to create and bind OAuth2 services. Regardless of which provider you choose, once the service is bound to your application, the settings are available in `VCAP_SERVICES`. diff --git a/api/v2/toc.yml b/api/v2/toc.yml index 44728470..bf89e020 100644 --- a/api/v2/toc.yml +++ b/api/v2/toc.yml @@ -111,7 +111,7 @@ name: Apache Geode/GemFire - name: Service Discovery topicHref: discovery/ - items: + items: - topicHref: discovery/initialize-discovery-client.md name: Initialize Discovery Client - topicHref: discovery/discovering-services.md diff --git a/api/v2/tracing/distributed-tracing-exporting.md b/api/v2/tracing/distributed-tracing-exporting.md index 96952203..86796d9d 100644 --- a/api/v2/tracing/distributed-tracing-exporting.md +++ b/api/v2/tracing/distributed-tracing-exporting.md @@ -46,7 +46,7 @@ The following table describes the settings that you can apply to the exporter: |serviceName|app name used in log messages|null| |useShortTraceIds|truncate the ids to 8 bytes instead of 16, use for backwards compatibility with Spring Sleuth, PCF Metrics, etc.|true| -**Note**: **Each setting above must be prefixed with `management:tracing:exporter:zipkin`**. +**Note**: **Each setting above must be prefixed with `management:tracing:exporter:zipkin`**. #### Add and Use Zipkin Exporter diff --git a/api/v3/bootstrap/index.md b/api/v3/bootstrap/index.md index d69a8fb8..d9ec305e 100644 --- a/api/v3/bootstrap/index.md +++ b/api/v3/bootstrap/index.md @@ -1,6 +1,6 @@ # Application Bootstrapping -In order to improve the Steeltoe developer experience, Steeltoe 3.1.0 added this new feature that allows the configuration of most Steeltoe components with a single line of code in your application. The package is named [`Steeltoe.Bootstrap.Autoconfig`](https://github.com/SteeltoeOSS/Steeltoe/tree/main/src/Bootstrap/src/Autoconfig), and it works by applying the same extensions that are already included in Steeltoe packages to automatically wire up each of those components. +In order to improve the Steeltoe developer experience, Steeltoe 3.1.0 added this new feature that allows the configuration of most Steeltoe components with a single line of code in your application. The package is named [`Steeltoe.Bootstrap.Autoconfig`](https://github.com/SteeltoeOSS/Steeltoe/tree/release/3.2/src/Bootstrap/src/Autoconfig), and it works by applying the same extensions that are already included in Steeltoe packages to automatically wire up each of those components. Applications running on .NET Core 3.1+ and .NET 5.0+ are supported. Get started by adding a reference to the Autoconfig package (you may want to add other Steeltoe references at this point too, see [the table below](#supported-steeltoe-packages) for the full list of what's supported now): diff --git a/api/v3/circuitbreaker/hystrix.md b/api/v3/circuitbreaker/hystrix.md index 1c7be526..5482589e 100644 --- a/api/v3/circuitbreaker/hystrix.md +++ b/api/v3/circuitbreaker/hystrix.md @@ -247,7 +247,7 @@ Each setting is prefixed with the key `RequestLog`, as shown in the following ex #### Thread Pool Settings -Hystrix commands use thread pools to implement an underlying isolation pattern for resilience and fault tolerance features. By default each command will create its own 'named' thread pool and every time an instance of that command is executed, a thread from that thread pool will be chosen and used. +Hystrix commands use thread pools to implement an underlying isolation pattern for resilience and fault tolerance features. By default each command will create its own 'named' thread pool and every time an instance of that command is executed, a thread from that thread pool will be chosen and used. Optionally, you can configure your own 'named' thread pool (see next section) and in turn associate one or more commands to a specific thread pool. The describes the settings that control what thread pool a command uses when executing: diff --git a/api/v3/configuration/config-server-provider.md b/api/v3/configuration/config-server-provider.md index fa022b2f..f0b5476d 100644 --- a/api/v3/configuration/config-server-provider.md +++ b/api/v3/configuration/config-server-provider.md @@ -8,9 +8,9 @@ To gain a better understanding of the Spring Cloud Config Server, you should rea In addition to the Quick Start provided later, you can refer to several other Steeltoe sample applications when you need to understand how to use this provider: -* [AspDotNetCore/Simple](https://github.com/SteeltoeOSS/Samples/tree/master/Configuration/src/Simple): ASP.NET Core sample application showing how to use the open source Config Server. -* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/master/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a microservices based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. -* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/master/FreddysBBQ): A polyglot microservices-based sample application showing inter-operability between Java and .NET on Cloud Foundry. It is secured with OAuth2 Security Services and uses Spring Cloud Services. +* [AspDotNetCore/Simple](https://github.com/SteeltoeOSS/Samples/tree/3.x/Configuration/src/Simple): ASP.NET Core sample application showing how to use the open source Config Server. +* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/3.x/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a microservices based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. +* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/3.x/FreddysBBQ): A polyglot microservices-based sample application showing inter-operability between Java and .NET on Cloud Foundry. It is secured with OAuth2 Security Services and uses Spring Cloud Services. ## Usage diff --git a/api/v3/configuration/index.md b/api/v3/configuration/index.md index 0c81eab3..b1dd6c4f 100644 --- a/api/v3/configuration/index.md +++ b/api/v3/configuration/index.md @@ -21,4 +21,4 @@ Steeltoe adds additional configuration providers to the preceding list: * RandomValue generator * Spring Cloud Config Server -The following sections provide more more detail on each of these new providers. +The following sections provide more detail on each of these new providers. diff --git a/api/v3/connectors/gemfire.md b/api/v3/connectors/gemfire.md deleted file mode 100644 index f38bc2de..00000000 --- a/api/v3/connectors/gemfire.md +++ /dev/null @@ -1,99 +0,0 @@ -# Apache Geode/GemFire - ->Note: This feature is available in version 2.3.0+. - -[VMware Tanzu GemFire](https://tanzu.vmware.com/gemfire) is VMware's distribution of [Apache Geode](https://geode.apache.org/). This connector was built for using GemFire in an application by using the [GemFire Native Client](https://gemfire-native.docs.pivotal.io/100/gemfire-native-client/about-client-users-guide.html) on Cloud Foundry. It has not been extensively tested under other deployment configurations, but is best-effort supported for other situations as well. - ->WARNING: The GemFire Native Client currently supports only 64 bit applications running on Windows. See [GemFire Native Client System Requirements](https://gemfire-native.docs.pivotal.io/100/gemfire-native-client/system_requirements.html) for more. - -## Usage - -To use this connector: - -1. Create a GemFire service instance and bind it to your application. -1. Optionally, configure GemFire client settings. -1. Add the Steeltoe Cloud Foundry config provider to you `ConfigurationBuilder`. -1. Add GemFire classes to your DI container. - -### Get the GemFire Driver - -Follow the instructions in the [GemFire Native Client documentation](https://gemfire-native.docs.pivotal.io/100/gemfire-native-client/install-upgrade-native.html) for instructions on downloading the driver and getting started with general driver usage. - ->TIP: To avoid committing the driver to source, copy the [script](https://github.com/SteeltoeOSS/steeltoe/blob/2.x/src/Connectors/EnableGemFire.ps1) that Steeltoe's CI process uses in your own pipelines. You need a [legacy API token](https://network.pivotal.io/docs/api#how-to-authenticate) for the script to complete. - -### Add NuGet Reference - -[Add a reference to the appropriate Steeltoe Connector NuGet package](usage.md#add-nuget-references). - -### Configure Settings - -The GemFire client is highly configurable, beyond the scope of this documentation. -Steeltoe does not interact with `geode.properties` or `cache.xml` files, but any settings found under `gemfire:client:properties` in your application's configuration are applied to the `CacheFactory`. -Steeltoe tries to map the properties node in your configuration to a `Dictionary` and then applies each entry to GemFire through the `Set` method on `CacheFactory`. - -For example, if you want to set the log-level and connection timeout, use the following in your `application.json` file: - -```json -{ - "gemfire": { - "client": { - "properties": { - "log-level": "fine", - "connect-timeout": "100ms" - } - } - } -} -``` - -See the [GemFire documentation](https://gemfire-native.docs.pivotal.io/100/geode-native-client/configuring/sysprops.html) for a more complete list of settings to configure. - -### Cloud Foundry - -To use GemFire Cloud Cache on Cloud Foundry: - -1. Create a service instance -1. Bind the instance to your application via either a manifest file or the CLI (shown below) -1. Create region (If the application is unable to do so automatically) - -```bash -# Create CloudCache service instance -cf create-service p-cloudcache dev-plan myPCCService - -# Bind service to `myApp` -cf bind-service myApp myPCCService - -# Restage the app to pick up change -cf restage myApp -``` - -If your application fails to [programmatically create regions](https://gemfire-native.docs.pivotal.io/100/geode-native-client/regions/regions.html#programmatic-region-creation), use the [gfsh CLI](https://gemfire.docs.pivotal.io/98/gemfire/tools_modules/gfsh/chapter_overview.html) to create it. You need the gfsh URL and the cluster operator credentials provided in the service binding: - -```json -"p-cloudcache": [{ - ... - "urls": { - "gfsh": "https://cloudcache-serviceguid.run.pcfone.io/gemfire/v1", - ... - }, - "users": [{ - "password": "********", - "roles": [ "cluster_operator" ], - "username": "********" - ... - }] -}] -``` - -Use gfsh to connect to the cluster and create the region: - -```bash -gfsh>connect --url=https://cloudcache-someguid.run.pcfone.io/gemfire/v1 --user=cluster_operator_****** --password=****** - -Successfully connected to: GemFire Manager HTTP service @ https://cloudcache-someguid.run.pcfone.io/gemfire/v1 - -Cluster-0 gfsh>create region --name=SteeltoeDemo --type=PARTITION - Member | Status ------------------------------------------------- | ------------------------------------------------------------------------------------ -cacheserver-71461c75-ba87-4207-8d6d-c84be814a601 | Region "/SteeltoeDemo" created on "cacheserver-71461c75-ba87-4207-8d6d-c84be814a601" -``` diff --git a/api/v3/connectors/mysql.md b/api/v3/connectors/mysql.md index 5e53a513..faf7eb08 100644 --- a/api/v3/connectors/mysql.md +++ b/api/v3/connectors/mysql.md @@ -9,8 +9,8 @@ Currently, the connector supports the following providers: The following Steeltoe sample applications can help you understand how to use this connector: -* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/master/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a microservices based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. -* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/master/FreddysBBQ): A polyglot (Java and .NET) microservices-based sample application showing interoperability between Java- and .NET-based microservices running on Cloud Foundry, secured with OAuth2 Security Services and using Spring Cloud Services. +* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/3.x/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a microservices based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. +* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/3.x/FreddysBBQ): A polyglot (Java and .NET) microservices-based sample application showing interoperability between Java- and .NET-based microservices running on Cloud Foundry, secured with OAuth2 Security Services and using Spring Cloud Services. This connector provides a `IHealthContributor` object, which you can use in conjunction with the [Steeltoe Management Health](../management/health.md) check endpoint. diff --git a/api/v3/connectors/redis.md b/api/v3/connectors/redis.md index 3f0e701b..a560afcc 100644 --- a/api/v3/connectors/redis.md +++ b/api/v3/connectors/redis.md @@ -4,8 +4,8 @@ This connector simplifies using a Microsoft [`RedisCache`](https://docs.microsof The following Steeltoe sample applications are available to help you understand how to use this connector: -* [DataProtection](https://github.com/SteeltoeOSS/Samples/tree/master/Security/src/RedisDataProtectionKeyStore): A sample application showing how to use the Steeltoe DataProtection Key Storage Provider for Redis. -* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/master/MusicStore): A sample application showing how to use all of the Steeltoe components together in an ASP.NET Core application. This is a microservices-based application built from the MusicStore ASP.NET Core reference application provided by Microsoft. +* [DataProtection](https://github.com/SteeltoeOSS/Samples/tree/3.x/Security/src/RedisDataProtectionKeyStore): A sample application showing how to use the Steeltoe DataProtection Key Storage Provider for Redis. +* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/3.x/MusicStore): A sample application showing how to use all of the Steeltoe components together in an ASP.NET Core application. This is a microservices-based application built from the MusicStore ASP.NET Core reference application provided by Microsoft. This connector provides an `IHealthContributor`, which you can use in conjunction with the [Steeltoe Management Health](../management/health.md) check endpoint. diff --git a/api/v3/connectors/usage.md b/api/v3/connectors/usage.md index 655236b5..1b59ee84 100644 --- a/api/v3/connectors/usage.md +++ b/api/v3/connectors/usage.md @@ -140,4 +140,4 @@ builder.Configuration.AddKubernetesServiceBindings(); ### Additional Resources -To see the binding support in action, review the [Steeltoe PostgreSql EF Core Connector sample](https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/PostgreSqlEFCore). +To see the binding support in action, review the [Steeltoe PostgreSql EF Core Connector sample](https://github.com/SteeltoeOSS/Samples/tree/3.x/Connectors/src/PostgreSqlEFCore). diff --git a/api/v3/discovery/hashicorp-consul.md b/api/v3/discovery/hashicorp-consul.md index ac9a637a..6078036b 100644 --- a/api/v3/discovery/hashicorp-consul.md +++ b/api/v3/discovery/hashicorp-consul.md @@ -91,7 +91,7 @@ The health check for a Consul service instance defaults to `/actuator/health`, w ## Configuring Metadata -Steeltoe `IServiceInstance` has an `IDictionary Metadata` property that is used to obtain metadata settings for an instance. +Steeltoe `IServiceInstance` has an `IDictionary Metadata` property that is used to obtain metadata settings for an instance. Steeltoe `IServiceInstance` also has a `IEnumerable Tags`, which can be used to approximate metadata registration. diff --git a/api/v3/discovery/initialize-discovery-client.md b/api/v3/discovery/initialize-discovery-client.md index b3b019a1..7c36a93f 100644 --- a/api/v3/discovery/initialize-discovery-client.md +++ b/api/v3/discovery/initialize-discovery-client.md @@ -57,7 +57,7 @@ public class Program The `AddDiscoveryClient` extension shown above uses reflection to find assemblies containing a discovery client. Specifically, assemblies are located by the presence of the attribute `DiscoveryClientAssembly`, which contains a reference to an `IDiscoveryClientExtension` that does the work in configuring options and injecting the required service for the `IDiscoveryClient` to operate. ->If no discovery client package is found a [NoOpDiscoveryClient](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Discovery/src/ClientBase/SimpleClients/NoOpDiscoveryClient.cs) will be used. This will happen when no client has been added or if you publish your application with [`/p:PublishSingleFile=true`](https://docs.microsoft.com/dotnet/core/deploying/single-file)) +>If no discovery client package is found a [NoOpDiscoveryClient](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Discovery/src/ClientBase/SimpleClients/NoOpDiscoveryClient.cs) will be used. This will happen when no client has been added or if you publish your application with [`/p:PublishSingleFile=true`](https://docs.microsoft.com/dotnet/core/deploying/single-file)) To avoid this reflection-based approach, use declarative configuration of the client(s) you plan to use, like this: @@ -77,7 +77,7 @@ public class Program As of version 3.0.2, you may add multiple `Usexxx()` statements to this options builder, so long as only one is configured at runtime. ->If no extension is supplied for `AddServiceDiscovery`, a [NoOpDiscoveryClient](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Discovery/src/ClientBase/SimpleClients/NoOpDiscoveryClient.cs) will be used. +>If no extension is supplied for `AddServiceDiscovery`, a [NoOpDiscoveryClient](https://github.com/SteeltoeOSS/Steeltoe/blob/3.2/src/Discovery/src/ClientBase/SimpleClients/NoOpDiscoveryClient.cs) will be used. ## Other Extensions diff --git a/api/v3/discovery/kubernetes.md b/api/v3/discovery/kubernetes.md index def1aab6..95054d61 100644 --- a/api/v3/discovery/kubernetes.md +++ b/api/v3/discovery/kubernetes.md @@ -33,4 +33,4 @@ Using native Kubernetes service discovery ensures compatibility with additional The calling service then need only refer to names resolvable in a particular Kubernetes cluster. This may be as simple as using the service name as the host name, or it may require a fully qualified domain name (FQDN), such as `{service-name}.{namespace}.svc.{cluster}.local:{service-port}` depending on your environment. -In order to use both the discovery client programming model and the platform's native capabilities, a [NoOpDiscoveryClient](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Discovery/src/ClientBase/SimpleClients/NoOpDiscoveryClient.cs) can be used by either disabling other discovery clients, or not including them in the first place. +In order to use both the discovery client programming model and the platform's native capabilities, a [NoOpDiscoveryClient](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Discovery/src/ClientBase/SimpleClients/NoOpDiscoveryClient.cs) can be used by either disabling other discovery clients, or not including them in the first place. diff --git a/api/v3/discovery/netflix-eureka.md b/api/v3/discovery/netflix-eureka.md index d2633769..eb650c57 100644 --- a/api/v3/discovery/netflix-eureka.md +++ b/api/v3/discovery/netflix-eureka.md @@ -4,8 +4,8 @@ The Eureka client implementation lets applications register services with a Eure In addition to the Quick Start below, the following Steeltoe sample applications may help you to understand how to use this client: -* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/master/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a microservices-based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. -* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/master/FreddysBBQ): A polyglot microservices-based sample application showing interoperability between Java and .NET on Cloud Foundry. It is secured with OAuth2 Security Services and uses Spring Cloud Services. +* [MusicStore](https://github.com/SteeltoeOSS/Samples/tree/3.x/MusicStore): A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a microservices-based application built from the ASP.NET Core MusicStore reference app provided by Microsoft. +* [FreddysBBQ](https://github.com/SteeltoeOSS/Samples/tree/3.x/FreddysBBQ): A polyglot microservices-based sample application showing interoperability between Java and .NET on Cloud Foundry. It is secured with OAuth2 Security Services and uses Spring Cloud Services. ## Eureka Settings diff --git a/api/v3/logging/serilog-logger.md b/api/v3/logging/serilog-logger.md index 0caa5a19..8110ddf6 100644 --- a/api/v3/logging/serilog-logger.md +++ b/api/v3/logging/serilog-logger.md @@ -2,9 +2,9 @@ This logging provider extends the dynamic logging provider with [Serilog](https://serilog.net/). This allows logger levels configured via Serilog to be queried and modified at runtime via the loggers endpoint. -The source code for the Serilog Dynamic Logger can be found [here](https://github.com/SteeltoeOSS/steeltoe/tree/master/src/Logging/src/). +The source code for the Serilog Dynamic Logger can be found [here](https://github.com/SteeltoeOSS/steeltoe/tree/release/3.2/src/Logging/src/). -A sample working project can be found [here](https://github.com/SteeltoeOSS/Samples/tree/master/Management/src/CloudFoundry). +A sample working project can be found [here](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src/CloudFoundry). ## Usage diff --git a/api/v3/management/cloud-foundry.md b/api/v3/management/cloud-foundry.md index b0837751..818406eb 100644 --- a/api/v3/management/cloud-foundry.md +++ b/api/v3/management/cloud-foundry.md @@ -91,7 +91,7 @@ public class Startup //services.AddCloudFoundryActuators(Configuration); // if you prefer to add individual actuators //services.AddCloudFoundryActuator(Configuration); - ... + ... } public void Configure(IApplicationBuilder app) { diff --git a/api/v3/management/dbmigrations.md b/api/v3/management/dbmigrations.md index c2dc1846..7b011014 100644 --- a/api/v3/management/dbmigrations.md +++ b/api/v3/management/dbmigrations.md @@ -48,7 +48,7 @@ public void ConfigureServices(IServiceCollection services) { // Add Db Migration Actuator services.AddDbMigrationsActuator(); - + // Other registrations... } @@ -73,7 +73,7 @@ The default path for this endpoint is `/actuator/dbmigrations` and the response ```json { - "TestDataContext": + "TestDataContext": { "pendingMigrations": [ "2021078158434_AddNewTable" diff --git a/api/v3/management/health.md b/api/v3/management/health.md index 6b766fc0..3744feeb 100644 --- a/api/v3/management/health.md +++ b/api/v3/management/health.md @@ -125,7 +125,7 @@ For any group that has been defined, you may access health information from the Applications deployed on Kubernetes can provide information about their internal state with [Container Probes](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes). Depending on your [Kubernetes configuration](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/), the kubelet will call those probes and react to the result. -Steeltoe provides an [`ApplicationAvailability`](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Common/src/Common/Availability/ApplicationAvailability.cs) class for managing various types of application state. Out of the box support is provided for Liveness and Readiness, where each are exposed in a corresponding `IHealthContributor` and Health Group. +Steeltoe provides an [`ApplicationAvailability`](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Common/src/Common/Availability/ApplicationAvailability.cs) class for managing various types of application state. Out of the box support is provided for Liveness and Readiness, where each are exposed in a corresponding `IHealthContributor` and Health Group. In order to change the health contributors that are included in either of the two default groups, use the same style of configuration seen above. Please note that this will _replace_ the default groupings, so if you would like to _add_ an `IHealthContributor` you will need to include the original entry. These entries demonstrate including disk space in both groups: @@ -281,4 +281,4 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF } ``` -A complete example is available [here](https://github.com/SteeltoeOSS/Samples/tree/master/Management/src/AspDotNetCore/MicrosoftHealthChecks). +A complete example is available [here](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src/AspDotNetCore/MicrosoftHealthChecks). diff --git a/api/v3/management/info.md b/api/v3/management/info.md index 9a1cddaf..967362a8 100644 --- a/api/v3/management/info.md +++ b/api/v3/management/info.md @@ -14,7 +14,7 @@ The following table describes the `IInfoContributor` implementations provided by | `BuildInfoContributor` | Exposes file/version info for both the included version of Steeltoe and the application. | | `GitInfoContributor` | Exposes git information (if a `git.properties` file is available). | -For an example of how to use the above `GitInfoContributor` within MSBuild using [GitInfo](https://github.com/kzu/GitInfo), see the [Steeltoe management sample](https://github.com/SteeltoeOSS/Samples/tree/master/Management/src/AspDotNetCore/CloudFoundry) and the [CloudFoundry.csproj](https://github.com/SteeltoeOSS/Samples/blob/master/Management/src/AspDotNetCore/CloudFoundry/CloudFoundry.csproj) file. +For an example of how to use the above `GitInfoContributor` within MSBuild using [GitInfo](https://github.com/kzu/GitInfo), see the [Steeltoe management sample](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src/CloudFoundry) and the [CloudFoundry.csproj](https://github.com/SteeltoeOSS/Samples/blob/3.x/Management/src/CloudFoundry/CloudFoundry.csproj) file. If you wish to provide custom information for your application, create a class that implements the `IInfoContributor` interface and then add that to the `InfoEndpoint`. Details on how to add a contributor to the endpoint is provided later in this section. diff --git a/api/v3/management/using-endpoints.md b/api/v3/management/using-endpoints.md index 3258820b..857785d6 100644 --- a/api/v3/management/using-endpoints.md +++ b/api/v3/management/using-endpoints.md @@ -205,4 +205,4 @@ When using the `IHostBuilder` extensions, it can be added as shown: When called without arguments, the default profile is used. Other overloads allow passing a profile or a profile name. -A complete example is available here [here](https://github.com/SteeltoeOSS/Samples/tree/master/Management/src/SecureEndpoints). +A complete example is available here [here](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src/SecureEndpoints). diff --git a/api/v3/messaging/amqp.md b/api/v3/messaging/amqp.md index 5d6fa987..4b4d6c1d 100644 --- a/api/v3/messaging/amqp.md +++ b/api/v3/messaging/amqp.md @@ -1061,7 +1061,7 @@ public static MessageBuilder fromClonedMessage(Message message) <5> <1> The message created by the builder has a body that is a direct reference to the argument. <2> The message created by the builder has a body that is a new array containing a copy of bytes in the argument. -<3> The message created by the builder has a body that is a new array containing the range of bytes from the argument. +<3> The message created by the builder has a body that is a new array containing the range of bytes from the argument. See https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html[`Arrays.copyOfRange()`] for more details. <4> The message created by the builder has a body that is a direct reference to the body of the argument. The argument's properties are copied to a new `MessageProperties` object. @@ -1127,11 +1127,11 @@ The following listing shows the `BatchingStrategy` interface definition: ```Java public interface BatchingStrategy { - MessageBatch addToBatch(String exchange, String routingKey, Message message); + MessageBatch addToBatch(String exchange, String routingKey, Message message); - Date nextRelease(); + Date nextRelease(); - Collection releaseBatches(); + Collection releaseBatches(); } ``` @@ -1215,22 +1215,22 @@ The following listing shows those method definitions: ```Java boolean receiveAndReply(ReceiveAndReplyCallback callback) - throws AmqpException; + throws AmqpException; boolean receiveAndReply(String queueName, ReceiveAndReplyCallback callback) - throws AmqpException; + throws AmqpException; boolean receiveAndReply(ReceiveAndReplyCallback callback, - String replyExchange, String replyRoutingKey) throws AmqpException; + String replyExchange, String replyRoutingKey) throws AmqpException; boolean receiveAndReply(String queueName, ReceiveAndReplyCallback callback, - String replyExchange, String replyRoutingKey) throws AmqpException; + String replyExchange, String replyRoutingKey) throws AmqpException; boolean receiveAndReply(ReceiveAndReplyCallback callback, - ReplyToAddressCallback replyToAddressCallback) throws AmqpException; + ReplyToAddressCallback replyToAddressCallback) throws AmqpException; boolean receiveAndReply(String queueName, ReceiveAndReplyCallback callback, - ReplyToAddressCallback replyToAddressCallback) throws AmqpException; + ReplyToAddressCallback replyToAddressCallback) throws AmqpException; ``` The `AmqpTemplate` implementation takes care of the `receive` and `reply` phases. @@ -1341,7 +1341,7 @@ The following listing shows the definition of `FunctionalInterface`: @FunctionalInterface public interface ReplyingMessageListener { - R handleMessage(T t); + R handleMessage(T t); } ``` @@ -3225,7 +3225,7 @@ The following listing shows examples of how to manually wire up the beans: } ``` -A complete example of a `RabbitTemplate` wired with a fixed reply queue, together with a "remote" listener container that handles the request and returns the reply is shown in [this test case](https://github.com/spring-projects/spring-amqp/tree/master/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/listener/JavaConfigFixedReplyQueueTests.java). +A complete example of a `RabbitTemplate` wired with a fixed reply queue, together with a "remote" listener container that handles the request and returns the reply is shown in [this test case](https://github.com/spring-projects/spring-amqp/tree/main/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/listener/JavaConfigFixedReplyQueueTests.java). >IMPORTANT: When the reply times out (`replyTimeout`), the `sendAndReceive()` methods return null. @@ -3697,17 +3697,17 @@ public static class Config { @Bean public DirectExchange e1() { - return new DirectExchange("e1", false, true); + return new DirectExchange("e1", false, true); } @Bean public Queue q1() { - return new Queue("q1", false, false, true); + return new Queue("q1", false, false, true); } @Bean public Binding b1() { - return BindingBuilder.bind(q1()).to(e1()).with("k1"); + return BindingBuilder.bind(q1()).to(e1()).with("k1"); } @Bean @@ -4383,10 +4383,10 @@ The following example shows how to do so: ```Java @Bean public StatefulRetryOperationsInterceptor interceptor() { - return RetryInterceptorBuilder.stateful() - .maxAttempts(5) - .backOffOptions(1000, 2.0, 10000) // initialInterval, multiplier, maxInterval - .build(); + return RetryInterceptorBuilder.stateful() + .maxAttempts(5) + .backOffOptions(1000, 2.0, 10000) // initialInterval, multiplier, maxInterval + .build(); } ``` @@ -4451,10 +4451,10 @@ The following example shows how to set a `RepublishMessageRecoverer` as the reco ```Java @Bean RetryOperationsInterceptor interceptor() { - return RetryInterceptorBuilder.stateless() - .maxAttempts(5) - .recoverer(new RepublishMessageRecoverer(amqpTemplate(), "something", "somethingelse")) - .build(); + return RetryInterceptorBuilder.stateless() + .maxAttempts(5) + .recoverer(new RepublishMessageRecoverer(amqpTemplate(), "something", "somethingelse")) + .build(); } ``` diff --git a/api/v3/messaging/rabbitmq-intro.md b/api/v3/messaging/rabbitmq-intro.md index bdfac153..5044ee46 100644 --- a/api/v3/messaging/rabbitmq-intro.md +++ b/api/v3/messaging/rabbitmq-intro.md @@ -239,7 +239,7 @@ Alternatively, you could configure the same connection settings using the `Addre >When specifying addresses as shown above, the `host` and `port` properties are ignored. If the address uses the `amqps` protocol, SSL support is automatically enabled. -See [`RabbitOptions`](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Messaging/src/RabbitMQ/Config/RabbitOptions.cs) for more of the supported options. +See [`RabbitOptions`](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Messaging/src/RabbitMQ/Config/RabbitOptions.cs) for more of the supported options. >TIP: See [Understanding AMQP, the protocol used by RabbitMQ](https://www.rabbitmq.com/tutorials/amqp-concepts.html) for more details. @@ -365,7 +365,7 @@ The latter is the mechanism used when retries are enabled and the maximum number The Steeltoe RabbitMQHost extends the Microsoft Generic Host and provides for auto configuration of Steeltoe RabbitMQ services. > [!NOTE] -> For more detailed examples of using the RabbitMQ Host, please refer to the [Messaging](https://github.com/SteeltoeOSS/Samples/tree/main/Messaging/src) solutions in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples of using the RabbitMQ Host, please refer to the [Messaging](https://github.com/SteeltoeOSS/Samples/tree/3.x/Messaging/src) solutions in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). Below are two code snippets within `Program.cs` and `Startup.cs` that demonstrate the usage of RabbitMQHost: @@ -407,7 +407,7 @@ When using the WebApplication Builder, or if you prefer not to use the RabbitMQH // Add Steeltoe services for RabbitMQ builder.services.AddRabbitServices(); - + // Add the Steeltoe RabbitMQ admin client... will be used to declare queues below builder.services.AddRabbitAdmin(); @@ -416,4 +416,4 @@ When using the WebApplication Builder, or if you prefer not to use the RabbitMQH // ... } -``` \ No newline at end of file +``` diff --git a/api/v3/messaging/rabbitmq-reference.md b/api/v3/messaging/rabbitmq-reference.md index 6ce2fd63..fabc62b0 100644 --- a/api/v3/messaging/rabbitmq-reference.md +++ b/api/v3/messaging/rabbitmq-reference.md @@ -516,7 +516,7 @@ We will explore message sending and reception, respectively, in [Sending Message ### Adding Retry Capabilities You can now configure the `RabbitTemplate` to use a `RetryTemplate` to help with handling problems with broker connectivity. -See the [Steeltoe Retry](https://github.com/SteeltoeOSS/Steeltoe/tree/master/src/Common/src/Common/Retry) framework for complete information. +See the [Steeltoe Retry](https://github.com/SteeltoeOSS/Steeltoe/tree/release/3.2/src/Common/src/Common/Retry) framework for complete information. The following is only one example that uses a [Polly](http://www.thepollyproject.org/) based retry policy, which makes three tries before throwing the exception to the caller. ```csharp @@ -2355,11 +2355,11 @@ Those methods are quite useful for request-reply scenarios, since they handle th Similar request-reply methods are also available where the `IMessageConverter` is applied to both the request and reply. Those methods are named `ConvertSendAndReceive`. -See the [`RabbitTemplate`](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Messaging/src/RabbitMQ/Core/RabbitTemplate.cs) code for more detail. +See the [`RabbitTemplate`](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Messaging/src/RabbitMQ/Core/RabbitTemplate.cs) code for more detail. Each of the `SendAndReceive` method variants has an overloaded version that takes `CorrelationData`. Together with a properly configured connection factory, this enables the receipt of publisher confirms for the send side of the operation. -See [Template Publisher Confirms and Returns](#template-publisher-confirms-and-returns) and the [`RabbitTemplate`](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Messaging/src/RabbitMQ/Core/RabbitTemplate.cs) code for more detail. +See [Template Publisher Confirms and Returns](#template-publisher-confirms-and-returns) and the [`RabbitTemplate`](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Messaging/src/RabbitMQ/Core/RabbitTemplate.cs) code for more detail. You can configure the `RabbitTemplate` with the `NoLocalReplyConsumer` option to control a `noLocal` flag for the reply RabbitMQ Client `BasicConsume()` operation. This is `false` by default. @@ -2480,7 +2480,7 @@ If the reply queue is configured to send rejected messages to a dead letter exch To do so, bind a queue to the configured dead letter exchange with a routing key equal to the reply queue's name. See the [RabbitMQ Dead Letter Documentation](https://www.rabbitmq.com/dlx.html) for more information about configuring dead lettering. -You can also take a look at the [FixedReplyQueueDeadLetterTest](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Messaging/test/RabbitMQ.Test/Core/FixedReplyQueueDeadLetterTest.cs) test case for an example. +You can also take a look at the [FixedReplyQueueDeadLetterTest](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Messaging/test/RabbitMQ.Test/Core/FixedReplyQueueDeadLetterTest.cs) test case for an example. ## Configuring the Broker @@ -2696,7 +2696,7 @@ var fooExchange = ExchangeBuilder.DirectExchange("foo") ``` -See the code for [QueueBuilder](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Messaging/src/RabbitMQ/Config/QueueBuilder.cs) and [ExchangeBuilder](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Messaging/src/RabbitMQ/Config/ExchangeBuilder.cs) for more information. +See the code for [QueueBuilder](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Messaging/src/RabbitMQ/Config/QueueBuilder.cs) and [ExchangeBuilder](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Messaging/src/RabbitMQ/Config/ExchangeBuilder.cs) for more information. The `ExchangeBuilder` creates durable exchanges by default, to be consistent with the simple constructors on the individual `AbstractExchange` classes. To make a non-durable exchange with the builder, use `.Durable(false)` before invoking `.Build()`. @@ -3077,7 +3077,7 @@ Since 2.7.0, rejected messages go to the front of the queue, in a similar manner ### Using RabbitTransactionManager -The [RabbitTransactionManager](https://github.com/SteeltoeOSS/Steeltoe/blob/master/src/Messaging/src/RabbitMQ/Transaction/RabbitTransactionManager.cs) is the only `IPlatformTransactionManager` supported at this point. +The [RabbitTransactionManager](https://github.com/SteeltoeOSS/Steeltoe/blob/release/3.2/src/Messaging/src/RabbitMQ/Transaction/RabbitTransactionManager.cs) is the only `IPlatformTransactionManager` supported at this point. This transaction manager is an implementation of the [`IPlatformTransactionManager`] interface and should be used with a single RabbitMQ `IConnectionFactory`. >IMPORTANT: This strategy is not able to provide XA transactions - for example, in order to share transactions between messaging and database access. @@ -3247,10 +3247,10 @@ The following example shows how to set a `RepublishMessageRecoverer` as the reco ```Java @Bean RetryOperationsInterceptor interceptor() { - return RetryInterceptorBuilder.stateless() - .maxAttempts(5) - .recoverer(new RepublishMessageRecoverer(amqpTemplate(), "something", "somethingelse")) - .build(); + return RetryInterceptorBuilder.stateless() + .maxAttempts(5) + .recoverer(new RepublishMessageRecoverer(amqpTemplate(), "something", "somethingelse")) + .build(); } ``` diff --git a/api/v3/security/mtls.md b/api/v3/security/mtls.md index e77fe319..ed064e21 100644 --- a/api/v3/security/mtls.md +++ b/api/v3/security/mtls.md @@ -45,7 +45,7 @@ The above example will create self-signed certificates with an OrgId of `a8fef16 ### Securing Endpoints -In order to use identity certificates for authorization in a service application, services need to be configured and activated and polices need to be applied. +In order to use identity certificates for authorization in a service application, services need to be configured and activated and policies need to be applied. #### Adding and using services @@ -76,7 +76,7 @@ public void Configure(IApplicationBuilder app, ...) >These steps are only required on services that are receiving mTLS-secured requests -#### Applying Authorization Polices +#### Applying Authorization Policies Steeltoe includes policies for validating that a request came from an application in the same org or the space. Once you have done the work in the `Startup` class, you can secure endpoints by using the standard ASP.NET Core `Authorize` attribute with one of these security policies. diff --git a/api/v3/security/sso-oauth2.md b/api/v3/security/sso-oauth2.md index 52723146..c6b9324b 100644 --- a/api/v3/security/sso-oauth2.md +++ b/api/v3/security/sso-oauth2.md @@ -72,7 +72,7 @@ The Steeltoe OAuth2 security provider options are based on [`Microsoft.AspNetCor ### Cloud Foundry -As mentioned earlier, there are two OAuth-compatible services available on Cloud Foundry. We recommend you read the official documentation ([UAA Server](https://github.com/cloudfoundry/uaa) and [TAS SSO](https://docs.pivotal.io/p-identity/1-5/getting-started.html)) or follow the instructions included in the samples for [UAA Server](https://github.com/SteeltoeOSS/Samples/blob/master/Security/src/AspDotNetCore/CloudFoundrySingleSignon/README.md) and [TAS SSO](https://github.com/SteeltoeOSS/Samples/blob/master/Security/src/AspDotNetCore/CloudFoundrySingleSignon/README-SSO.md) to quickly learn how to create and bind OAuth2 services. +As mentioned earlier, there are two OAuth-compatible services available on Cloud Foundry. We recommend you read the official documentation ([UAA Server](https://github.com/cloudfoundry/uaa) and [TAS SSO](https://docs.pivotal.io/p-identity/1-5/getting-started.html)) or follow the instructions included in the samples for [UAA Server](https://github.com/SteeltoeOSS/Samples/blob/3.x/Security/src/CloudFoundrySingleSignon/README.md) and [TAS SSO](https://github.com/SteeltoeOSS/Samples/blob/3.x/Security/src/CloudFoundrySingleSignon/README-SSO.md) to quickly learn how to create and bind OAuth2 services. Regardless of which provider you choose, once the service is bound to your application, the settings are available in `VCAP_SERVICES`. diff --git a/api/v3/stream/data-flow-stream.md b/api/v3/stream/data-flow-stream.md index effe7e3c..5ec55192 100644 --- a/api/v3/stream/data-flow-stream.md +++ b/api/v3/stream/data-flow-stream.md @@ -32,7 +32,7 @@ In this guide, we describe how you can register these Steeltoe based components ## Development -The [samples repo](https://github.com/SteeltoeOSS/Samples/tree/main/Stream) has a number of Steeltoe Stream sample applications. For this example we will be using the `CloudDataFlowLogToUpperProcessor` sample, which implements an `IProcessor` interface and the `CloudDataFlowLogSink` sample, which implements an `ISink` interface. +The [samples repo](https://github.com/SteeltoeOSS/Samples/tree/3.x/Stream) has a number of Steeltoe Stream sample applications. For this example we will be using the `CloudDataFlowLogToUpperProcessor` sample, which implements an `IProcessor` interface and the `CloudDataFlowLogSink` sample, which implements an `ISink` interface. For an `ISource` use the `HttpSource` application available at `maven://org.springframework.cloud.stream.app:http-source-rabbit:3.0.1` Spring Cloud team publishes a number of sample applications as `maven` and `docker` artifacts at the `https://repo.spring.io` Maven repository. These pre-packaged applications can be used with Steeltoe Stream. diff --git a/api/v3/stream/rabbit-binder.md b/api/v3/stream/rabbit-binder.md index 6f4f2820..562e8691 100644 --- a/api/v3/stream/rabbit-binder.md +++ b/api/v3/stream/rabbit-binder.md @@ -662,7 +662,7 @@ There are similar settings used when declaring a dead-letter exchange/queue, whe ## Retry With the RabbitMQ Binder When retry is enabled within the binder, the listener container thread is suspended for any back off periods that are configured. -This might be important when strict ordering is required with a single consumer. However, for other use cases, it prevents other messages from being processed on that thread. +This might be important when strict ordering is required with a single consumer. However, for other use cases, it prevents other messages from being processed on that thread. An alternative to using binder retry is to set up dead lettering with time to live on the dead-letter queue (DLQ) as well as dead-letter configuration on the DLQ itself. See [RabbitMQ Binder Settings](#rabbitmq-binder-settings) for more information about the settings discussed here. You can use the following example configuration to enable this feature: @@ -731,7 +731,7 @@ After 5 seconds, the message expires and is routed to the original queue by usin } [StreamListener(ISink.INPUT)] - public void Listen(string input, + public void Listen(string input, [Header(Name ="x-death", Required = false)] IDictionary death) { @@ -800,7 +800,7 @@ The examples assume the original destination is `so8400in` and the consumer grou The first two examples are for when the destination is *not* partitioned: ```csharp -public class Program +public class Program { private const string ORIGINAL_QUEUE = "so8400in.so8400"; private const string DLQ = ORIGINAL_QUEUE + ".dlq"; @@ -836,7 +836,7 @@ public class Program [DeclareQueue(Name = PARKING_LOT)] [RabbitListener(DLQ)] public void RePublish( - string text, + string text, [Header(Name = X_RETRIES_HEADER, Required = false)] int? retriesHeader) { @@ -844,7 +844,7 @@ public class Program .WithPayload(Encoding.UTF8.GetBytes(text)) .SetHeader(X_RETRIES_HEADER, (retriesHeader ?? 0) + 1) .Build(); - + if (!retriesHeader.HasValue || retriesHeader < 3) { rabbitTemplate.Send(ORIGINAL_QUEUE, failedMessage); @@ -1003,7 +1003,7 @@ When `republishToDlq` is `False`, RabbitMQ publishes the message to the DLX/DLQ else { throw new RabbitRejectAndDontRequeueException("failed"); - } + } } else { @@ -1144,7 +1144,7 @@ The following C# and JSON configuration examples show how to configure the produ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - await Task.Delay(5000, stoppingToken); // Wait for the Infrastructure to be setup correctly; + await Task.Delay(5000, stoppingToken); // Wait for the Infrastructure to be setup correctly; while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); diff --git a/api/v3/stream/standalone-stream-rabbitmq.md b/api/v3/stream/standalone-stream-rabbitmq.md index bb9e3327..be9391b7 100644 --- a/api/v3/stream/standalone-stream-rabbitmq.md +++ b/api/v3/stream/standalone-stream-rabbitmq.md @@ -5,7 +5,7 @@ In another guide, we [deploy these applications using Data Flow](./data-flow-str Taking the time to deploy the applications manually will provide you with a better understanding of the steps that Data Flow automates for you. The following sections describe how to build these applications from scratch. -If you prefer, you can clone the Steeltoe [sample applications](https://github.com/SteeltoeOSS/Samples/blob/main/Stream/UsageCost), and proceed to the [deployment](#deployment) section. +If you prefer, you can clone the Steeltoe [sample applications](https://github.com/SteeltoeOSS/Samples/blob/3.x/Stream/UsageCost), and proceed to the [deployment](#deployment) section. ## Development @@ -309,7 +309,7 @@ Create a new .NET Console project and add the NuGet packages as referred in the To create the business logic: -1. Create a `UsageCostDetail` class that looks like [UsageCostDetail.cs](https://github.com/SteeltoeOSS/Samples/blob/main/Stream/UsageCost/UsageLogger/UsageCostDetail.cs). +1. Create a `UsageCostDetail` class that looks like [UsageCostDetail.cs](https://github.com/SteeltoeOSS/Samples/blob/3.x/Stream/UsageCost/UsageLogger/UsageCostDetail.cs). The `UsageCostDetail` class contains `UserId`, `CallCost`, and `DataCost` properties. 1. Create the `UsageCostLogger` class, which receives the `UsageCostDetail` message and logs it. The following listing shows the source code: diff --git a/api/v3/stream/stream-reference.md b/api/v3/stream/stream-reference.md index 93f54b69..e6f511e6 100644 --- a/api/v3/stream/stream-reference.md +++ b/api/v3/stream/stream-reference.md @@ -66,7 +66,7 @@ Two types of consumer are supported by the Stream infrastructure: * Message-driven (sometimes referred to as Asynchronous) * Polled (sometimes referred to as Synchronous) -The default is to implement message driven consumers, but when you wish to control the rate at which messages are processed, you might want to use a synchronous consumer. +The default is to implement message driven consumers, but when you wish to control the rate at which messages are processed, you might want to use a synchronous consumer. ### Consumer Groups @@ -169,7 +169,7 @@ Out of the box, Steeltoe provides the three bindings that are commonly used in m The following listing shows the definition of the various interfaces: ```csharp -public interface ISink +public interface ISink { const string INPUT = "input"; @@ -255,7 +255,7 @@ In this case, an implementation of `IPollableMessageSource` is bound to the chan As mentioned earlier the `Input` and `Output` attributes allow you to specify a customized channel name for the channel, as shown in the following example: ```csharp -public interface IBarista +public interface IBarista { [Input("InboundOrders")] ISubscribableChannel Orders { get; } @@ -365,7 +365,7 @@ In the following example of a `StreamListener` with dispatching conditions, all [EnableBinding(typeof(IProcessor))] public class CatsAndDogs { - + [StreamListener(ISink.INPUT, "Headers['type']=='Dog'")] public void Handle(Dog dog) { @@ -389,7 +389,7 @@ Consider the following example: The code below is perfectly valid. It compiles and deploys without any issues, yet it never produces the result you expect. ```csharp -public class Program +public class Program { static async Task Main(string[] args) { @@ -405,13 +405,13 @@ public class CatsAndDogs { [StreamListener(Target = Sink.INPUT, Condition = "Payload.GetType().Name=='Dog'")] - public void Bark(Dog dog) + public void Bark(Dog dog) { // handle the message } [StreamListener(Target = Sink.INPUT, Condition = "Payload.GetType().Name=='Cat'")] - public void Purr(Cat cat) + public void Purr(Cat cat) { // handle the message } @@ -441,14 +441,14 @@ Here is the example of the Processor application exposing message handler as `ja @EnableBinding(Processor.class) public class MyFunctionBootApp { - public static void main(String[] args) { - SpringApplication.run(MyFunctionBootApp.class, "--spring.cloud.stream.function.definition=toUpperCase"); - } + public static void main(String[] args) { + SpringApplication.run(MyFunctionBootApp.class, "--spring.cloud.stream.function.definition=toUpperCase"); + } - @Bean - public Function toUpperCase() { - return s -> s.toUpperCase(); - } + @Bean + public Function toUpperCase() { + return s -> s.toUpperCase(); + } } ``` In the above you we simply define a bean of type `java.util.function.Function` called _toUpperCase_ and identify it as a bean to be used as message handler @@ -461,13 +461,13 @@ Here is the example of a Source application defined as `java.util.function.Suppl @SpringBootApplication @EnableBinding(Source.class) public static class SourceFromSupplier { - public static void main(String[] args) { - SpringApplication.run(SourceFromSupplier.class, "--spring.cloud.stream.function.definition=date"); - } - @Bean - public Supplier date() { - return () -> new Date(12345L); - } + public static void main(String[] args) { + SpringApplication.run(SourceFromSupplier.class, "--spring.cloud.stream.function.definition=date"); + } + @Bean + public Supplier date() { + return () -> new Date(12345L); + } } ``` @@ -476,13 +476,13 @@ Here is the example of a Processor application defined as `java.util.function.Fu @SpringBootApplication @EnableBinding(Processor.class) public static class ProcessorFromFunction { - public static void main(String[] args) { - SpringApplication.run(ProcessorFromFunction.class, "--spring.cloud.stream.function.definition=toUpperCase"); - } - @Bean - public Function toUpperCase() { - return s -> s.toUpperCase(); - } + public static void main(String[] args) { + SpringApplication.run(ProcessorFromFunction.class, "--spring.cloud.stream.function.definition=toUpperCase"); + } + @Bean + public Function toUpperCase() { + return s -> s.toUpperCase(); + } } ``` @@ -491,13 +491,13 @@ Here is the example of a Sink application defined as `java.util.function.Consume @EnableAutoConfiguration @EnableBinding(Sink.class) public static class SinkFromConsumer { - public static void main(String[] args) { - SpringApplication.run(SinkFromConsumer.class, "--spring.cloud.stream.function.definition=sink"); - } - @Bean - public Consumer sink() { - return System.out::println; - } + public static void main(String[] args) { + SpringApplication.run(SinkFromConsumer.class, "--spring.cloud.stream.function.definition=sink"); + } + @Bean + public Consumer sink() { + return System.out::println; + } } ``` @@ -512,13 +512,13 @@ For example: @EnableAutoConfiguration @EnableBinding(Processor.class) public static class SinkFromConsumer { - public static void main(String[] args) { - SpringApplication.run(SinkFromConsumer.class, "--spring.cloud.stream.function.definition=reactiveUpperCase"); - } - @Bean - public Function, Flux> reactiveUpperCase() { - return flux -> flux.map(val -> val.toUpperCase()); - } + public static void main(String[] args) { + SpringApplication.run(SinkFromConsumer.class, "--spring.cloud.stream.function.definition=reactiveUpperCase"); + } + @Bean + public Function, Flux> reactiveUpperCase() { + return flux -> flux.map(val -> val.toUpperCase()); + } } ``` ##### Functional Composition @@ -528,7 +528,7 @@ As an example let's add the following function bean to the application defined a ```java @Bean public Function wrapInQuotes() { - return s -> "\"" + s + "\""; + return s -> "\"" + s + "\""; } ``` and modify the `spring.cloud.stream.function.definition` property to reflect your intention to compose a new function from both ‘toUpperCase’ and ‘wrapInQuotes’. @@ -597,7 +597,7 @@ Given the polled consumer in the preceding example, you might use it as follows: protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - await Task.Delay(5000, stoppingToken); // Wait for setup on first poll + await Task.Delay(5000, stoppingToken); // Wait for setup on first poll while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); @@ -644,11 +644,11 @@ You can override that behavior by taking responsibility for the acknowledgment, ```csharp public void HandleMessage(IMessage message) { - try + try { StaticMessageHeaderAccessor.GetAcknowledgmentCallback(message).IsAutoAck = False; // e.g. hand off to another thread which can perform the ack or Acknowledge(Status.REQUEUE) - } + } catch (Exception e) { // handle failure @@ -675,7 +675,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); - try + try { if (!_binding.DestIn.Poll(this), typeof(Dictionary)) { @@ -691,11 +691,11 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) public void HandleMessage(IMessage message) { - try + try { var payload = ((Dictionary) message.Payload); .... - } + } catch (Exception e) { // handle failure @@ -737,13 +737,13 @@ spring:cloud:stream:bindings:input:group=myGroup ```csharp [StreamListener(ISink.INPUT)] // destination name 'input.myGroup' -public void Handle(Person value) +public void Handle(Person value) { throw new Exception("BOOM!"); } [ServiceActivator(IProcessor.INPUT + ".myGroup.errors")] //channel name 'input.myGroup.errors' -public void Error(IMessage message) +public void Error(IMessage message) { Console.WriteLine("Handling ERROR: " + message); } @@ -762,7 +762,7 @@ a *global error channel* by bridging each individual error channel to the channe ```csharp [ServiceActivator("errorChannel")] -public void Error(IMessage message) +public void Error(IMessage message) { Console.WriteLine("Handling ERROR: " + message); } @@ -922,7 +922,7 @@ The Binder SPI consists of a number of interfaces, out-of-the box utility classe The key point of the SPI is the `IBinder` interface(s), which is a strategy for connecting inputs and outputs to external middleware. The following listing shows the definition of the `IBinder` interface: ```csharp -public interface IBinder : IServiceNameAware +public interface IBinder : IServiceNameAware { Type TargetType { get; } IBinding BindConsumer(string name, string group, object inboundTarget, IConsumerOptions consumerOptions); @@ -1336,7 +1336,7 @@ See [Error Handling](#error-handling) for more information. Default: `False`. -### Dynamically Bound Destinations +### Dynamically Bound Destinations Besides the channels defined by using `EnableBinding` attribute, Stream lets applications send messages to dynamically bound destinations. This is useful, for example, when the target destination needs to be determined at runtime. @@ -1345,7 +1345,7 @@ Applications can do so by using the `BinderAwareChannelResolver` service (which The `spring.cloud.stream.dynamicDestinations` setting can be used for restricting the dynamic destination names to a known set (whitelisting). If this property is not set, any destination can be bound dynamically. -The `BinderAwareChannelResolver` can be used directly, as shown in the following example of a console application receiving messages from an input source and deciding the target channel based on the body of the message (see [Dynamic Destination Sample](https://github.com/SteeltoeOSS/Samples/tree/main/Stream/DynamicDestinationMessaging) for full solution): +The `BinderAwareChannelResolver` can be used directly, as shown in the following example of a console application receiving messages from an input source and deciding the target channel based on the body of the message (see [Dynamic Destination Sample](https://github.com/SteeltoeOSS/Samples/tree/3.x/Stream/DynamicDestinationMessaging) for full solution): Program.cs @@ -1359,7 +1359,7 @@ class Program { var host = StreamHost.CreateDefaultBuilder(args).Build(); - binderAwareChannelResolver = + binderAwareChannelResolver = host.Services.GetService>() as BinderAwareChannelResolver; await host.StartAsync(); diff --git a/api/v3/tracing/distributed-tracing-exporting.md b/api/v3/tracing/distributed-tracing-exporting.md index baa53698..5b84a708 100644 --- a/api/v3/tracing/distributed-tracing-exporting.md +++ b/api/v3/tracing/distributed-tracing-exporting.md @@ -92,7 +92,7 @@ Steeltoe will discover and automatically configure the Open Telemetry Protocol e ### Use Wavefront Exporter (Tanzu Observability) -Steeltoe will automatically send traces to Wavefront if the following settings are provided. Note that these are shared between tracing and metrics and the Wavefront Trace exporter is activated by the presence of a valid `Uri` and `ApiToken` combination. +Steeltoe will automatically send traces to Wavefront if the following settings are provided. Note that these are shared between tracing and metrics and the Wavefront Trace exporter is activated by the presence of a valid `Uri` and `ApiToken` combination. | Key | Description | Default | | --- | --- | --- | @@ -110,8 +110,8 @@ In addition, the following settings can be used to set the application and servi | Key | Description | Default | | --- | --- | --- | -| `Source`| Unique identifier for the app instance that is publishing metrics to Wavefront | DNS name +| `Source`| Unique identifier for the app instance that is publishing metrics to Wavefront | DNS name | `Name` | Name of the application | SteeltoeApp | | `Service` | Name of the service | SteeltoeService | -**Note**: **Each setting above must be prefixed with `Wavefront:Application`** \ No newline at end of file +**Note**: **Each setting above must be prefixed with `Wavefront:Application`** diff --git a/api/v4/bootstrap/index.md b/api/v4/bootstrap/index.md new file mode 100644 index 00000000..f911a19e --- /dev/null +++ b/api/v4/bootstrap/index.md @@ -0,0 +1,94 @@ +# Application Bootstrapping + +To improve the Steeltoe developer experience, this feature allows the configuration of most Steeltoe components with a single line of code in your application. The package is named [`Steeltoe.Bootstrap.AutoConfiguration`](https://github.com/SteeltoeOSS/Steeltoe/tree/main/src/Bootstrap/src/AutoConfiguration), and it works by calling the same extension methods that are already included in Steeltoe packages to automatically wire up each of those components. + +Get started by adding a reference to the AutoConfiguration package (you may want to add other Steeltoe references at this point too, see [the table below](#supported-steeltoe-packages) for the full list of what's supported): + +```shell +dotnet add package Steeltoe.Bootstrap.AutoConfiguration +``` + +After adding the NuGet reference(s), simply include `.AddSteeltoe()` like you see in the code below and you're all set with the basic implementation. + +```csharp +using Steeltoe.Bootstrap.AutoConfiguration; + +var builder = WebApplication.CreateBuilder(args); +builder.AddSteeltoe(); +``` + +## Supported Steeltoe Packages + +`Steeltoe.Bootstrap.AutoConfiguration` is not a meta-package. In order for a Steeltoe feature to be automatically bootstrapped in the application, the appropriate NuGet package must also be referenced. The following table describes the Steeltoe package that is required to light up a feature and any additional packages that may also be installed: + +| Feature Description | Steeltoe Package | Additional Packages | +| --- | --- | --- | +| [Config Server Configuration Provider](../configuration/config-server-provider.md) | `Steeltoe.Configuration.ConfigServer` | Optional: `Steeltoe.Discovery.Eureka` to use discovery-first | +| [Cloud Foundry Configuration Provider](../configuration/cloud-foundry-provider.md) |`Steeltoe.Configuration.CloudFoundry` | N/A | +| [Random Value Configuration Provider](../configuration/random-value-provider.md) |`Steeltoe.Configuration.RandomValue` | N/A | +| [Placeholder Configuration Provider](../configuration/placeholder-provider.md) |`Steeltoe.Configuration.Placeholder` | N/A | +| [Encrypted Configuration Provider](../configuration/decryption-provider.md) | `Steeltoe.Configuration.Encryption` | N/A | +| [Spring Boot Configuration Provider](../configuration/spring-boot-provider.md) | `Steeltoe.Configuration.SpringBoot` | N/A | +| [Connectors](../connectors/index.md) |`Steeltoe.Connectors` | Required: Supported driver [^1] (MySQL, PostgreSQL, SQL Server, MongoDB, CosmosDB, Redis, RabbitMQ) | +| [Eureka Service Discovery](../discovery/netflix-eureka.md) |`Steeltoe.Discovery.Eureka` | Optional: `Steeltoe.Management.Endpoint` for health checks | +| [Consul Service Discovery](../discovery/hashicorp-consul.md) |`Steeltoe.Discovery.Consul` | N/A | +| [Configuration-based Service Discovery](../discovery/configuration-based.md) |`Steeltoe.Discovery.Configuration` | N/A | +| [Dynamic Console Logging](../logging/dynamic-console-logging.md) | `Steeltoe.Logging.DynamicConsole` | N/A | +| [Dynamic Serilog Logging](../logging/dynamic-serilog-logging.md) | `Steeltoe.Logging.DynamicSerilog` | N/A | +| [Actuators](../management/index.md) | `Steeltoe.Management.Endpoint` | N/A | +| [Distributed Tracing](../tracing/index.md) | `Steeltoe.Management.Tracing` | N/A | + +[^1]: Individual connector clients will only be configured if a corresponding supported driver NuGet package reference is also included. + +## Excluding Components + +If you wish to exclude a component from the automatic bootstrap process, you may add the feature's assembly name to the exclusions list. One example where this feature would be desired is if you want to control the order in which configuration providers are added. This example shows how to provide exclusions: + +```csharp +using Steeltoe.Bootstrap.AutoConfiguration; + +HashSet assemblyNamesToExclude = [SteeltoeAssemblyNames.ConfigurationConfigServer]; +builder.AddSteeltoe(assemblyNamesToExclude); +``` + +> [!TIP] +> The static class `SteeltoeAssemblyNames` enables to easily find the name of any specific assembly to exclude. + +## Logging inside Configuration Providers + +For some Steeltoe components, primarily configuration providers, providing a `LoggerFactory` is required to retrieve logs for debugging. Use the optional parameter to provide one as needed: + +```csharp +using Microsoft.Extensions.Logging.Debug; +using Steeltoe.Bootstrap.AutoConfiguration; + +var loggerFactory = LoggerFactory.Create(loggingBuilder => +{ + loggingBuilder.AddDebug(); // or: loggingBuilder.AddConsole(); + loggingBuilder.SetMinimumLevel(LogLevel.Debug); +}); + +builder.AddSteeltoe(loggerFactory); +``` + +Alternatively, you can use `BootstrapLoggerFactory`. It logs to the console until the service container has been built. +Once the service container has become available, it automatically upgrades existing loggers to use the application configuration. + +```csharp +using Steeltoe.Bootstrap.AutoConfiguration; +using Steeltoe.Common.Logging; + +var loggerFactory = BootstrapLoggerFactory.CreateConsole(); +builder.AddSteeltoe(loggerFactory); +``` + +## Limitations + +At this time there is no support for: + +* Features that need to be configured directly in `IApplicationBuilder`, such as Cloud Foundry SSO and JWT. +* Features that require a custom type (such as a `DbContext`) for setup. + +## Feedback + +Love it? Hate it? Want to know more or make a suggestion? Let us know by [filing an issue](https://github.com/SteeltoeOSS/Steeltoe/issues/new/choose), [joining us on slack](https://slack.steeltoe.io/) or [Tweeting at us](https://twitter.com/steeltoeoss) diff --git a/api/v4/configuration/cloud-foundry-provider.md b/api/v4/configuration/cloud-foundry-provider.md new file mode 100644 index 00000000..fab58612 --- /dev/null +++ b/api/v4/configuration/cloud-foundry-provider.md @@ -0,0 +1,120 @@ +# Cloud Foundry Provider + +The Cloud Foundry provider enables the standard Cloud Foundry environment variables (`VCAP_APPLICATION`, `VCAP_SERVICES`, and `CF_*`) to be parsed and accessed as configuration data within a .NET application. + +Cloud Foundry creates and uses these environment variables to communicate an application's environment and configuration to the application code running inside a container. More specifically, the values found in `VCAP_APPLICATION` provide information about the application's resource limits, routes (URIs), and version numbers, among other things. The `VCAP_SERVICES` environment variable provides information about the external services (databases, caches, and so on) to which the application is bound, along with details on how to contact those services. + +You can read more information on the Cloud Foundry environment variables at the [Cloud Foundry docs](https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html) website. + +## Usage + +You should have a good understanding of how the [.NET Configuration System](https://learn.microsoft.com/aspnet/core/fundamentals/configuration) works before starting to use this provider. + +To use the Steeltoe Cloud Foundry provider, you need to do the following: + +1. Add the appropriate NuGet package reference to your project. +1. Add the provider to the host builder or configuration builder. +1. Configure Cloud Foundry option classes by binding configuration data to them. +1. Inject and use `IConfiguration` or `IOptions<>` to access configuration data. + +### Add NuGet Reference + +To use the provider, you need to add a reference to the `Steeltoe.Configuration.CloudFoundry` NuGet package. + +### Add Configuration Provider with Options + +The `AddCloudFoundryConfiguration()` host builder extension method is the easiest way to set things up. It performs +both of the individual steps described below: add the configuration provider and configure options. +The following example shows how to do so: + +```csharp +using Steeltoe.Configuration.CloudFoundry; + +var builder = WebApplication.CreateBuilder(args); +builder.AddCloudFoundryConfiguration(); +``` + +#### Add Configuration Provider + +If you don't want to use the host builder extension method, the following code shows how to add the Cloud Foundry configuration provider to the `ConfigurationBuilder`: + +```csharp +using Steeltoe.Configuration.CloudFoundry; + +var configurationBuilder = new ConfigurationBuilder(); +configurationBuilder.AddCloudFoundry(); +var configuration = configurationBuilder.Build(); +``` + +### Access Configuration Data + +Once the configuration has been built, the values from the `VCAP_APPLICATION` and `VCAP_SERVICES` environment variables have been added to the application's configuration data and become available under keys prefixed with `vcap:application` and `vcap:services` respectively. + +You can access the values from the `VCAP_APPLICATION` environment variable settings directly from the `IConfiguration` as follows: + +```csharp +var appName = configuration["vcap:application:application_name"]; +var instanceId = configuration["vcap:application:instance_id"]; +``` + +A list of all `VCAP_APPLICATION` keys is available in the [VCAP_APPLICATION](https://docs.CloudFoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-APPLICATION) topic of the Cloud Foundry documentation. + +You can also directly access the values from the `VCAP_SERVICES` environment variable. For example, to access the information about the first instance of a bound Cloud Foundry service with the name `service-name`, you could code the following: + +```csharp +var name = configuration["vcap:services:service-name:0:name"]; +var uri = configuration["vcap:services:service-name:0:credentials:uri"]; +``` + +A list of all `VCAP_SERVICES` keys is available in the [VCAP_SERVICES](https://docs.CloudFoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-SERVICES) topic of the Cloud Foundry documentation. + +> [!NOTE] +> This provider uses the built-in .NET [JSON configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#json-configuration-provider) when parsing the JSON provided in the `VCAP_*` environment variables. As a result, you can expect the exact same key names and behavior as you see when parsing JSON configuration files (such as `appsettings.json`) in your application. + +### Access Configuration Data as Options + +Alternatively, instead of accessing the Cloud Foundry configuration data directly from the configuration, you can use the [Options Pattern](https://learn.microsoft.com/aspnet/core/fundamentals/configuration/options) together with [Dependency Injection](https://learn.microsoft.com/aspnet/core/fundamentals/dependency-injection) to obtain an instance of the option classes into your controllers and views. + +The Cloud Foundry provider includes two additional classes, `CloudFoundryApplicationOptions` and `CloudFoundryServicesOptions`. You can configure both to bind to the parsed `VCAP_*` data. + +If you're not using the host builder extension method mentioned above, the `AddCloudFoundryOptions()` method can be used to configure the Cloud Foundry option classes. This method binds the parsed `VCAP_*` data to the `CloudFoundryApplicationOptions` and `CloudFoundryServicesOptions` classes. The following example shows how to do so: + +```csharp +using Steeltoe.Configuration.CloudFoundry; + +var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddCloudFoundry(); +builder.Services.AddCloudFoundryOptions(); +``` + +Once this is done, you can access these configuration objects in the controllers or views of an application by using normal Dependency Injection, as follows: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Steeltoe.Configuration.CloudFoundry; + +public class HomeController( + IOptionsSnapshot applicationOptionsSnapshot, + IOptionsSnapshot servicesOptionsSnapshot) + : Controller +{ + public IActionResult Index() + { + CloudFoundryApplicationOptions applicationOptions = applicationOptionsSnapshot.Value; + + ViewData["AppName"] = applicationOptions.ApplicationName; + ViewData["AppId"] = applicationOptions.ApplicationId; + ViewData["URI-0"] = applicationOptions.Uris[0]; + + CloudFoundryServicesOptions servicesOptions = servicesOptionsSnapshot.Value; + CloudFoundryService firstService = servicesOptions.GetAllServices().First(); + + ViewData["name"] = firstService.Name; + ViewData["client_id"] = firstService.Credentials["client_id"].Value; + ViewData["client_secret"] = firstService.Credentials["client_secret"].Value; + ViewData["uri"] = firstService.Credentials["uri"].Value; + return View(); + } +} +``` diff --git a/api/v4/configuration/config-server-provider.md b/api/v4/configuration/config-server-provider.md new file mode 100644 index 00000000..b98c3d3a --- /dev/null +++ b/api/v4/configuration/config-server-provider.md @@ -0,0 +1,281 @@ +# Config Server Provider + +This provider enables the Spring Cloud Config Server to be used as a source of configuration data for a .NET application. + +The Spring Cloud Config Server is an application configuration service that gives you a central place to manage an application's configuration values externally across all environments. As an application moves through the deployment pipeline from development to test and into production, you can use the config server to manage the configuration between environments and be certain that the application has everything it needs to run when you migrate it. The config server easily supports labeled versions of environment-specific configurations and is accessible to a wide range of tooling for managing its content. + +To gain a better understanding of the Spring Cloud Config Server, you should read the [Spring Cloud Config documentation](https://spring.io/projects/spring-cloud-config). + +In addition to the Quick Start provided later, you can refer to the [Steeltoe ConfigurationProviders](https://github.com/SteeltoeOSS/Samples/tree/main/Configuration/src/ConfigurationProviders) sample application when you need to understand how to use this provider. + +## Usage + +You should know how the [.NET Configuration System](https://learn.microsoft.com/aspnet/core/fundamentals/configuration) works before starting to use this provider. A basic understanding of the `ConfigurationBuilder` and how to add providers to the builder is necessary. + +You should also have a good understanding of the [Spring Cloud Config Server](https://cloud.spring.io/spring-cloud-config/). + +To use the Steeltoe provider, you need to do the following: + +1. Add the appropriate NuGet package reference to your project. +1. Configure the settings that the Steeltoe provider uses to access the Spring Cloud Config Server. +1. Add the provider to the host builder or configuration builder. +1. Optionally, bind the configuration data to a class using the Options Pattern. +1. Inject and use `IConfiguration` or `IOptions<>` to access configuration data. + +### Add NuGet Reference + +To use the provider, you need to add a reference to the `Steeltoe.Configuration.ConfigServer` NuGet package. + +### Configure Settings + +The most convenient way to configure settings for the provider is to put them in a file and then use one of the other file-based configuration providers to read them. + +The following example shows some provider settings that have been put in a JSON file. Only two settings are really necessary. `Spring:Application:Name` configures the "application name" to be `sample`, and `Spring:Cloud:Config:Uri` configures the address of the config server. + +> [!TIP] +> The `Spring:Application:Name` key is also used by various other Steeltoe components. + +```json +{ + "Spring": { + "Application":{ + "Name": "sample" + }, + "Cloud": { + "Config": { + "Uri": "http://localhost:8888" + } + } + } +} +``` + +The following table describes all the settings that can be used to configure the behavior of the provider: + +| Key | Description | Default | +| --- | --- | --- | +| `Name` | Application name for which to request configuration. | | +| `Enabled` | Enable or disable the config server client. | `true` | +| `Uri` | Comma-separated list of config server endpoints. | `http://localhost:8888` | +| `Env` | Environment or profile used in the server request. | `Production` | +| `ValidateCertificates` | Enable or disable server certificate validation. | `true` | +| `Label` | Comma-separated list of labels to request. | | +| `Timeout` | Time to wait for response from server, in milliseconds. | `60_000` (1 min) | +| `PollingInterval` | How often to check for changes in Config Server. | | +| `Username` | Username for basic authentication. | | +| `Password` | Password for basic authentication. | | +| `FailFast` | Enable or disable failure at startup. | `false` | +| `Headers` | Extra HTTP headers which are added to config server requests. | | +| `Token` | HashiCorp Vault authentication token. | | +| `TokenTtl` | HashiCorp Vault token renewal TTL, in milliseconds. Valid on Cloud Foundry only. | `300_000` (5 min) | +| `TokenRenewRate` | HashiCorp Vault token renewal rate, in milliseconds. Valid on Cloud Foundry only. | `60_000` (1 min) | +| `DisableTokenRenewal` | Enable or disable HashiCorp Vault token renewal. Valid on Cloud Foundry only. | `false` | +| `Retry:Enabled` | Enable or disable retry logic. | `false` | +| `Retry:MaxAttempts` | Max retries if retry enabled. | `6` | +| `Retry:InitialInterval` | Starting interval, in milliseconds. | `1000` | +| `Retry:MaxInterval` | Maximum retry interval, in milliseconds. | `2000` | +| `Retry:Multiplier` | Retry interval multiplier. | `1.1` | +| `ClientId` | OAuth2 client ID when using OAuth security. | | +| `ClientSecret` | OAuth2 client secret when using OAuth security. | | +| `AccessTokenUri` | URI to use to obtain OAuth access token. | | +| `Discovery:Enabled` | Enable or disable the Discovery First feature. | `false` | +| `Discovery:ServiceId` | Config Server service ID to use in Discovery First feature. | `configserver` | +| `Health:Enabled` | Enable or disable config server health check contributor. | `true` | +| `Health:TimeToLive` | Health check contributor cache time to live, in milliseconds. | `300_000` (5 min) | + +As mentioned earlier, all settings above should start with `Spring:Cloud:Config:` + +> [!TIP] +> If you use self-signed certificates on Cloud Foundry, you might run into certificate validation issues when pushing an application. +> A quick way to work around this is to disable certificate validation until a proper solution can be put in place. + +### Add Configuration Provider + +Once the provider's settings have been defined and put in a file (such as a JSON file), the next step is to read them and make them available to the provider. + +In the next C# example, the provider's configuration settings from the preceding example are put in the `appsettings.json` file included with the application. Then, by using the .NET JSON configuration provider, we can read the settings by adding the JSON provider to the configuration builder (`AddJsonFile("appsettings.json")`). + +Then, after the JSON provider has been added, you can add the config server provider to the builder. Steeltoe provides an extension method, `AddConfigServer()`, that you can use to do so. + +Because the JSON provider that reads `appsettings.json` has been added *before* the config server provider, the JSON-based settings become available to the Steeltoe provider. Note that you do not have to use JSON for the Steeltoe settings. You can use any of the other off-the-shelf configuration providers for the settings (such as INI files, environment variables, and so on). + +> [!CAUTION] +> You need to use the `Add*()` methods to add the source of the config server clients settings (`AddJsonFile(..)`) *before* you use `AddConfigServer(..)`. Otherwise, the settings are not picked up and used. + +The following sample shows how to add a configuration provider: + +```csharp +using Steeltoe.Configuration.ConfigServer; + +var configurationBuilder = new ConfigurationBuilder() + .SetBasePath(hostEnvironment.ContentRootPath) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{hostEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true) + .AddConfigServer(); + +var configuration = configurationBuilder.Build(); +``` + +When developing a .NET Core application, you can accomplish the same thing by using the `AddConfigServer()` host builder extension method, as follows: + +```csharp +using Steeltoe.Configuration.ConfigServer; + +var builder = WebApplication.CreateBuilder(args); +builder.AddConfigServer(); +``` + +### Bind to Cloud Foundry + +When you want to use a Config Server on Cloud Foundry and you have installed [Spring Cloud Services](https://github.com/SteeltoeOSS/Samples/blob/main/CommonTasks.md#provision-sccs-on-cloud-foundry), you can create and bind an instance of it to your application by using the Cloud Foundry CLI, as follows: + +```bash +# Create a Config Server instance named `myConfigServer` +cf create-service p-config-server standard myConfigServer + +# Wait for service to become ready +cf services + +# Bind the service to `myApp` +cf bind-service myApp myConfigServer + +# Restage the app to pick up change +cf restage myApp +``` + +Once the service is bound to the application, the config server settings are available and can be set up in `VCAP_SERVICES`. + +Then, when you push the application, the Steeltoe provider takes the settings from the service binding and merges those settings with the settings that you have provided through other configuration mechanisms (such as `appsettings.json`). + +If there are any merge conflicts, the last provider added to the configuration takes precedence and overrides all others. + +### Access Configuration Data + +When the `ConfigurationBuilder` builds the configuration, the Config Server client makes the appropriate REST calls to the Config Server and retrieves the configuration values based on the settings that have been provided. + +If there are any errors or problems accessing the server, the application continues to initialize, but the values from the server are not retrieved. If this is not the behavior you want, you should set `Spring:Cloud:Config:FailFast` to `true`. Once that is done, the application fails to start if problems occur during the retrieval. + +> [!TIP] +> To diagnose startup errors, activate bootstrap logging as described [here](../bootstrap/index.md#logging-inside-configuration-providers). + +After the configuration has been built, you can access the retrieved data directly by using `IConfiguration`. The following example shows how to do so: + +```csharp +var configuration = configurationBuilder.Build(); +string? property1 = configuration["example:property1"]; +string? property2 = configuration["example:property2"]; +``` + +Alternatively, you can create a class to hold your configuration data and then use the [Options Pattern](https://learn.microsoft.com/aspnet/core/fundamentals/configuration/options) together with [Dependency Injection](https://learn.microsoft.com/aspnet/core/fundamentals/dependency-injection) to obtain an instance of your options class into your controllers and views. + +To do so, first create a class representing the configuration data you expect to retrieve from the server, as follows: + +```csharp +public class ExampleOptions +{ + public string? Property1 { get; set; } + public string? Property2 { get; set; } +} +``` + +Next, use the code below to bind the `example:*` values to an instance of the `ExampleOptions` class. + +```csharp +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddOptions().BindConfiguration("example"); +``` + +After this has been done, you can gain access to the data in your `Controller` or `View` through dependency injection. The following example shows how to do so: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; + +public class HomeController(IOptionsSnapshot optionsSnapshot) + : Controller +{ + public IActionResult Index() + { + ExampleOptions options = optionsSnapshot.Value; + + ViewData["property1"] = options.Property1; + ViewData["property2"] = options.Property2; + ViewData["property2"] = options.Property2; + return View(); + } +} +``` + +### Configuring Discovery First + +The default behavior for the Steeltoe Config Client is to access the Config Server through the `Spring:Cloud:Config:Uri` configuration setting. This of course requires that the application contains an `appsettings.json` or an environment variable with the Config Server's address set in `Spring:Cloud:Config:Uri`. This mode of operation, the default, is called "Config First". + +Alternatively, you can set up your Config Server to register with a discovery service such as Netflix Eureka. This enables your application to look up the address of the Config Server by using a discovery service instead of configuring it in `appsettings.json`. Note that you have to specifically configure your Config Server deployment to register with a discovery service, as this does not happen automatically. See the Spring Cloud Config Server documentation for how to do so. + +However, with the default "Config First" mode of the Steeltoe client, you are not able to take advantage of the Config Server registration unless you change the clients' mode of operation to "Discovery First". To do so: + +1. If your application does not use a service discovery service, you need to configure your application to do so. See the [Steeltoe Discovery documentation](../discovery/initialize-discovery-client.md) for the details on how. At a minimum, you need to configure the Eureka Server address. +1. Change the Steeltoe Config Server client setting `Spring:Cloud:Config:Discovery:Enabled` to `true` (the default is `false`). +1. If your Config Server is registered with Eureka using a name other than "configserver", use `Spring:Cloud:Config:Discovery:ServiceId` to specify the name used by the client for lookup. + +Note that the cost for using this mode of operation is an extra network roundtrip on startup to locate the Config Server service registration. The benefit is that, as long as the discovery service is at a fixed point, the Config Server can change its address and no changes to applications are needed. + +### Configuring Health Contributor + +The Config Server package provides a Steeltoe management health contributor that attempts to load configuration from the Config Server and contributes health information to the results of the health endpoint. + +If you use the `AddConfigServer()` host builder extension method, the contributor is automatically added to the container and is automatically picked up and used. Otherwise, you can manually add the contributor to the container by using the `AddConfigServerHealthContributor()` extension method. + +The contributor is enabled by default, but can be disabled by setting `Spring:Cloud:Config:Health:Enabled` to `false`. + +The response from the Config Server is cached for performance reasons. The default cache time-to-live is five minutes. To change that value, set the `Spring:Cloud:Config:Health:TimeToLive` to the desired milliseconds. + +### Configuring Fail Fast + +In some cases, you may want to fail the startup of your application if it cannot connect to the Config Server. If this is the desired behavior, set the configuration setting `Spring:Cloud:Config:FailFast` to `true` to make the client halt with an `Exception`. + +### Configuring Retries + +If you expect that the Config Server may occasionally be unavailable when your application starts, you can make it keep trying after a failure. + +First, you need to set `Spring:Cloud:Config:FailFast` to `true`. Then you need to enable retry by setting `Spring:Cloud:Config:Retry:Enabled` to `true`. + +The default behavior is to retry six times with an initial back-off interval of 1000ms and an exponential multiplier of 1.1 for subsequent back-offs. You can configure these settings (and others) by setting the `Spring:Cloud:Config:Retry:*` configuration settings described earlier. + +### Configuring Multiple URLs + +To ensure high availability when you have multiple instances of Config Server deployed and expect one or more instances to be unavailable from time to time, you can either specify multiple URLs as a comma-separated list for `Spring:Cloud:Config:Uri` or have all your instances register in a Service Registry such as Eureka (if you use "Discovery First" mode). + +Note that doing so ensures high availability only when the Config Server is not running or responding (for example, when the server has exited or when a connection timeout has occurred). For example, if the Config Server returns a 500 (Internal Server Error) response or the Steeltoe client receives a 401 from the Config Server (due to bad credentials or other causes), the client does not try to fetch properties from other URLs. An error of that kind indicates a user issue rather than an availability problem. + +If you use HTTP basic auth security on your Config Server, it is possible to use per-Config Server auth credentials by embedding the credentials in each URL you specify for the `Spring:Cloud:Config:Uri` setting. If you use any other kind of security mechanism, you cannot currently use per-Config Server authentication and authorization. + +### Configuring Mutual TLS + +When Spring Cloud Config Server is configured to require Mutual TLS authentication, Steeltoe needs to be provided with a valid client certificate. A client certificate can be configured in `appsettings.json`: + +```json +{ + "Certificates": { + "ConfigServer": { + "CertificateFilePath": "/path/to/instance.crt", + "PrivateKeyFilePath": "/path/to/instance.key" + } + } +} +``` + +Aside from PEM files, Steeltoe supports a single file in PKCS#12 format: + +```json +{ + "Certificates": { + "ConfigServer": { + "CertificateFilePath": "/path/to/instance.p12" + } + } +} +``` + +> [!TIP] +> A single certificate can be shared with both Config Server and Eureka, by using the key "Certificates" instead of "Certificates:ConfigServer". diff --git a/api/v4/configuration/decryption-provider.md b/api/v4/configuration/decryption-provider.md new file mode 100644 index 00000000..52d50226 --- /dev/null +++ b/api/v4/configuration/decryption-provider.md @@ -0,0 +1,109 @@ +# Decryption Provider + +The decryption provider decrypts secrets generated by the Spring Cloud Config Server encryption method. For more details on generating secrets, +you should read the [Spring Cloud documentation](https://cloud.spring.io/spring-cloud-static/spring-cloud.html#_encryption_and_decryption_2) and the [Spring Cloud Config Server documentation](https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#_encryption_and_decryption) +on encrypting and decrypting. + +The two main use cases for the decryption provider are: +- Decrypting encrypted secrets hosted by Config Server +- Storing encrypted secrets in a git repository + +To use the provider, you need to add a reference to the `Steeltoe.Configuration.Encryption` NuGet package. +Then the decryption provider can be enabled as follows: + +```csharp +using Steeltoe.Configuration.Encryption; + +var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddDecryption(); +``` + +This will use the Spring Cloud Config encryption mechanism. + +Any configuration value prefixed with `{cipher}` will be decrypted using the configured key: + +```json +{ + "EncryptedSecret": "{cipher}23f97efe......" +} +``` + +To decrypt secrets, the decryption provider needs to be configured to match the encryption settings. + +There are two types of encryption: symmetric and asymmetric. +For symmetric encryption, a shared key is used to decrypt the secrets: + +```json +{ + "Encrypt": { + "Enabled": true, + "Key": "12345678901234567890" + } +} +``` + +> [!CAUTION] +> The shared key should not be part of any source code repository, but should be passed in some other way to the application. + +For asymmetric encryption, the configuration should be as follows: + +```json +{ + "Encrypt": { + "Enabled": true, + "KeyStore": { + "Location": "path/to/keystore", + "Password": "keystore_password", + "Alias": "keyalias" + } + } +} +``` + +> [!CAUTION] +> The password and the keystore file should not be part of any source code repository, but should be passed in some other way to the application. + +The following table describes the configuration settings that you can apply to the decryption provider: + +| Key | Description | Default | +| --- | --- | --- | +| `Encrypt:Enabled` | Enable decryption of encrypted `{cipher}` values. | `false` | +| `Encrypt:Rsa:Strong` | When set to `true`, the "strong" GCM AES algorithm is used. Otherwise, the standard CBC algorithm is used. | `false` | +| `Encrypt:Rsa:Salt` | Salt for the random secret used to encrypt cipher text. | `deadbeef` | +| `Encrypt:Rsa:Algorithm` | The RSA algorithm to use (`DEFAULT` or `OAEP`). | `DEFAULT` | +| `Encrypt:KeyStore:Location` | Location of the keystore file. Only PKCS12 store is supported. | | +| `Encrypt:KeyStore:Password` | Password that locks the keystore. | | +| `Encrypt:KeyStore:Alias` | Alias for a key in the store. | | +| `Encrypt:Key` | A symmetric key. As a stronger alternative, consider using a keystore. | | + +## Custom encryption + +You can use your own encryption algorithm by implementing the `ITextDecryptor` interface: + +```csharp +public class ExampleTextDecryptor : ITextDecryptor +{ + public string Decrypt(string fullCipher) + { + throw new NotImplementedException(); + } + + public string Decrypt(string fullCipher, string alias) + { + throw new NotImplementedException(); + } +} +``` + +Registration is done using the overloaded `AddDecryption` method: + +```csharp +using Microsoft.Extensions.Logging.Abstractions; +using Steeltoe.Configuration.Encryption; + +var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddDecryption(new ExampleTextDecryptor(), NullLoggerFactory.Instance); +``` + +> [!WARNING] +> Creating encryption algorithms is notoriously difficult. Only use this if you know what you are doing. diff --git a/api/v4/configuration/index.md b/api/v4/configuration/index.md new file mode 100644 index 00000000..f21f55e4 --- /dev/null +++ b/api/v4/configuration/index.md @@ -0,0 +1,25 @@ +# Application Configuration + +Steeltoe Configuration builds on the .NET configuration API, which enables developers to configure an application with values from a variety of sources by using configuration providers. Each provider supports reading a set of name-value pairs from a given source location and adding them into a combined multi-level configuration dictionary. + +Each value contained in the configuration is tied to a string-typed key or name. The values are organized by key into a hierarchical list of name-value pairs in which the components of the keys are separated by a colon (for example, `Spring:Application:Name = DemoApp`). + +.NET supports the following providers and sources: + +* Command-line arguments +* File sources (such as JSON, XML, and INI) +* Environment variables +* Custom providers + +To better understand .NET configuration services, you should read the [ASP.NET Core documentation](https://learn.microsoft.com/aspnet/core/fundamentals/configuration). Note that, while the documentation link suggests this service is tied to ASP.NET Core, it is not. It can be used in many different application types, including Console, ASP.NET 4.x., UWP, and others. + +Steeltoe adds additional configuration providers to the preceding list: + +* Cloud Foundry (JSON from the `VCAP_APPLICATION` and `VCAP_SERVICES` environment variables) +* Spring Cloud Config Server +* Placeholder resolvers +* Decryption of encrypted values +* Random value generator +* Spring Boot configuration + +The following sections provide more detail on each of these Steeltoe providers. diff --git a/api/v4/configuration/placeholder-provider.md b/api/v4/configuration/placeholder-provider.md new file mode 100644 index 00000000..95a0930f --- /dev/null +++ b/api/v4/configuration/placeholder-provider.md @@ -0,0 +1,65 @@ +# Placeholder Provider + +The placeholder resolver enables usage of `${....}` placeholders in your configuration. The provider lets you define configuration values as placeholders and have them be substituted with evaluated values at runtime during configuration access, based on the values of other configuration keys. + +A placeholder takes the form of `${key:subkey1:subkey2?defaultValue}`, where `key:subkey1:subkey2` represents another key in the configuration. At runtime, when you access a configuration key whose value contains a placeholder, the resolver is called to substitute the placeholder with a value that exists in the configuration. If no value is found at the placeholder key, the placeholder is returned unresolved. But if a default value is specified in the placeholder, that default value is returned instead. + +Note that placeholder defaults (for example, `defaultValue`) can also be defined to be placeholders, and they are resolved as well. + +## Usage + +You should have a good understanding of how the [.NET Configuration System](https://learn.microsoft.com/aspnet/core/fundamentals/configuration) works before starting to use this provider. + +To use the Steeltoe placeholder resolver provider, you need to: + +1. Add the appropriate NuGet package reference to your project. +1. Add the provider to the Configuration Builder. +1. Access substituted values from the `IConfiguration`. + +### Add NuGet Reference + +To use the provider, you need to add a reference to the `Steeltoe.Configuration.Placeholder` NuGet package. + +### Add Configuration Provider + +To have placeholders resolved when accessing your configuration data, you need to add the placeholder resolver provider to the `ConfigurationBuilder`. + +```csharp +using Steeltoe.Configuration.Placeholder; + +var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddPlaceholderResolver(); +``` + +> [!IMPORTANT] +> The placeholder resolver works by wrapping and replacing (effectively taking ownership of) all existing configuration sources already added to the `ConfigurationBuilder`. +> As a result, you typically will want to add it as the *last* provider. + +### Access Configuration Data + +Once the configuration has been built, the placeholder resolver is used to resolve any placeholders as you access your configuration data. You can access the configuration data as you normally would, and the resolver tries to resolve any placeholder before returning the value for the key requested. + +Consider the following `appsettings.json` file: + +```json +{ + "Spring": { + "Application": { + "Name": "myName" + }, + "Cloud": { + "Config": { + "Name" : "${Spring:Application:Name?unknown}", + } + } + } + ... +} +``` + +When using the normal `IConfiguration` indexer to access the configuration, you see the placeholder resolver do its thing: + +```csharp +var configuration = builder.Build(); +string? name = configuration["Spring:Cloud:Config:Name"]; // "myName" +``` diff --git a/api/v4/configuration/random-value-provider.md b/api/v4/configuration/random-value-provider.md new file mode 100644 index 00000000..745324f5 --- /dev/null +++ b/api/v4/configuration/random-value-provider.md @@ -0,0 +1,83 @@ +# Random Value Provider + +Sometimes, you might need to generate random values as part of your application's configuration values. + +The Steeltoe random value generator is a configuration provider that you can use to do just that. It can produce integers, longs, GUIDs, or strings, as the following examples show: + +```csharp +string? randomValue = builder.Configuration["random:value"]; +int randomNumber = builder.Configuration.GetValue("random:int"); +long randomLargeNumber = builder.Configuration.GetValue("random:long"); +Guid randomGuid = builder.Configuration.GetValue("random:uuid"); +int randomNumberLessThanTen = builder.Configuration.GetValue("random:int(10)"); +int randomNumberInRange = builder.Configuration.GetValue("random:int[1024,65536]"); +``` + +You can also use the generator together with property placeholders. For example, consider the following `appsettings.json`: + +```json +{ + "Example": { + "RandomValue": "${random:value}", + "RandomNumber": "${random:int}", + "RandomLargeNumber": "${random:long}", + "RandomGuid": "${random:uuid}", + "RandomNumberLessThanTen": "${random:int(10)}", + "RandomNumberInRange": "${random:int[1024,65536]}" + } +} +``` + +## Usage + +You should have a good understanding of how the [.NET Configuration System](https://learn.microsoft.com/aspnet/core/fundamentals/configuration) works before starting to use this provider. + +To use the Steeltoe random value provider, you need to: + +1. Add the appropriate NuGet package reference to your project. +1. Add the provider to the Configuration Builder. +1. Access random values from the `IConfiguration`. + +### Add NuGet Reference + +To use the provider, you need to add a reference to the `Steeltoe.Configuration.RandomValue` NuGet package. + +### Add Configuration Provider + +To have the ability to generate random values from the configuration, you need to add the random value provider to the `ConfigurationBuilder`. + +The following example shows how to do so: + +```csharp +using Steeltoe.Configuration.RandomValue; + +var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddRandomValueSource(); +``` + +> [!TIP] +> If you wish to generate random values as part of using placeholders, you need to add the random value provider to the builder *before* you add the placeholder resolver. + +### Access Random Value Data + +Once the configuration has been built, the random value provider can be used to generate values. You can access the configuration data by using the appropriate `random` keys. + +Consider the following `HomeController` example: + +```csharp +public class HomeController(IConfiguration configuration) : Controller +{ + public IActionResult Index() + { + ViewData["random:int"] = configuration["random:int"]; + ViewData["random:long"] = configuration["random:long"]; + ViewData["random:int(10)"] = configuration["random:int(10)"]; + ViewData["random:long(100)"] = configuration["random:long(100)"]; + ViewData["random:int(10,20)"] = configuration["random:int(10,20)"]; + ViewData["random:long(100,200)"] = configuration["random:long(100,200)"]; + ViewData["random:uuid"] = configuration["random:uuid"]; + ViewData["random:string"] = configuration["random:string"]; + return View(); + } +} +``` diff --git a/api/v4/configuration/spring-boot-provider.md b/api/v4/configuration/spring-boot-provider.md new file mode 100644 index 00000000..eb339304 --- /dev/null +++ b/api/v4/configuration/spring-boot-provider.md @@ -0,0 +1,58 @@ +# Spring Boot Provider + +This provider exists for interoperability with Spring Boot environment variables and command-line arguments. + +The Steeltoe Spring Boot configuration provider reads the JSON in the `SPRING_BOOT_APPLICATION` environment variable and adds its contents to the configuration. It does the same for command-line arguments. +In both cases, any `.` delimiters in configuration keys are converted to `:`, which is the configuration key separator used by .NET. Likewise, Spring array syntax, such as `[1]`, is converted to .NET array syntax `:1`. + +## Usage + +You should have a good understanding of how the [.NET Configuration System](https://learn.microsoft.com/aspnet/core/fundamentals/configuration) works before starting to use this provider. + +To use the Steeltoe Spring Boot provider, you need to: + +1. Add the appropriate NuGet package reference to your project. +1. Add the provider to the Configuration Builder. +1. Access keys from the `IConfiguration`. + +### Add NuGet Reference + +To use the provider, you need to add a reference to the `Steeltoe.Configuration.SpringBoot` NuGet package. + +### Add Configuration Provider + +To access Spring Boot configuration data, you need to add the Spring Boot provider to the `ConfigurationBuilder`. + +The following example shows how to do so: + +```csharp +using Steeltoe.Configuration.SpringBoot; + +var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddSpringBootFromEnvironmentVariable(); +builder.Configuration.AddSpringBootFromCommandLine(args); +``` + +### Access Spring Boot Data + +Once the configuration has been built, the Spring Boot provider can be used to access Spring-style keys in .NET syntax. +For example: + +```csharp +using Steeltoe.Configuration.SpringBoot; + +Environment.SetEnvironmentVariable("SPRING_APPLICATION_JSON", """ +{ + "foo.bar": "value1" +} +"""); + +args = ["spring.bar[0].foo=value2"]; + +var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddSpringBootFromEnvironmentVariable(); +builder.Configuration.AddSpringBootFromCommandLine(args); + +string? value1 = builder.Configuration["foo:bar"]; +string? value2 = builder.Configuration["spring:bar:0:foo"]; +``` diff --git a/api/v4/connectors/cosmosdb.md b/api/v4/connectors/cosmosdb.md new file mode 100644 index 00000000..351130a0 --- /dev/null +++ b/api/v4/connectors/cosmosdb.md @@ -0,0 +1,139 @@ +# CosmosDB + +This connector simplifies accessing [Azure CosmosDB](https://azure.microsoft.com/products/cosmos-db/) databases. +It supports the following .NET drivers: +- [Microsoft.Azure.Cosmos](https://www.nuget.org/packages/Microsoft.Azure.Cosmos), which provides a `CosmosClient`. + +The remainder of this page assumes you're familiar with the [basic concepts of Steeltoe Connectors](./usage.md). + +## Usage + +To use this connector: + +1. Create a CosmosDB server instance or use the [emulator](https://learn.microsoft.com/azure/cosmos-db/local-emulator). +1. Add NuGet references to your project. +1. Configure your connection string in `appsettings.json`. +1. Initialize the Steeltoe Connector at startup. +1. Use the driver-specific connection/client instance. + +### Add NuGet References + +To use this connector, add a NuGet reference to `Steeltoe.Connectors`. + +Also add a NuGet reference to one of the .NET drivers listed above, as you would if you were not using Steeltoe. + +### Configure connection string + +The CosmosDB connection string can be obtained as described [here](https://learn.microsoft.com/azure/cosmos-db/nosql/how-to-dotnet-get-started#retrieve-your-account-connection-string). + +The following example `appsettings.json` uses the emulator: + +```json +{ + "Steeltoe": { + "Client": { + "CosmosDb": { + "Default": { + "ConnectionString": "AccountEndpoint=https://localhost:8081;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==", + "Database": "TestDatabase" + } + } + } + } +} +``` + +Notice this configuration file contains the database name, in addition to the connection string. This value is exposed +as `CosmosDbOptions.Database`. + +### Initialize Steeltoe Connector + +Update your `Program.cs` as below to initialize the Connector: + +```csharp +using Steeltoe.Connectors.CosmosDb; + +var builder = WebApplication.CreateBuilder(args); +builder.AddCosmosDb(); +``` + +### Use CosmosClient + +Start by defining a class that contains container data: +```csharp +using Newtonsoft.Json; + +public class SampleObject +{ + [JsonProperty(PropertyName = "id")] + public string Id { get; set; } + + public string? Text { get; set; } +} +``` + +To obtain a `CosmosClient` instance in your application, inject the Steeltoe factory in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.Cosmos; +using Microsoft.Azure.Cosmos.Linq; +using Steeltoe.Connectors; +using Steeltoe.Connectors.CosmosDb; + +public class HomeController : Controller +{ + public async Task Index( + [FromServices] ConnectorFactory connectorFactory) + { + var connector = connectorFactory.Get(); + CosmosClient client = connector.GetConnection(); + + Container container = client.GetContainer(connector.Options.Database, "TestContainer"); + List sampleObjects = new(); + + await foreach (SampleObject sampleObject in GetAllAsync(container)) + { + sampleObjects.Add(sampleObject); + } + + return View(sampleObjects); + } + + private async IAsyncEnumerable GetAllAsync(Container container) + { + using FeedIterator iterator = + container.GetItemLinqQueryable().ToFeedIterator(); + + while (iterator.HasMoreResults) + { + FeedResponse response = await iterator.ReadNextAsync(); + + foreach (SampleObject sampleObject in response) + { + yield return sampleObject; + } + } + } +} +``` + +A complete sample app that uses `CosmosClient` is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/CosmosDb. + +## Cloud Foundry + +This Connector supports the following service brokers: +- [VMware Tanzu Cloud Service Broker for Azure](https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-Azure/1.4/csb-azure/GUID-index.html) + +You can create and bind an instance to your application by using the Cloud Foundry CLI: + +```bash +# Create CosmosDB service +cf create-service csb-azure-cosmosdb-sql mini myCosmosDbService + +# Bind service to your app +cf bind-service myApp myCosmosDbService + +# Restage the app to pick up change +cf restage myApp +``` diff --git a/api/v4/connectors/extensibility.md b/api/v4/connectors/extensibility.md new file mode 100644 index 00000000..47e8bfe0 --- /dev/null +++ b/api/v4/connectors/extensibility.md @@ -0,0 +1,6 @@ +# Extensibility + +Connectors were redesigned from scratch in Steeltoe v4. At the time of writing, extensibility is not yet available. +We intend to address this gap in the near future. Please follow along and add any input you may have on [this issue](https://github.com/SteeltoeOSS/Steeltoe/issues/1154). + +See [Advanced settings](usage.md#advanced-settings) to customize the built-in Connectors. diff --git a/api/v4/connectors/index.md b/api/v4/connectors/index.md new file mode 100644 index 00000000..fdb46d46 --- /dev/null +++ b/api/v4/connectors/index.md @@ -0,0 +1,17 @@ +# Connectors + +Steeltoe Connectors simplify the process of connecting to, using, and monitoring backing services +(databases, message brokers, and distributed caches). +Connectors are primarily a bonding layer between your infrastructure and your application. +Connectors don't directly manipulate the connection to backing services, but do contain logic +for turning raw credentials into formatted connection strings and also provide health monitoring tools. + +Get started with the [basic concepts](usage.md) or go directly to any supported technology: + +- [MySql](mysql.md) +- [Microsoft SQL Server](microsoft-sql-server.md) +- [PostgreSQL](postgresql.md) +- [RabbitMQ](rabbitmq.md) +- [MongoDB](mongodb.md) +- [CosmosDB](cosmosdb.md) +- [Redis](redis.md) diff --git a/api/v4/connectors/microsoft-sql-server.md b/api/v4/connectors/microsoft-sql-server.md new file mode 100644 index 00000000..6143765c --- /dev/null +++ b/api/v4/connectors/microsoft-sql-server.md @@ -0,0 +1,156 @@ +# Microsoft SQL Server + +This connector simplifies accessing [Microsoft SQL Server](https://www.microsoft.com/sql-server) databases. +It supports the following .NET drivers: +- [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient), which provides an ADO.NET `DbConnection`. +- [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient), which provides an ADO.NET `DbConnection`. +- [Microsoft.EntityFrameworkCore.SqlServer](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.SqlServer), which provides [Entity Framework Core](https://learn.microsoft.com/ef/core) support. + +The remainder of this page assumes you're familiar with the [basic concepts of Steeltoe Connectors](./usage.md). + +## Usage + +To use this connector: +1. Create a SQL Server instance or use [SQL Server Express LocalDB](https://learn.microsoft.com/sql/database-engine/configure-windows/sql-server-express-localdb). +1. Add NuGet references to your project. +1. Configure your connection string in `appsettings.json`. +1. Initialize the Steeltoe Connector at startup. +1. Use the driver-specific connection/client instance. + +### Add NuGet References + +To use this connector, add a NuGet reference to `Steeltoe.Connectors`. If you're using Entity Framework Core, add a +NuGet reference to `Steeltoe.Connectors.EntityFrameworkCore` instead. + +Also add a NuGet reference to one of the .NET drivers listed above, as you would if you were not using Steeltoe. + +### Configure connection string + +The available connection string parameters for SQL Server are documented [here](https://learn.microsoft.com/dotnet/api/microsoft.data.sqlclient.sqlconnection.connectionstring#remarks). + +The following example `appsettings.json` uses SQL Server Express LocalDB: + +```json +{ + "Steeltoe": { + "Client": { + "SqlServer": { + "Default": { + "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=SampleDB" + } + } + } + } +} +``` + +### Initialize Steeltoe Connector + +Update your `Program.cs` as below to initialize the Connector: + +```csharp +using Steeltoe.Connectors.SqlServer; + +var builder = WebApplication.CreateBuilder(args); +builder.AddSqlServer(); +``` + +### Use SqlConnection + +To obtain a `SqlConnection` instance in your application, inject the Steeltoe factory in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Microsoft.Data.SqlClient; +using Steeltoe.Connectors; +using Steeltoe.Connectors.SqlServer; + +public class HomeController : Controller +{ + public async Task Index( + [FromServices] ConnectorFactory connectorFactory) + { + var connector = connectorFactory.Get(); + await using SqlConnection connection = connector.GetConnection(); + await connection.OpenAsync(); + + SqlCommand command = connection.CreateCommand(); + command.CommandText = "SELECT 1"; + object? result = await command.ExecuteScalarAsync(); + + ViewData["Result"] = result; + return View(); + } +} +``` + +### Use Entity Framework Core + +Start by defining your `DbContext` class: +```csharp +public class AppDbContext : DbContext +{ + public DbSet SampleEntities => Set(); + + public AppDbContext(DbContextOptions options) + : base(options) + { + } +} + +public class SampleEntity +{ + public long Id { get; set; } + public string? Text { get; set; } +} +``` + +Next, call the `UseSqlServer()` Steeltoe extension method from `Program.cs` to initialize Entity Framework Core: + +```csharp +using Steeltoe.Connectors.EntityFrameworkCore.SqlServer; +using Steeltoe.Connectors.SqlServer; + +var builder = WebApplication.CreateBuilder(args); +builder.AddSqlServer(); + +builder.Services.AddDbContext( + (serviceProvider, options) => options.UseSqlServer(serviceProvider)); +``` + +Once you have configured and added your `DbContext` to the service container, +you can inject it and use it in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +public class HomeController : Controller +{ + public async Task Index([FromServices] AppDbContext appDbContext) + { + List entities = await appDbContext.SampleEntities.ToListAsync(); + return View(entities); + } +} +``` + +A complete sample app that uses Entity Framework Core with SQL Server is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/SqlServerEFCore. + +## Cloud Foundry + +This Connector supports the following service brokers: +- [VMware Tanzu Cloud Service Broker for Azure](https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-Azure/1.4/csb-azure/GUID-index.html) + +You can create and bind an instance to your application by using the Cloud Foundry CLI: + +```bash +# Create SQL Server service +cf create-service csb-azure-mssql small-v2 mySqlServerService + +# Bind service to your app +cf bind-service myApp mySqlServerService + +# Restage the app to pick up change +cf restage myApp +``` diff --git a/api/v4/connectors/mongodb.md b/api/v4/connectors/mongodb.md new file mode 100644 index 00000000..c38d8554 --- /dev/null +++ b/api/v4/connectors/mongodb.md @@ -0,0 +1,124 @@ +# MongoDB + +This connector simplifies accessing [MongoDB](https://www.mongodb.com/) databases. +It supports the following .NET drivers: +- [MongoDB.Driver](https://www.nuget.org/packages/MongoDB.Driver), which provides an `IMongoClient`. + +The remainder of this page assumes you're familiar with the [basic concepts of Steeltoe Connectors](./usage.md). + +## Usage + +To use this connector: + +1. Create a MongoDB server instance or use a [docker container](https://github.com/SteeltoeOSS/Samples/blob/main/CommonTasks.md#mongodb). +1. Add NuGet references to your project. +1. Configure your connection string in `appsettings.json`. +1. Initialize the Steeltoe Connector at startup. +1. Use the driver-specific connection/client instance. + +### Add NuGet References + +To use this connector, add a NuGet reference to `Steeltoe.Connectors`. + +Also add a NuGet reference to one of the .NET drivers listed above, as you would if you were not using Steeltoe. + +### Configure connection string + +The available connection string parameters for MongoDB are documented [here](https://www.mongodb.com/docs/manual/reference/connection-string/). + +The following example `appsettings.json` uses the docker container from above: + +```json +{ + "Steeltoe": { + "Client": { + "MongoDb": { + "Default": { + "ConnectionString": "mongodb://localhost:27017", + "Database": "TestCollection" + } + } + } + } +} +``` + +Notice this configuration file contains the database name, in addition to the connection string. This value is exposed +as `MongoDbOptions.Database`. + +### Initialize Steeltoe Connector + +Update your `Program.cs` as below to initialize the Connector: + +```csharp +using Steeltoe.Connectors.MongoDb; + +var builder = WebApplication.CreateBuilder(args); +builder.AddMongoDb(); +``` + +### Use IMongoClient + +Start by defining a class that contains collection data: +```csharp +using MongoDB.Bson; + +public class SampleObject +{ + public ObjectId Id { get; set; } + public string? Text { get; set; } +} +``` + +To obtain an `IMongoClient` instance in your application, inject the Steeltoe factory in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using MongoDb.Data; +using MongoDB.Driver; +using Steeltoe.Connectors; +using Steeltoe.Connectors.MongoDb; + +public class HomeController : Controller +{ + public async Task Index( + [FromServices] ConnectorFactory connectorFactory) + { + var connector = connectorFactory.Get(); + IMongoClient client = connector.GetConnection(); + + IMongoDatabase database = client.GetDatabase(connector.Options.Database); + IMongoCollection collection = database.GetCollection("SampleObjects"); + List sampleObjects = await collection.Find(obj => true).ToListAsync(); + + return View(sampleObjects); + } +} +``` + +A complete sample app that uses `IMongoClient` is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/MongoDb. + +## Cloud Foundry + +This Connector supports the following service brokers: +- [VMware Tanzu Cloud Service Broker for Azure](https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-Azure/1.4/csb-azure/GUID-index.html) + +You can create and bind an instance to your application by using the Cloud Foundry CLI: + +```bash +# Create MongoDB service +cf create-service csb-azure-mongodb small myMongoDbService + +# Bind service to your app +cf bind-service myApp myMongoDbService + +# Restage the app to pick up change +cf restage myApp +``` + +## Kubernetes + +This Connector supports the [Service Binding Specification for Kubernetes](https://github.com/servicebinding/spec). +It can be used through the Bitnami [Services Toolkit](https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.5/tap/services-toolkit-install-services-toolkit.html). + +For details on how to use this, see the instructions at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/MongoDb#running-on-tanzu-application-platform-tap. diff --git a/api/v4/connectors/mysql.md b/api/v4/connectors/mysql.md new file mode 100644 index 00000000..00774ec4 --- /dev/null +++ b/api/v4/connectors/mysql.md @@ -0,0 +1,169 @@ +# MySQL + +This connector simplifies accessing [MySQL](https://www.mysql.com/) databases. +It supports the following .NET drivers: +- [MySqlConnector](https://www.nuget.org/packages/MySqlConnector), which provides an ADO.NET `DbConnection`. +- [MySql.Data](https://www.nuget.org/packages/MySql.Data), which provides an ADO.NET `DbConnection`. +- [Pomelo.EntityFrameworkCore.MySql](https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql), which provides [Entity Framework Core](https://learn.microsoft.com/ef/core) support. +- [MySql.EntityFrameworkCore](https://www.nuget.org/packages/MySql.EntityFrameworkCore), which provides [Entity Framework Core](https://learn.microsoft.com/ef/core) support. + +The remainder of this page assumes you're familiar with the [basic concepts of Steeltoe Connectors](./usage.md). + +## Usage + +To use this connector: + +1. Create a MySQL server instance or use a [docker container](https://github.com/SteeltoeOSS/Samples/blob/main/CommonTasks.md#mysql). +1. Add NuGet references to your project. +1. Configure your connection string in `appsettings.json`. +1. Initialize the Steeltoe Connector at startup. +1. Use the driver-specific connection/client instance. + +### Add NuGet References + +To use this connector, add a NuGet reference to `Steeltoe.Connectors`. If you're using Entity Framework Core, add a +NuGet reference to `Steeltoe.Connectors.EntityFrameworkCore` instead. + +Also add a NuGet reference to one of the .NET drivers listed above, as you would if you were not using Steeltoe. + +### Configure connection string + +The available connection string parameters for MySQL are documented [here](https://mysqlconnector.net/connection-options/) and [here](https://dev.mysql.com/doc/refman/8.0/en/connecting-using-uri-or-key-value-pairs.html#connection-parameters-base). + +The following example `appsettings.json` uses the docker container from above: + +```json +{ + "Steeltoe": { + "Client": { + "MySql": { + "Default": { + "ConnectionString": "Server=localhost;Database=steeltoe;Uid=steeltoe;Pwd=steeltoe" + } + } + } + } +} +``` + +### Initialize Steeltoe Connector + +Update your `Program.cs` as below to initialize the Connector: + +```csharp +using Steeltoe.Connectors.MySql; + +var builder = WebApplication.CreateBuilder(args); +builder.AddMySql(); +``` + +### Use MySqlConnection + +To obtain a `MySqlConnection` instance in your application, inject the Steeltoe factory in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using MySqlConnector; +using Steeltoe.Connectors; +using Steeltoe.Connectors.MySql; + +public class HomeController : Controller +{ + public async Task Index( + [FromServices] ConnectorFactory connectorFactory) + { + var connector = connectorFactory.Get(); + await using MySqlConnection connection = connector.GetConnection(); + await connection.OpenAsync(); + + MySqlCommand command = connection.CreateCommand(); + command.CommandText = "SELECT 1"; + object? result = await command.ExecuteScalarAsync(); + + ViewData["Result"] = result; + return View(); + } +} +``` + +A complete sample app that uses `MySqlConnection` is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/MySql. + +### Use Entity Framework Core + +Start by defining your `DbContext` class: +```csharp +public class AppDbContext : DbContext +{ + public DbSet SampleEntities => Set(); + + public AppDbContext(DbContextOptions options) + : base(options) + { + } +} + +public class SampleEntity +{ + public long Id { get; set; } + public string? Text { get; set; } +} +``` + +Next, call the `UseMySql()` Steeltoe extension method from `Program.cs` to initialize Entity Framework Core: + +```csharp +using Steeltoe.Connectors.EntityFrameworkCore.MySql; +using Steeltoe.Connectors.MySql; + +var builder = WebApplication.CreateBuilder(args); +builder.AddMySql(); + +builder.Services.AddDbContext( + (serviceProvider, options) => options.UseMySql(serviceProvider)); +``` + +Once you have configured and added your `DbContext` to the service container, +you can inject it and use it in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +public class HomeController : Controller +{ + public async Task Index([FromServices] AppDbContext appDbContext) + { + List entities = await appDbContext.SampleEntities.ToListAsync(); + return View(entities); + } +} +``` + +A complete sample app that uses Entity Framework Core with MySQL is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/MySqlEFCore. + +## Cloud Foundry + +This Connector supports the following service brokers: +- [VMware SQL with MySQL for Tanzu Application Service](https://docs.vmware.com/en/VMware-SQL-with-MySQL-for-Tanzu-Application-Service/3.0/mysql-for-tas/index.html) +- [VMware Tanzu Cloud Service Broker for Azure](https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-Azure/1.4/csb-azure/GUID-index.html) +- [VMware Tanzu Cloud Service Broker for GCP](https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-GCP/1.2/csb-gcp/GUID-index.html) + +You can create and bind an instance to your application by using the Cloud Foundry CLI: + +```bash +# Create MySQL service +cf create-service p.mysql db-small myMySqlService + +# Bind service to your app +cf bind-service myApp myMySqlService + +# Restage the app to pick up change +cf restage myApp +``` + +## Kubernetes + +This Connector supports the [Service Binding Specification for Kubernetes](https://github.com/servicebinding/spec). +It can be used through the Bitnami [Services Toolkit](https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.5/tap/services-toolkit-install-services-toolkit.html). + +For details on how to use this, see the instructions at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/MySql#running-on-tanzu-application-platform-tap. diff --git a/api/v4/connectors/postgresql.md b/api/v4/connectors/postgresql.md new file mode 100644 index 00000000..541b3d46 --- /dev/null +++ b/api/v4/connectors/postgresql.md @@ -0,0 +1,166 @@ +# PostgreSQL + +This connector simplifies accessing [PostgreSQL](https://www.postgresql.org/) databases. +It supports the following .NET drivers: +- [Npgsql](https://www.nuget.org/packages/Npgsql), which provides an ADO.NET `DbConnection`. +- [Npgsql.EntityFrameworkCore.PostgreSQL](https://www.nuget.org/packages/Npgsql.EntityFrameworkCore.PostgreSQL), which provides [Entity Framework Core](https://learn.microsoft.com/ef/core) support. + +The remainder of this page assumes you're familiar with the [basic concepts of Steeltoe Connectors](./usage.md). + +## Usage + +To use this connector: + +1. Create a PostgreSQL server instance or use a [docker container](https://github.com/SteeltoeOSS/Samples/blob/main/CommonTasks.md#postgresql). +1. Add NuGet references to your project. +1. Configure your connection string in `appsettings.json`. +1. Initialize the Steeltoe Connector at startup. +1. Use the driver-specific connection/client instance. + +### Add NuGet References + +To use this connector, add a NuGet reference to `Steeltoe.Connectors`. If you're using Entity Framework Core, add a +NuGet reference to `Steeltoe.Connectors.EntityFrameworkCore` instead. + +Also add a NuGet reference to one of the .NET drivers listed above, as you would if you were not using Steeltoe. + +### Configure connection string + +The available connection string parameters for PostgreSQL are documented [here](https://www.npgsql.org/doc/connection-string-parameters.html). + +The following example `appsettings.json` uses the docker container from above: + +```json +{ + "Steeltoe": { + "Client": { + "PostgreSql": { + "Default": { + "ConnectionString": "Server=localhost;Database=steeltoe;Uid=steeltoe;Pwd=steeltoe" + } + } + } + } +} +``` + +### Initialize Steeltoe Connector + +Update your `Program.cs` as below to initialize the Connector: + +```csharp +using Steeltoe.Connectors.PostgreSql; + +var builder = WebApplication.CreateBuilder(args); +builder.AddPostgreSql(); +``` + +### Use NpgsqlConnection + +To obtain an `NpgsqlConnection` instance in your application, inject the Steeltoe factory in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Npgsql; +using Steeltoe.Connectors; +using Steeltoe.Connectors.PostgreSql; + +public class HomeController : Controller +{ + public async Task Index( + [FromServices] ConnectorFactory connectorFactory) + { + var connector = connectorFactory.Get(); + await using NpgsqlConnection connection = connector.GetConnection(); + await connection.OpenAsync(); + + NpgsqlCommand command = connection.CreateCommand(); + command.CommandText = "SELECT 1"; + object? result = await command.ExecuteScalarAsync(); + + ViewData["Result"] = result; + return View(); + } +} +``` + +A complete sample app that uses `NpgsqlConnection` is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/PostgreSql. + +### Use Entity Framework Core + +Start by defining your `DbContext` class: +```csharp +public class AppDbContext : DbContext +{ + public DbSet SampleEntities => Set(); + + public AppDbContext(DbContextOptions options) + : base(options) + { + } +} + +public class SampleEntity +{ + public long Id { get; set; } + public string? Text { get; set; } +} +``` + +Next, call the `UseNpgsql()` Steeltoe extension method from `Program.cs` to initialize Entity Framework Core: + +```csharp +using Steeltoe.Connectors.EntityFrameworkCore.PostgreSql; +using Steeltoe.Connectors.PostgreSql; + +var builder = WebApplication.CreateBuilder(args); +builder.AddPostgreSql(); + +builder.Services.AddDbContext( + (serviceProvider, options) => options.UseNpgsql(serviceProvider)); +``` + +Once you have configured and added your `DbContext` to the service container, +you can inject it and use it in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +public class HomeController : Controller +{ + public async Task Index([FromServices] AppDbContext appDbContext) + { + List entities = await appDbContext.SampleEntities.ToListAsync(); + return View(entities); + } +} +``` + +A complete sample app that uses Entity Framework Core with PostgreSQL is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/PostgreSqlEFCore. + +## Cloud Foundry + +This Connector supports the following service brokers: +- [VMware Tanzu Cloud Service Broker for Azure](https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-Azure/1.4/csb-azure/GUID-index.html) +- [VMware Tanzu Cloud Service Broker for GCP](https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-GCP/1.2/csb-gcp/GUID-index.html) + +You can create and bind an instance to your application by using the Cloud Foundry CLI: + +```bash +# Create PostgreSQL service +cf create-service csb-azure-postgresql small myPostgreSqlService + +# Bind service to your app +cf bind-service myApp myPostgreSqlService + +# Restage the app to pick up change +cf restage myApp +``` + +## Kubernetes + +This Connector supports the [Service Binding Specification for Kubernetes](https://github.com/servicebinding/spec). +It can be used through the Bitnami [Services Toolkit](https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.5/tap/services-toolkit-install-services-toolkit.html). + +For details on how to use this, see the instructions at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/PostgreSql#running-on-tanzu-application-platform-tap. diff --git a/api/v4/connectors/rabbitmq.md b/api/v4/connectors/rabbitmq.md new file mode 100644 index 00000000..396aac46 --- /dev/null +++ b/api/v4/connectors/rabbitmq.md @@ -0,0 +1,110 @@ +# RabbitMQ + +This connector simplifies accessing [RabbitMQ](https://www.rabbitmq.com/) message brokers. +It supports the following .NET drivers: +- [RabbitMQ.Client](https://www.nuget.org/packages/RabbitMQ.Client), which provides an `IConnection`. + +The remainder of this page assumes you're familiar with the [basic concepts of Steeltoe Connectors](./usage.md). + +## Usage + +To use this connector: + +1. Create a RabbitMQ server instance or use a [docker container](https://github.com/SteeltoeOSS/Samples/blob/main/CommonTasks.md#rabbitmq). +1. Add NuGet references to your project. +1. Configure your connection string in `appsettings.json` (optional). +1. Initialize the Steeltoe Connector at startup. +1. Use the driver-specific connection/client instance. + +### Add NuGet References + +To use this connector, add a NuGet reference to `Steeltoe.Connectors`. + +Also add a NuGet reference to one of the .NET drivers listed above, as you would if you were not using Steeltoe. + +### Configure connection string + +The available connection string parameters for RabbitMQ are documented [here](https://www.rabbitmq.com/uri-spec.html). + +The following example `appsettings.json` uses the docker container from above: + +```json +{ + "Steeltoe": { + "Client": { + "RabbitMQ": { + "Default": { + "ConnectionString": "amqp://localhost" + } + } + } + } +} +``` + +### Initialize Steeltoe Connector + +Update your `Program.cs` as below to initialize the Connector: + +```csharp +using Steeltoe.Connectors.RabbitMQ; + +var builder = WebApplication.CreateBuilder(args); +builder.AddRabbitMQ(); +``` + +### Use IConnection + +To obtain an `IConnection` instance in your application, inject the Steeltoe factory in a controller or view: + +```csharp +using System.Text; +using Microsoft.AspNetCore.Mvc; +using RabbitMQ.Client; +using Steeltoe.Connectors; +using Steeltoe.Connectors.RabbitMQ; + +public class HomeController : Controller +{ + public IActionResult Index( + [FromServices] ConnectorFactory connectorFactory) + { + var connector = connectorFactory.Get(); + IConnection connection = connector.GetConnection(); + + using IModel channel = connection.CreateModel(); + BasicGetResult? result = channel.BasicGet("ExampleQueue", true); + string? message = result != null ? Encoding.UTF8.GetString(result.Body.ToArray()) : null; + + ViewData["Result"] = message; + return View(); + } +} +``` + +A complete sample app that uses `IConnection` is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/RabbitMQ. + +## Cloud Foundry + +This Connector supports the following service brokers: +- [VMware RabbitMQ for Tanzu Application Service](https://docs.vmware.com/en/VMware-RabbitMQ-for-Tanzu-Application-Service/2.2/tanzu-rmq/GUID-index.html) + +You can create and bind an instance to your application by using the Cloud Foundry CLI: + +```bash +# Create RabbitMQ service +cf create-service p.rabbitmq single-node myRabbitMQService + +# Bind service to your app +cf bind-service myApp myRabbitMQService + +# Restage the app to pick up change +cf restage myApp +``` + +## Kubernetes + +This Connector supports the [Service Binding Specification for Kubernetes](https://github.com/servicebinding/spec). +It can be used through the Bitnami [Services Toolkit](https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.5/tap/services-toolkit-install-services-toolkit.html). + +For details on how to use this, see the instructions at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/RabbitMQ#running-on-tanzu-application-platform-tap. diff --git a/api/v4/connectors/redis.md b/api/v4/connectors/redis.md new file mode 100644 index 00000000..a13976a1 --- /dev/null +++ b/api/v4/connectors/redis.md @@ -0,0 +1,139 @@ +# Redis + +This connector simplifies accessing [Redis](https://redis.io/) databases. +It supports the following .NET drivers: +- [StackExchange.Redis](https://www.nuget.org/packages/StackExchange.Redis), which provides an `IConnectionMultiplexer`. +- [Microsoft.Extensions.Caching.StackExchangeRedis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.StackExchangeRedis), which provides an `IDistributedCache`. + +The remainder of this page assumes you're familiar with the [basic concepts of Steeltoe Connectors](./usage.md). + +## Usage + +To use this connector: + +1. Create a Redis server instance or use a [docker container](https://github.com/SteeltoeOSS/Samples/blob/main/CommonTasks.md#redis). +1. Add NuGet references to your project. +1. Configure your connection string in `appsettings.json`. +1. Initialize the Steeltoe Connector at startup. +1. Use the driver-specific connection/client instance. + +### Add NuGet References + +To use this connector, add a NuGet reference to `Steeltoe.Connectors`. + +Also add a NuGet reference to one of the .NET drivers listed above, as you would if you were not using Steeltoe. + +### Configure connection string + +The available connection string parameters for Redis are documented [here](https://stackexchange.github.io/StackExchange.Redis/Configuration.html). + +The following example `appsettings.json` uses the docker container from above: + +```json +{ + "Steeltoe": { + "Client": { + "Redis": { + "Default": { + "ConnectionString": "localhost" + } + } + } + } +} +``` + +### Initialize Steeltoe Connector + +Update your `Program.cs` as below to initialize the Connector: + +```csharp +using Steeltoe.Connectors.Redis; + +var builder = WebApplication.CreateBuilder(args); +builder.AddRedis(); +``` + +### Use IConnectionMultiplexer + +To obtain an `IConnectionMultiplexer` instance in your application, inject the Steeltoe factory in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using StackExchange.Redis; +using Steeltoe.Connectors; +using Steeltoe.Connectors.Redis; + +public class HomeController : Controller +{ + public async Task Index( + [FromServices] ConnectorFactory connectorFactory) + { + var connector = connectorFactory.Get(); + IConnectionMultiplexer client = connector.GetConnection(); + + IDatabase database = client.GetDatabase(); + database.StringSet("myKey", DateTime.UtcNow.ToString()); + + ViewData["Result"] = database.StringGet("myKey"); + return View(); + } +} +``` + +A complete sample app that uses `IConnectionMultiplexer` is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/Redis. + +### Use IDistributedCache + +To obtain an `IDistributedCache` instance in your application, inject the Steeltoe factory in a controller or view: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Caching.Distributed; +using Steeltoe.Connectors; +using Steeltoe.Connectors.Redis; + +public class HomeController : Controller +{ + public async Task Index( + [FromServices] ConnectorFactory connectorFactory) + { + var connector = connectorFactory.Get(); + IDistributedCache client = connector.GetConnection(); + + await client.SetStringAsync("myKey", DateTime.UtcNow.ToString()); + + ViewData["Result"] = await client.GetStringAsync("myKey"); + return View(); + } +} +``` + +A complete sample app that uses `IDistributedCache` is provided at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/Redis. + +## Cloud Foundry + +This Connector supports the following service brokers: +- [Redis for VMware Tanzu Application Service](https://docs.vmware.com/en/Redis-for-VMware-Tanzu-Application-Service/3.1/redis-tanzu-application-service/GUID-index.html) +- [VMware Tanzu Cloud Service Broker for Azure](https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-Azure/1.4/csb-azure/GUID-index.html) +- [VMware Tanzu Cloud Service Broker for GCP](https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-GCP/1.2/csb-gcp/GUID-index.html) + +You can create and bind an instance to your application by using the Cloud Foundry CLI: + +```bash +# Create Redis service +cf create-service p-redis shared-vm myRedisService + +# Bind service to your app +cf bind-service myApp myRedisService + +# Restage the app to pick up change +cf restage myApp +``` + +## Kubernetes + +This Connector supports the [Service Binding Specification for Kubernetes](https://github.com/servicebinding/spec). +It can be used through the Bitnami [Services Toolkit](https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.5/tap/services-toolkit-install-services-toolkit.html). + +For details on how to use this, see the instructions at https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/Redis#running-on-tanzu-application-platform-tap. diff --git a/api/v4/connectors/usage.md b/api/v4/connectors/usage.md new file mode 100644 index 00000000..b190ba9d --- /dev/null +++ b/api/v4/connectors/usage.md @@ -0,0 +1,348 @@ +## Overview + +Steeltoe Connectors provide access to both low-level connection strings and higher-level driver-specific .NET +connection/client instances. Local connection strings are merged with settings from the cloud. +[Health checks](../management/health.md) are registered for use with Steeltoe Management Actuators. +Additional extension methods are provided for integration with Entity Framework Core. + +This page covers the basic concepts of Connectors, how they work, and how to use them. +The rest of the pages cover information that is specific to the various .NET drivers. + +### Connection strings + +At its core, a Steeltoe Connector reads a connection string from appsettings and exposes it via the +[ASP.NET Options pattern](https://learn.microsoft.com/aspnet/core/fundamentals/configuration/options). + +For example, given the next `appsettings.json`: + +```json +{ + "Steeltoe": { + "Client": { + "PostgreSql": { + "Default": { + "ConnectionString": + "Server=localhost;Database=steeltoe;Uid=steeltoe;Pwd=steeltoe;Log Parameters=true" + } + } + } + } +} +``` + +and NuGet references to `Steeltoe.Connectors` and [Npgsql](https://www.nuget.org/packages/Npgsql), +the code fragment below reads the PostgreSQL connection string and prints it. + +```csharp +using Microsoft.Extensions.Options; +using Steeltoe.Connectors.PostgreSql; + +var builder = WebApplication.CreateBuilder(); +builder.AddPostgreSql(); + +WebApplication app = builder.Build(); + +var options = app.Services.GetRequiredService>(); +Console.WriteLine(options.Value.ConnectionString); +``` + +This outputs: + +``` +Host=localhost;Database=steeltoe;Username=steeltoe;Password=steeltoe;Log Parameters=True +``` + +Notice that the parameter names are slightly different in the printed output. +This is because Steeltoe relies on the [DbConnectionStringBuilder](https://learn.microsoft.com/dotnet/api/system.data.common.dbconnectionstringbuilder) +of the [PostgreSQL .NET driver](https://www.npgsql.org/doc/api/Npgsql.NpgsqlConnectionStringBuilder.html), which normalizes the parameter names. +The advantage of this approach is that you're free to use any driver-specific connection string parameters, +without the need for Steeltoe to understand them first. + +> [!NOTE] +> Earlier versions of Steeltoe assigned default values (such as "localhost") for required connection string parameters that were not specified +in configuration. This is no longer the case. In practice, this means you'll need to configure a connection string in most cases to run locally. + +### Cloud-hosted applications + +When your app is running in Cloud Foundry or Kubernetes, the Connector enriches the local connection string from `appsettings.json` +by merging any cloud-provided parameters into it. The resulting connection string is exposed via the Options pattern in the +same way as described above. + +The Connector automatically detects when merging is needed: +- When running in Cloud Foundry, it reads the connection parameters from the JSON in the `VCAP_SERVICES` environment variable. + For more information on `VCAP_SERVICES`, see the [Cloud Foundry documentation](https://docs.cloudfoundry.org/services/binding-credentials.html). +- When running in Kubernetes, it reads the secret files from the directory that the `SERVICE_BINDING_ROOT` environment variable points to. + For more information on `SERVICE_BINDING_ROOT`, see the [Service Binding Specification for Kubernetes](https://github.com/servicebinding/spec). + + +### Named connection strings + +Multiple service bindings can be accessed using named options. Just replace "Default" in your `appsettings.json` with the name +of the service binding. + +For example, the next `appsettings.json` file contains two named connection strings: + +```json +{ + "Steeltoe": { + "Client": { + "PostgreSql": { + "MyServiceOne": { + "ConnectionString": + "Server=host1;Database=db1;Uid=user1;Pwd=pass1;Include Error Detail=true" + }, + "MyServiceTwo": { + "ConnectionString": + "Server=host1;Database=db2;Uid=user2;Pwd=pass2;Log Parameters=true" + } + } + } + } +} +``` + +which can be accessed using the code fragment below. + +```csharp +using Microsoft.Extensions.Options; +using Steeltoe.Connectors.PostgreSql; + +var builder = WebApplication.CreateBuilder(); +builder.AddPostgreSql(); + +WebApplication app = builder.Build(); + +var optionsMonitor = app.Services.GetRequiredService>(); +Console.WriteLine(optionsMonitor.Get("MyServiceOne").ConnectionString); +Console.WriteLine(optionsMonitor.Get("MyServiceTwo").ConnectionString); +``` + +This outputs: + +``` +Host=host1;Database=db1;Username=user1;Password=pass1;Include Error Detail=True +Host=host1;Database=db2;Username=user2;Password=pass2;Log Parameters=True +``` + +When using cloud hosting, the local connection string names need to match the service binding names in the cloud for proper +merging to take place. + +However, for convenience, if you have a single named service binding in the cloud, you can just use "Default" locally. +This is useful if you don't know the cloud-hosted service binding name upfront while developing your application. + +## Connection/client instances + +On top of the exposed connection string, a Steeltoe Connector provides a factory to obtain driver-specific connection/client instances. + +The example below uses the same `appsettings.json` file from before, but obtains a connection from the factory: + +```csharp +using Npgsql; +using Steeltoe.Connectors; +using Steeltoe.Connectors.PostgreSql; + +var builder = WebApplication.CreateBuilder(args); +builder.AddPostgreSql(); + +WebApplication app = builder.Build(); + +var factory = app.Services.GetRequiredService>(); +var connector = factory.Get(); + +using NpgsqlConnection connection = connector.GetConnection(); +connection.Open(); +``` + +Likewise, the connection for a named service binding can be obtained by passing in its name: + +```csharp +var connectorOne = factory.Get("MyServiceOne"); + +using NpgsqlConnection connectionOne = connectorOne.GetConnection(); +connectionOne.Open(); +``` + +Per named service, `ConnectorFactory` either returns a new connection/client instance each time or caches the first one, +based on documented best practices for the specific .NET driver. + +## Legacy host builders + +Steeltoe provides direct extension methods on `WebApplicationBuilder` for ease of use. + +If you're using the legacy [IHostBuilder](https://learn.microsoft.com/aspnet/core/fundamentals/host/generic-host) or +[IWebHostBuilder](https://learn.microsoft.com/aspnet/core/fundamentals/host/web-host), you need to call two methods instead. + +For example, when using MySQL with `IWebHostBuilder`, add a NuGet reference to +[MySqlConnector](https://www.nuget.org/packages/MySqlConnector) and call both `ConfigureMySql()` and `AddMySql()`: + +```csharp +using Microsoft.AspNetCore; +using Steeltoe.Connectors.MySql; + +internal static class Program +{ + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + } + + private static IWebHostBuilder CreateWebHostBuilder(string[] args) + { + return WebHost.CreateDefaultBuilder(args) + .UseStartup() + .ConfigureAppConfiguration( + configurationBuilder => configurationBuilder.ConfigureMySql()) + .ConfigureServices( + (context, services) => services.AddMySql(context.Configuration)); + } +} +``` + +## Entity Framework Core + +To use the merged connection string with Entity Framework Core, add a NuGet reference to `Steeltoe.Connectors.EntityFrameworkCore` +and call the corresponding `Use*` Steeltoe method, in addition to adding the Connector to the host builder as shown before. + +For example, given the next `appsettings.json`: + +```json +{ + "Steeltoe": { + "Client": { + "SqlServer": { + "Default": { + "ConnectionString": + "Server=(localdb)\\mssqllocaldb;Database=ExampleDB;Pooling=true" + } + } + } + } +} +``` + +After adding a NuGet reference to `Steeltoe.Connectors.EntityFrameworkCore` and [Microsoft.EntityFrameworkCore.SqlServer](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.SqlServer), +the code fragment below sets the SQL Server connection string in Entity Framework Core and prints it. + +```csharp +using Microsoft.EntityFrameworkCore; +using Steeltoe.Connectors.EntityFrameworkCore.SqlServer; +using Steeltoe.Connectors.SqlServer; + +var builder = WebApplication.CreateBuilder(args); +builder.AddSqlServer(); + +builder.Services.AddDbContext( + (serviceProvider, options) => options.UseSqlServer(serviceProvider)); + +WebApplication app = builder.Build(); + +await using AsyncServiceScope scope = app.Services.CreateAsyncScope(); +var dbContext = scope.ServiceProvider.GetRequiredService(); +Console.WriteLine(dbContext.Database.GetConnectionString()); + +public class AppDbContext : DbContext +{ + public AppDbContext(DbContextOptions options) + : base(options) + { + } +} +``` + +This outputs: + +``` +Data Source=(localdb)\mssqllocaldb;Initial Catalog=ExampleDB;Pooling=True +``` + +Notice that the `UseSqlServer()` method from the `Steeltoe.Connectors.SqlServer` namespace is used, +instead of the one provided by Microsoft. The Steeltoe method obtains the connection string, and then delegates to +the Microsoft-provided method. + +To use multiple named service bindings, use an overload that takes the service binding name. For example: + +```csharp +builder.Services.AddDbContext( + (serviceProvider, options) => options.UseMySql(serviceProvider, "MyServiceOne")); + +builder.Services.AddDbContext( + (serviceProvider, options) => options.UseMySql(serviceProvider, "MyServiceTwo")); +``` + +## Advanced settings + +Usage of the ASP.NET Options pattern by Steeltoe Connectors enables configuring them using custom code. + +For example, the code below adds the application name to the MongoDB connection URL at runtime: + +```csharp +using MongoDB.Driver; +using Steeltoe.Connectors.MongoDb; + +var builder = WebApplication.CreateBuilder(args); +builder.AddMongoDb(); + +builder.Services.Configure(options => +{ + var urlBuilder = new MongoUrlBuilder(options.ConnectionString) + { + ApplicationName = "mongodb-example-app" + }; + + options.ConnectionString = urlBuilder.ToString(); +}); +``` + +The Steeltoe Connector extension methods provide overloads to influence how they work. This enables to hook in custom logic +to construct the connection/client instance and override its lifetime. Or override if and how health checks are registered. +See the documentation on `ConnectorConfigureOptionsBuilder` and `ConnectorAddOptionsBuilder` for details. + +The example below overrides the creation of the Redis `ConnectionMultiplexer` instance and turns off health checks: + +```csharp +using Microsoft.Extensions.Options; +using StackExchange.Redis; +using Steeltoe.Connectors.Redis; + +var builder = WebApplication.CreateBuilder(args); + +builder.AddRedis(null, addOptions => +{ + // Override the built-in logic that creates the ConnectionMultiplexer instance. + addOptions.CreateConnection = (serviceProvider, serviceBindingName) => + { + // Obtain connection string from named options. + var optionsMonitor = serviceProvider.GetRequiredService>(); + RedisOptions options = optionsMonitor.Get(serviceBindingName); + + // Create ConnectionMultiplexer with a custom time-out. + ConfigurationOptions redisOptions = ConfigurationOptions.Parse(options.ConnectionString); + redisOptions.ConnectTimeout = 30; + return ConnectionMultiplexer.Connect(redisOptions); + }; + + // Turn off health checks. + addOptions.EnableHealthChecks = false; +}); +``` + +The Steeltoe Connector extension methods for Entity Framework Core take an optional parameter to configure the driver-specific +settings. But because Steeltoe has no compile-time reference to the drivers, you need to upcast its parameter first. + +The next example activates the retry policy on the SQL Server provider for Entity Framework Core: + +```csharp +using Microsoft.EntityFrameworkCore.Infrastructure; +using Steeltoe.Connectors.EntityFrameworkCore.SqlServer; +using Steeltoe.Connectors.SqlServer; + +var builder = WebApplication.CreateBuilder(args); +builder.AddSqlServer(); + +builder.Services.AddDbContext((serviceProvider, options) => + options.UseSqlServer(serviceProvider, null, untypedOptions => + { + var sqlServerOptions = (SqlServerDbContextOptionsBuilder)untypedOptions; + sqlServerOptions.EnableRetryOnFailure(); + })); +``` diff --git a/api/v4/discovery/configuration-based.md b/api/v4/discovery/configuration-based.md new file mode 100644 index 00000000..bcad67fd --- /dev/null +++ b/api/v4/discovery/configuration-based.md @@ -0,0 +1,50 @@ +# Configuration-based discovery client + +The simplest form of service discovery is by storing the list of app instances in .NET configuration. + +## Configuration settings + +An app instance in configuration contains the following keys: + +| Key | Description | +| --- | --- | --- | +| `ServiceId` | The app friendly name. | +| `Host` | The hostname or IP address of the service instance. | +| `Port` | The port number the service instance is listening on. | +| `IsSecure` | Whether to use HTTP or HTTPS to access the service instance. | + +For example, the `appsettings.json` file below adds one instance of "billingService" and two instances of "shippingService". + +```json +{ + "Discovery": { + "Services": [ + { + "ServiceId": "billingService", + "Host": "192.168.0.1", + "Port": "5000", + "IsSecure": false + }, + { + "ServiceId": "shippingService", + "Host": "one.internal.shipping.company.com", + "Port": "888", + "IsSecure": true + }, + { + "ServiceId": "shippingService", + "Host": "two.internal.shipping.company.com", + "Port": "999", + "IsSecure": true + } + ] + } +} +``` + +Using the above configuration, sending an HTTP request to `http://shippingService/api?id=123` with Steeltoe service discovery +activated would send the request to either: +- `https://one.internal.shipping.company.com:888/api?id=123` +- `https://two.internal.shipping.company.com:999/api?id=123` + +The chosen instance depends on the load balancer strategy, which defaults to random. diff --git a/api/v4/discovery/discovering-services.md b/api/v4/discovery/discovering-services.md new file mode 100644 index 00000000..74dd7a09 --- /dev/null +++ b/api/v4/discovery/discovering-services.md @@ -0,0 +1,200 @@ +# Discovering services + +Resolving friendly names happens through a load balancer, which queries `IDiscoveryClient`s for available service instances. + +## Using HttpClientFactory + +The recommended approach is to use a typed `HttpClient`, supplied through +[HttpClientFactory](https://learn.microsoft.com/aspnet/core/fundamentals/http-requests). Call the `.AddServiceDiscovery()` +extension method from the `Steeltoe.Discovery.HttpClients` NuGet package to activate service discovery. + +> [!NOTE] +> The `AddServiceDiscovery()` extension method takes an optional `ILoadBalancer` parameter. +> If no load balancer is provided, the built-in `RandomLoadBalancer` is activated, +> which uses randomized selection of service instances. + +For example, consider the following typed client: +```csharp +public sealed class OrderService(HttpClient httpClient) +{ + public async Task GetOrderByIdAsync( + string orderId, CancellationToken cancellationToken) + { + return await httpClient.GetFromJsonAsync( + $"https://ordering-api/orders/{orderId}", cancellationToken); + } +} +``` + +This typed client can be configured to use service discovery. Add the following code to `Program.cs` +to rewrite the `https://ordering-api` part to a service instance obtained from Eureka. + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddEurekaDiscoveryClient(); +builder.Services.AddHttpClient().AddServiceDiscovery(); +``` + +With the above code in place, you can inject `OrderService` in your MVC controller, for example: + +```csharp +public sealed class OrdersController(OrderService orderService) : Controller +{ + [HttpGet("{orderId}")] + public async Task Index(string orderId, CancellationToken cancellationToken) + { + var model = await orderService.GetOrderByIdAsync(orderId, cancellationToken); + return View(model); + } +} +``` + +When the MVC controller executes, `HttpClientFactory` returns an `HttpClient` that is configured for service discovery. +Under the covers, Steeltoe adds `DiscoveryHttpDelegatingHandler` to the HTTP handler pipeline, +which intercepts requests and rewrites the scheme/host/port with the values obtained from the registry (via its load balancer). + +### Global service discovery + +To use service discovery for *all* `HttpClient` instances, use the following code: + +```csharp +builder.Services.ConfigureHttpClientDefaults(clientBuilder => clientBuilder.AddServiceDiscovery()); +``` + +## Using HttpClient + +Another way to use service discovery is to use the Steeltoe `DiscoveryHttpClientHandler` with `HttpClient`. + +The variant of `OrderService` below creates a new `HttpClient` from the injected handler: + +```csharp +public sealed class OrderService(DiscoveryHttpClientHandler handler) +{ + public async Task GetOrderByIdAsync( + string orderId, CancellationToken cancellationToken) + { + var httpClient = new HttpClient(handler, disposeHandler: false); + return await httpClient.GetFromJsonAsync( + $"https://ordering-api/orders/{orderId}", cancellationToken); + } +} +``` + +To register the handler, add the following code to `Program.cs`: + +```csharp +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +``` + +## Using IDiscoveryClient directly + +In the event the provided HTTP support does not serve your needs, you can always make lookups directly against +the registered collection of `IDiscoveryClient`s, for example: + +```csharp +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddEurekaDiscoveryClient(); + +var app = builder.Build(); + +var clients = app.Services.GetRequiredService>(); +var instance = await ResolveAsync(clients); +if (instance != null) +{ + Console.WriteLine($"Resolved '{instance.ServiceId}' to {instance.Host}:{instance.Port}"); +} + +static async Task ResolveAsync(IEnumerable clients) +{ + foreach (var client in clients) + { + var instances = await client.GetInstancesAsync("ordering-api", default); + if (instances.Count > 0) + { + int randomIndex = Random.Shared.Next(0, instances.Count); + return instances[randomIndex]; + } + } + return null; +} +``` + +## Load balancing + +Service discovery relies on a load balancer to choose one from the available service instances. + +The built-in load balancers use `ServiceInstancesResolver` to find the matching service instances from the +registered discovery clients. This resolver optionally supports caching them using `IDistributedCache`, +which is useful for discovery clients that do not provide their own caching (such as the Consul client). + +To activate caching, use the code below: + +```csharp +builder.Services.AddDistributedMemoryCache(); +builder.Services.AddSingleton(new DistributedCacheEntryOptions +{ + SlidingExpiration = TimeSpan.FromMinutes(5) +}); +``` + +> [!NOTE] +> The built-in load balancers do not track statistics or exceptions. + +### Random load balancer + +The `RandomLoadBalancer`, as the name implies, randomly selects a service instance from all instances +that are resolved for a given friendly name. + +### Round-robin load balancer + +The provided `RoundRobinLoadBalancer` selects service instances in sequential order, as they are provided +by discovery clients for the given friendly name. + +To use this load balancer in service discovery, pass it to the `AddServiceDiscovery()` method: + +```csharp +builder.Services.AddHttpClient().AddServiceDiscovery(); +``` + +> [!TIP] +> When caching is activated (see above), this load balancer stores the last-used instance index in the cache. +> Combining it with a shared Redis cache ensures an even load distribution. + +### Custom load balancer + +If the provided load balancer implementations do not suit your needs, you can create your own implementation of `ILoadBalancer`. + +The following example shows a load balancer that always returns the first service instance: + +```csharp +public sealed class ChooseFirstLoadBalancer(ServiceInstancesResolver resolver) : ILoadBalancer +{ + public async Task ResolveServiceInstanceAsync(Uri requestUri, + CancellationToken cancellationToken) + { + var instances = await resolver.ResolveInstancesAsync(requestUri.Host, cancellationToken); + return instances.Count > 0 ? new Uri(instances[0].Uri, requestUri.PathAndQuery) : requestUri; + } + + public Task UpdateStatisticsAsync(Uri requestUri, Uri serviceInstanceUri, TimeSpan? responseTime, + Exception? exception, + CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} +``` + +A custom load balancer needs to be added to the service container manually, because Steeltoe can't know its lifetime. +Add the following code to `Program.cs` to activate the custom load balancer defined above: + +```csharp +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +builder.Services.AddHttpClient().AddServiceDiscovery(); +``` diff --git a/api/v4/discovery/hashicorp-consul.md b/api/v4/discovery/hashicorp-consul.md new file mode 100644 index 00000000..a1e021f6 --- /dev/null +++ b/api/v4/discovery/hashicorp-consul.md @@ -0,0 +1,129 @@ +# HashiCorp Consul discovery client + +The Steeltoe Consul discovery client lets an application register/unregister itself with a Consul server +and provides querying for service instances registered by other applications. + +Once activated, the client registers the currently running app with Consul and starts a background thread that +periodically sends a TTL heartbeat to the Consul server (this is optional). +The client fetches no service registrations until asked for, and doesn't cache them. + +## Usage + +To use this discovery client, add a NuGet package reference to `Steeltoe.Discovery.Consul` and initialize it from your `Program.cs`: + +```csharp +var builder = WebApplication.CreateBuilder(args); + +// Steeltoe: Add service discovery client for Consul. +builder.Services.AddConsulDiscoveryClient(); + +var app = builder.Build(); +``` + +## Configuration settings + +To get the Steeltoe discovery client to properly communicate with the Consul server, you need to provide +a few configuration settings. There are several sections you may need to configure. +What you provide depends on whether you want your application to register the running app and/or +whether it also needs to query for other apps. + +The first section pertains to configuring the information needed to connect to the Consul server. +All of these settings should start with `Consul:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Host` | Hostname or IP address of the Consul server. | `localhost` | +| `Port` | Port number the Consul server is listening on. | `8500` | +| `Scheme` | Scheme to connect with the Consul server (`http` or `https`). | `http` | +| `Datacenter` | The datacenter name passed in each request to the server. | | +| `Token` | Authentication token passed in each request to the server. | | +| `WaitTime` | The maximum duration for a blocking request. | | +| `Username` | Username for HTTP authentication. | | +| `Password` | Password for HTTP authentication. | | +| `Discovery:Enabled` | Whether to enable the Consul client. | `true` | + +The second section you may need to specify pertains to registering the running app. +All of these settings should start with `Consul:Discovery:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Register` | Whether to register the running app as a service instance. | `true` | +| `FailFast` | Throw an exception (instead of logging an error) if registration fails. | `true` | +| `Retry:Enabled` | Whether to try again when registering the running app fails. | `false` | +| `Retry:MaxAttempts` | Maximum number of registration attempts (if retries are enabled). | `6` | +| `Retry:InitialInterval` | The time to wait (in milliseconds) after the first registration failure. | `1000` | +| `Retry:Multiplier` | The factor to increment the next interval with. | `1.1` | +| `Retry:MaxInterval` | Upper bound (in milliseconds) for intervals. | `2000` | +| `Deregister` | Whether to de-register the running app on shutdown. | `true` | +| `ServiceName` | Friendly name to register the running app with. | computed | +| `Scheme` | Scheme to register the running app with (`http` or `https`). | `http` | +| `HostName` | Hostname to register the running app with (if `PreferIPAddress` is `false`). | computed | +| `IPAddress` | IP address to register the running app with (if `PreferIPAddress` is `true`). | computed | +| `UseNetworkInterfaces` | Query the operating system for network interfaces to determine `HostName` and `IPAddress`. | `false` | +| `PreferIPAddress` | Register the running app with IP address instead of hostname. | `false` | +| `Port` | Port number to register the running app with. | | +| `UseAspNetCoreUrls` | Register with the port number ASP.NET Core is listening on. | `true` | +| `InstanceId` | The unique ID to register the running app under. | computed | +| `Tags` | Array of tags used when registering the running app. | | +| `Meta` | Metadata key/value pairs used when registering the running app. | see [Configuring metadata](#configuring-metadata)| +| `InstanceGroup` | Metadata `group` value to use when registering the running app. | | +| `InstanceZone` | Metadata zone value to use when registering the running app. | | +| `DefaultZoneMetadataName` | Metadata key name for `InstanceZone`. | `zone` | +| `RegisterHealthCheck` | Whether to enable periodic health checking for the running app. | `true` | +| `HealthCheckCriticalTimeout` | Duration after which Consul deregisters the running app when in state `critical`. [^1] | `30m` | +| `Heartbeat:Enabled` | Whether the running app periodically sends TTL (time-to-live) heartbeats. [^1] | `true` | +| `Heartbeat:TtlValue` | How often a TTL heartbeat must be sent to be considered healthy. | `30` | +| `Heartbeat:TtlUnit` | Unit for `TtlValue` (`ms`, `s`, `m` or `h`) | `s` | +| `Heartbeat:IntervalRatio` | Rate at which the running app sends TTL heartbeats, relative to `TtlValue` with `TtlUnit`. | `0.66` | +| `HealthCheckPath` | Relative URL to the health endpoint of the running app. [^2] | `/actuator/health` | +| `HealthCheckUrl` | Absolute URL to the health endpoint of the running app (overrides `HealthCheckPath`). [^2] | | +| `HealthCheckTlsSkipVerify` | Whether Consul should skip TLS verification for HTTP health checks. [^2] | `false` | +| `HealthCheckInterval` | How often Consul should perform an HTTP health check. [^2] | `10s` | +| `HealthCheckTimeout` | The timeout Consul should use for an HTTP health check. [^2] | `10s` | + +[^1]: This setting only has effect when `RegisterHealthCheck` is `true` +[^2]: This setting only has effect when `RegisterHealthCheck` is `true` and `Heartbeat:Enabled` is `false` + +The last section pertains to querying for app instances. +All of these settings should start with `Consul:Discovery:`. + +| Key | Description | Default | +| --- | --- | --- | +| `DefaultQueryTag` | The tag to filter on when querying for service instances. | | +| `QueryPassing` | Filter on health status 'passing' when querying for service instances. | `true` | + +For a deeper understanding of these settings, see the Consul documentation on +[registering services](https://developer.hashicorp.com/consul/api-docs/agent/service#register-service), +[health setup during registration](https://developer.hashicorp.com/consul/api-docs/agent/check#register-check) and +[filtering service instances](https://developer.hashicorp.com/consul/api-docs/health). + +### Configuring metadata + +Steeltoe sends metadata (string-based key/value pairs) when registering the currently running app. +Additional metadata can be added in configuration, for example: + +```json +{ + "Consul": { + "Discovery": { + "Meta": { + "exampleKey1": "exampleValue1", + "exampleKey2": "exampleValue2" + } + } + } +} +``` + +By default, the following metadata is added: + +| Key | Value | +| - | - | +| `group` | Value from `Consul:Discovery:InstanceGroup` | +| Value from `Consul:Discovery:DefaultZoneMetadataName` | Value from `Consul:Discovery:InstanceZone` | +| `secure` | Value at `Consul:Discovery:Scheme` equals `https` | + +## Health Contributor + +The `Steeltoe.Discovery.Consul` package includes an `IHealthContributor` that verifies the Consul server is reachable. +This health contributor is automatically added to the service container. diff --git a/api/v4/discovery/index.md b/api/v4/discovery/index.md new file mode 100644 index 00000000..7c141264 --- /dev/null +++ b/api/v4/discovery/index.md @@ -0,0 +1,22 @@ +# Service Discovery + +Service Discovery enables the use of friendly names for the microservices your app depends on. +These microservices typically register themselves at startup to a discovery server, which acts as a central registry. +Each time your app connects to such a microservice, the friendly name is resolved to the actual scheme/host/port by querying the discovery server. + +A discovery server can track multiple instances for a single friendly name, which enables your app to load-balance over them. +It also tracks whether your microservice instances are still alive, using health checks and/or keep-alives. + +While service discovery enables changing infrastructure without affecting your app, its real power lies in scalability. +Discovery servers can typically be run in a cluster to eliminate the single point of failure. +And because they monitor the liveliness of your microservice instances, you can easily scale them up and down. + +Steeltoe facilitates both registration and querying of discovery servers by providing various implementations of `IDiscoveryClient`. +To resolve friendly names, Steeltoe provides implementations of `ILoadBalancer`, which rely on `IDiscoveryClient`. + +To use service discovery, you need to: + +- Add the appropriate NuGet package references to your project +- Register the desired discovery client(s) in the dependency container +- Configure the chosen discovery client(s) for registration and/or consumption +- Activate the provided `HttpClient`/`HttpClientFactory` facilities to resolve friendly names diff --git a/api/v4/discovery/initialize-discovery-client.md b/api/v4/discovery/initialize-discovery-client.md new file mode 100644 index 00000000..102aeff2 --- /dev/null +++ b/api/v4/discovery/initialize-discovery-client.md @@ -0,0 +1,65 @@ +# Discovery clients + +This section describes how to activate the Steeltoe discovery client(s), which is a prerequisite for resolving friendly names. +Your app can use multiple clients, but is limited to a single instance per server type. + +Fundamentally, several things need to happen: + +1. Add NuGet package references to your project +1. Register the desired discovery client(s) in the dependency container +1. Configure the discovery client(s) +1. Optional: enable debug logging + +## Add NuGet packages + +To get started with Steeltoe Discovery, add a reference to the package(s) containing the discovery technology you may wish to use. +Each package also includes all the relevant dependencies. + +| Package | Description | +| --- | --- | +| `Steeltoe.Discovery.Configuration` | Query app instances stored in .NET configuration | +| `Steeltoe.Discovery.Consul` | Use [HashiCorp Consul](https://www.consul.io/) server | +| `Steeltoe.Discovery.Eureka` | Use [Spring Cloud Eureka](https://projects.spring.io/spring-cloud/docs/1.0.3/spring-cloud.html#spring-cloud-eureka-server) server | + +## ServiceCollection extension methods + +After installing the NuGet package(s), the next step is to add the Steeltoe discovery client(s) to the service container. +Update your `Program.cs` as shown below: + +```csharp +var builder = WebApplication.CreateBuilder(args); + +// Steeltoe: Add service discovery clients for Consul, Eureka, and/or configuration-based. +builder.Services.AddConsulDiscoveryClient(); +builder.Services.AddEurekaDiscoveryClient(); +builder.Services.AddConfigurationDiscoveryClient(); + +var app = builder.Build(); +``` + +> [!TIP] +> Alternatively, `builder.AddSteeltoe()` (Steeltoe Bootstrap Auto Configuration) can be used, which uses reflection to determine +> which discovery assemblies are loaded, adding the appropriate clients automatically. + +## Client configuration + +Discovery clients need to be explicitly configured to fetch application instances and/or register your app with the discovery server. +See the sub-page for the discovery technology of choice on how to set it up. + +## Enable debug logging + +Sometimes, you may want to turn on debug logging for service discovery. +To do so, you can modify the `appsettings.json` file and turn on debug logging for the Steeltoe components. + +The following example shows a typical `appsettings.json` file: + +```json +{ + "Logging": { + "LogLevel": { + "Default": "Warning", + "Steeltoe.Discovery": "Debug" + } + } +} +``` diff --git a/api/v4/discovery/netflix-eureka.md b/api/v4/discovery/netflix-eureka.md new file mode 100644 index 00000000..1e11a625 --- /dev/null +++ b/api/v4/discovery/netflix-eureka.md @@ -0,0 +1,261 @@ +# Netflix Eureka discovery client + +The Steeltoe Eureka discovery client lets an application register/unregister itself with a Eureka server +and provides querying for service instances registered by other applications. + +Once activated, the client begins to operate in the background, both registering and renewing service registrations, +sending periodic heartbeats to the Eureka server, and also periodically fetching the service registry from the server. + +## Usage + +To use this discovery client, add a NuGet package reference to `Steeltoe.Discovery.Eureka` and initialize it from your `Program.cs`: + +```csharp +var builder = WebApplication.CreateBuilder(args); + +// Steeltoe: Add service discovery client for Eureka. +builder.Services.AddEurekaDiscoveryClient(); + +var app = builder.Build(); +``` + +## Configuration settings + +To get the Steeltoe discovery client to properly communicate with the Eureka server, you need to provide +a few configuration settings. There are several sections you may need to configure. +What you provide depends on whether you want your application to register the running app and/or +whether it needs to query for other apps. + +For a complete understanding of the effects of many of these settings, we recommend that you review the documentation on the +[Netflix Eureka Wiki](https://github.com/Netflix/eureka/wiki). +In most cases, unless you are confident that you understand the effects of changing the values from their defaults, +we recommend that you use the defaults. + +> [!TIP] +> Since Steeltoe v4, most of these settings can be changed at runtime, which updates the Eureka server accordingly. + +### General + +The following table describes the configuration settings that control the overall behavior of the client. +All of these settings should start with `Eureka:Client:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether to enable the Eureka client. | `true` | +| `ServiceUrl` | Comma-delimited list of Eureka server endpoints. | `http://localhost:8761/eureka/` | +| `AccessTokenUri` | URL to obtain OAuth2 access token from, before connecting to the Eureka server. | | +| `ClientId` | Client ID for obtaining an access token. | | +| `ClientSecret` | Secret for obtaining an access token. | | +| `Validate_Certificates` | Whether the client validates server certificates. | `true` | +| `EurekaServer:ShouldGZipContent` | Whether to auto-decompress responses from the Eureka server. | `true` | +| `EurekaServer:RetryCount` | Number of times to retry Eureka server requests. | `2` | +| `EurekaServer:ConnectTimeoutSeconds` | How long to wait (in seconds) before a connection to the Eureka server times out. | `5` | +| `EurekaServer:ProxyHost` | Proxy hostname used in contacting the Eureka server. | | +| `EurekaServer:ProxyPort` | Proxy port number used in contacting the Eureka server. | | +| `EurekaServer:ProxyUserName` | Proxy username used in contacting the Eureka server. | | +| `EurekaServer:ProxyPassword` | Proxy password used in contacting the Eureka server. | | +| `Health:Enabled` | Whether to activate an `IHealthContributor` that verifies connectivity to the Eureka server. | `true` | + +### Registration + +The configuration settings below pertain to registering the currently running app as a service instance in Eureka. +All of these settings should start with `Eureka:Client:`. + +| Key | Description | Default | +| --- | --- | --- | +| `ShouldRegisterWithEureka` | Whether to register the running app as a service instance. | `true` | +| `Health:CheckEnabled` | Whether to query ASP.NET health checks and `IHealthContributor`s during registration and renewals, in order to determine the status of the running app to report back to Eureka (see section below). | `true` | + +Additionally, the table below lists the configuration settings that control *how* to register the instance. +All of these settings should start with `Eureka:Instance:`. + +| Key | Description | Default | +| --- | --- | --- | +| `InstanceId` | Unique ID (within the scope of the app name) of the instance to be registered with Eureka. | computed | +| `AppName` | Name of the application to be registered with Eureka. | computed | +| `AppGroup` | Name of the application group to be registered with Eureka. | | +| `MetadataMap` | Name/value pairs associated with the instance. | computed | +| `HostName` | Hostname on which the instance is registered. | computed | +| `IPAddress` | IP address on which the instance is registered. | computed | +| `UseNetworkInterfaces` | Query the operating system for network interfaces to determine `HostName` and `IPAddress`. | `false` | +| `PreferIPAddress` | Whether to register with `IPAddress` instead of `HostName`. | `false` | +| `VipAddress` | Comma-delimited list of VIP addresses for the instance. | computed | +| `SecureVipAddress` | Comma-delimited list of secure VIP addresses for the instance. | computed | +| `Port` | Non-secure port number on which the instance should receive traffic. | computed | +| `NonSecurePortEnabled` | Whether the non-secure port should be enabled. [^1] | computed | +| `SecurePort` | Secure port on which the instance should receive traffic. | computed | +| `SecurePortEnabled` | Whether the secure port should be enabled. [^1] | computed | +| `RegistrationMethod` | How to register on Cloud Foundry. Can be `route`, `direct`, or `hostname`. [^2] | | +| `InstanceEnabledOnInit` | Whether the instance should take traffic as soon as it is registered. [^3] | `true` | +| `LeaseRenewalIntervalInSeconds` | How often (in seconds) the client sends heartbeats to Eureka to indicate that it is still alive. | `30` | +| `LeaseExpirationDurationInSeconds` | Time (in seconds) that the Eureka server waits since it received the last heartbeat before it marks the instance as down. | `90` | +| `StatusPageUrlPath` | Relative path to the status page for the instance. [^4] | `/info` | +| `StatusPageUrl` | Absolute URL to the status page for the instance (overrides `StatusPageUrlPath`). | computed | +| `HomePageUrlPath` | Relative path to the home page URL for the instance. | `/` | +| `HomePageUrl` | Absolute URL to the home page for the instance (overrides `HomePageUrlPath`). | computed | +| `HealthCheckUrlPath` | Relative path to the health check endpoint of the instance. [^4] | `/health` | +| `HealthCheckUrl` | Absolute URL for health checks of the instance (overrides `HealthCheckUrlPath`). | computed | +| `SecureHealthCheckUrl` | Secure absolute URL for health checks of the instance (overrides `HealthCheckUrlPath`). | computed | +| `AsgName` | AWS auto-scaling group name associated with the instance. | | +| `DataCenterInfo` | Data center the instance is deployed to (`Netflix`, `Amazon` or `MyOwn`). | MyOwn | + +[^1]: When both non-secure and secure ports are enabled, the secure port is preferred during service discovery. +[^2]: Specify `direct` to use container-to-container networking on Cloud Foundry. Specify `hostname` to force using `HostName`. +[^3]: When set to `false`, call `EurekaApplicationInfoManager.UpdateInstance()` after initialization to mark the instance as up. +[^4]: Add a NuGet package reference to `Steeltoe.Management.Endpoint` to use its `health` and `info` actuator paths. + +The values for `Port` and `SecurePort`, and whether they are enabled, are automatically determined from the ASP.NET address bindings. [^1] +See [8 ways to set the URLs for an ASP.NET Core app](https://andrewlock.net/8-ways-to-set-the-urls-for-an-aspnetcore-app/) +for how to influence them using environment variables. + +It is also possible to use dynamic port bindings (by setting the port number to `0` in ASP.NET). +In that case, Steeltoe adds a random number (outside the valid port range) to the `InstanceId` to make it unique. +Once the app has fully started, the assigned port numbers are updated in Eureka, but the `InstanceId` does not change. + +### Querying + +The configuration settings that pertain to querying the Eureka registry for apps (used by the load balancers during service discovery) are listed below. +All of these settings should start with `Eureka:Client:`. + +| Key | Description | Default | +| --- | --- | --- | +| `ShouldFetchRegistry` | Whether to periodically fetch registry information from the Eureka server. | `true` | +| `RegistryFetchIntervalSeconds` | How often (in seconds) to fetch registry information from the Eureka server. | `30` | +| `ShouldFilterOnlyUpInstances` | Whether to include only instances with UP status after fetching the list of applications. | `true` | +| `ShouldDisableDelta` | Whether to fetch the full registry each time or fetch only deltas. | `false` | +| `RegistryRefreshSingleVipAddress` | Whether to only fetch registry information for the specified VIP address. | `false` | +| `Health:MonitoredApps` | Comma-delimited list of applications in Eureka this app depends on (see section below). | | + +## Configuring health contributors + +The Steeltoe Eureka package provides two different health contributors that you can use to monitor Eureka server health. + +The first one, `EurekaServerHealthContributor`, is used to determine and report the health of the connection to the Eureka +servers. It looks at the status of the last good registry fetch and the last heartbeat attempt and uses that information to +compute the health of the connection. +This contributor is automatically activated, but can be turned off by setting `Eureka:Client:Health:Enabled` to `false`. + +The second contributor that you can enable is the `EurekaApplicationsHealthContributor`. +By default, this contributor is not enabled, so you must add it to the service container yourself: + +```csharp +builder.Services.AddSingleton(); +``` + +You can use the `EurekaApplicationsHealthContributor` to report the health of a configurable list of registered services +based on their status in the registry. For each service it is configured to monitor, it looks at all of the instances +of that service and, if all of the instances are marked `DOWN`, your app is reported as being in bad health. +You can configure the services that it monitors by using the `Eureka:Client:Health:MonitoredApps` configuration setting. +Typically you would set this to the list of external service names your app depends on and that, were they unavailable, +would impact the operation of your app. If this setting is left empty, *all* apps in Eureka are monitored. + +## Configuring health checks + +If `Eureka:Client:ShouldRegisterWithEureka` is set to `true` (the default), the Eureka discovery client sends +periodic heartbeats to inform the Eureka server that the currently running app is reachable. + +Unless specified otherwise, the client does not propagate the current health status of the application, +as calculated from the ASP.NET health checks and active health contributors, to Eureka. +Consequently, after successful registration, Eureka always announces that the application is in 'UP' state. +You can alter this behavior by enabling `Eureka:Client:Health:CheckEnabled` (`false` by default), +which results in propagating health status to Eureka. +As a consequence, other applications won't send traffic to your app unless the health checks and contributors report 'UP'. + +If you require more control over the health checks, consider implementing your own `IHealthCheckHandler`. + +## Configuring multiple Eureka servers + +You can specify a comma-delimited list of Eureka server URLs that the client uses when registering or fetching +the service registry. Those servers should be part of a properly configured Eureka server cluster and should be using +peer-to-peer communications to keep in sync. + +The Eureka client automatically fails over to the other nodes in the cluster. When a failed Eureka server node comes +back up, the Eureka client automatically reconnects back to the server at some point. + +## Using metadata + +It is worth spending a bit of time understanding how the Eureka metadata works so that you can use it in a way +that makes sense in your application. + +Standard instance information (such as hostname, IP address, port numbers, status page, and health check endpoint) +is associated with every service registration. These are published in the service registry and are used by clients +to contact the services in a straightforward way. + +You can add additional metadata to instance registrations by using the configuration setting `Eureka:Instance:MetadataMap`. +The key/value pairs you supply there are added to the service registration and become accessible to remote clients. + +When the metadata varies over time, depending on contextual information, it can be updated from code as well: +```csharp +var appManager = app.Services.GetRequiredService(); +appManager.UpdateInstance(newStatus: null, newOverriddenStatus: null, + newMetadata: new Dictionary(appManager.Instance.Metadata) + { + ["someNewKey"] = "someValue1", + ["someExistingKey"] = "someValue2" + }); +``` + +> [!WARN] +> Once metadata has been updated from code, later metadata changes in configuration are ignored. + +In general, additional metadata does not change the behavior of applications, unless they are made aware of +the meaning of the metadata. + +## Configuring mutual TLS + +To use mutual TLS authentication in the communication with the Eureka server, +add the path to your certificate file(s) to `appsettings.json`. For example: + +```json +"Certificates": { + "Eureka": { + "CertificateFilePath": "example.p12" + } +} +``` +or: +```json +"Certificates": { + "Eureka": { + "CertificateFilePath": "example.crt", + "PrivateKeyFilePath": "example.key" + } +} +``` + +> [!NOTE] +> To support certificate rotation, the configuration keys and the files on disk are automatically monitored for changes. + +> [!TIP] +> A single certificate can be shared with both Config Server and Eureka, by using the key "Certificates" instead of "Certificates:Eureka". + +### Using custom HTTP headers + +The communication with Eureka server uses the `HttpClientFactory` [pattern](https://learn.microsoft.com/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests), +which makes it aware of DNS changes over time and enables to tweak the handler pipeline. + +To send a custom HTTP header with every request, create a `DelegatingHandler` and add it to the pipeline: +```csharp +builder.Services.AddEurekaDiscoveryClient(); +builder.Services.AddTransient(); + +builder.Services.Configure("Eureka", options => +{ + options.HttpMessageHandlerBuilderActions.Add(handlerBuilder => + handlerBuilder.AdditionalHandlers.Add( + handlerBuilder.Services.GetRequiredService())); +}); + +public sealed class ExtraRequestHeaderDelegatingHandler : DelegatingHandler +{ + protected override Task SendAsync( + HttpRequestMessage request, CancellationToken cancellationToken) + { + request.Headers.Add("X-Example", "ExampleValue"); + return base.SendAsync(request, cancellationToken); + } +} +``` + +> [!NOTE] +> To send an extra header to the OAuth2 endpoint, replace `"Eureka"` with `"AccessTokenForEureka"` in the example above. diff --git a/api/v4/fileshares/index.md b/api/v4/fileshares/index.md new file mode 100644 index 00000000..5bdc23be --- /dev/null +++ b/api/v4/fileshares/index.md @@ -0,0 +1,5 @@ +# Windows Network File Shares + +Steeltoe's `WindowsNetworkFileShare` class provides a simplified experience for interacting with SMB file shares by making [P/Invoke calls](https://learn.microsoft.com/cpp/dotnet/how-to-call-native-dlls-from-managed-code-using-pinvoke) to underlying Windows APIs, specifically to `mpr.dll`. For more background on SMB, see the [Microsoft SMB Protocol documentation](https://learn.microsoft.com/windows/win32/fileio/microsoft-smb-protocol-and-cifs-protocol-overview). + +Network shares are not the most cloud-native way to deal with files. For new development, consider exploring message queues, caches, blob stores, and NoSQL stores. The alternatives offer greater resiliency and decoupling from backing services. That said, sometimes the alternatives are not viable. For .NET applications deployed to Microsoft Windows Servers, Steeltoe provides a stepping stone towards cloud-native in the form of the `WindowsNetworkFileShare`. For applications deployed to Linux hosts on the Tanzu Platform, [volume services](https://docs.vmware.com/en/VMware-Tanzu-Application-Service/6.0/tas-for-vms/enable-vol-services.html) are available. diff --git a/api/v4/fileshares/usage.md b/api/v4/fileshares/usage.md new file mode 100644 index 00000000..becff280 --- /dev/null +++ b/api/v4/fileshares/usage.md @@ -0,0 +1,86 @@ +# Usage + +Before starting with Steeltoe's Windows Network File Share library, you should already have a plan for interacting with the file system. Steeltoe only manages the connection to the file share. + +## Add NuGet References + +To use the `WindowsNetworkFileShare` class, you need to add a reference to the `Steeltoe.Common.Net` NuGet package. + +## Managing the Connection + +The state of the connection to the file share is managed through the lifecycle of `WindowsNetworkFileShare`. To open the connection, instantiate a `WindowsFileShare`: + +```csharp +using System.Net; +using Steeltoe.Common.Net; + +var fileShare = new WindowsNetworkFileShare(@"\\server\path", new NetworkCredential("username", "password")); +``` + +The constructor opens the connection with the equivalent of the `net use` command. + +To close the connection, call dispose on the `WindowsNetworkFileShare`: + +```csharp +fileShare.Dispose(); +``` + +Because `WindowsNetworkFileShare` implements `IDisposable`, you can also manage the `WindowsNetworkFileShare` with a `using` statement: + +```csharp +using (new WindowsNetworkFileShare(@"\\server\path", new NetworkCredential("username", "password"))) +{ + // Interact with an attached network share here. +} +``` + +### Managing Credentials + +Credentials are generally required for interacting with SMB shares. `WindowsNetworkFileShare` does not have an opinion on where those credentials are stored. However, as a general guideline, storing credentials with your application's code or standard configuration is not recommended. Consider using the [CredHub Service Broker](https://docs.vmware.com/en/VMware-Tanzu-Application-Service/6.0/tas-for-vms/credhub-index.html) for storing and retrieving your credentials. + +When used in conjunction with the Cloud Foundry Configuration Provider, you can access the values as follows: + +```shell +dotnet add package Steeltoe.Configuration.CloudFoundry +dotnet add package Steeltoe.Common.Net +``` + +```csharp +using System.Net; +using Microsoft.Extensions.Options; +using Steeltoe.Common.Net; +using Steeltoe.Configuration.CloudFoundry; + +var builder = WebApplication.CreateBuilder(args); +builder.AddCloudFoundryConfiguration(); +builder.Services.AddSingleton(); + +var app = builder.Build(); + +var reader = app.Services.GetRequiredService(); +var credentials = reader.ReadCredentials(); + +using (new WindowsNetworkFileShare(@"\\server\path", credentials)) +{ + // Interact with an attached network share here. +} + +public sealed class CredentialsReader(IOptionsMonitor optionsMonitor) +{ + public NetworkCredential ReadCredentials() + { + foreach (CloudFoundryService service in optionsMonitor.CurrentValue.GetServicesOfType("credhub")) + { + if (service.Name == "my-network-share") + { + string? username = service.Credentials["share-username"].Value; + string? password = service.Credentials["share-password"].Value; + + return new NetworkCredential(username, password); + } + } + + throw new InvalidOperationException("No credentials found for 'my-network-share'"); + } +} +``` diff --git a/api/v4/initializr/images/default.png b/api/v4/initializr/images/default.png new file mode 100644 index 00000000..76d47759 Binary files /dev/null and b/api/v4/initializr/images/default.png differ diff --git a/api/v4/initializr/images/explore.png b/api/v4/initializr/images/explore.png new file mode 100644 index 00000000..7e4247ab Binary files /dev/null and b/api/v4/initializr/images/explore.png differ diff --git a/api/v4/initializr/images/generate.png b/api/v4/initializr/images/generate.png new file mode 100644 index 00000000..b8c1ab54 Binary files /dev/null and b/api/v4/initializr/images/generate.png differ diff --git a/api/v4/initializr/images/share.png b/api/v4/initializr/images/share.png new file mode 100644 index 00000000..3314ef3b Binary files /dev/null and b/api/v4/initializr/images/share.png differ diff --git a/api/v4/initializr/index.md b/api/v4/initializr/index.md new file mode 100644 index 00000000..2f19084f --- /dev/null +++ b/api/v4/initializr/index.md @@ -0,0 +1,13 @@ +# Initializr + +An Initializr jumpstarts .NET development by generating projects based on project metadata. +Metadata may include, among other properties, a project name, a namespace, and a list of dependencies. +At the core of an Initializr is the _[InitializrService](https://github.com/SteeltoeOSS/InitializrService)_. +_InitializrService_ provides several REST/HTTP endpoints, which includes an endpoint to generate projects, and an endpoint to provide smart clients the metadata needed to construct user interfaces. + +It is possible to have a fully functioning Initializr deployment by simply deploying the _InitializrService_. +A more user-friendly deployment may include a user interface, such as a web frontend or an IDE plugin. +A deployment may also leverage a _[Spring Cloud Config Server](https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_server.html)_ to access a configuration store. +As an example, the [Steeltoe Initializr deployment](https://start.steeltoe.io) includes _[InitializrWeb](https://github.com/SteeltoeOSS/InitializrWeb)_ for a friendly user experience and a _Spring Cloud Config Server_ using a GitHub-maintained configuration. + +_InitializrWeb_ is the reference UI for the Steeltoe Initializr and is an example of a smart client. It uses project metadata from the _InitializrService_ to populate its web controls with, for example, supported .NET target frameworks and Steeltoe versions. diff --git a/api/v4/initializr/initializr-service.md b/api/v4/initializr/initializr-service.md new file mode 100644 index 00000000..786233d3 --- /dev/null +++ b/api/v4/initializr/initializr-service.md @@ -0,0 +1,116 @@ +# InitializrService + +The _InitializrService_ provides 4 REST/HTTP endpoints: + +* `api/` +* `api/about` +* `api/config` +* `api/project` + +## `api/` + +`api/` accepts `GET` requests and returns a help document. +The document includes available parameters (and their defaults) and dependencies, as well as CLI samples. + +```bash +# sample: view help doc +$ http -p b https://start.steeltoe.io/api/ +... +This service generates quickstart projects that can be easily customized. +Possible customizations include a project's dependencies and .NET target framework. + +The URI templates take a set of parameters to customize the result of a request. ++-----------------+-----------------------+----------------------------+ +| Parameter | Description | Default value | ++-----------------+-----------------------+----------------------------+ +| name | project name | Sample | +| applicationName | application name | SampleApplication | +... +``` + +## `api/about` + +`api/about` accepts `GET` requests and returns the _InitialzrService_ "About" information. + +```bash +# sample: view "About" document +$ http -p b https://start.steeltoe.io/api/about +{ + "commit": "381bbd2a1e30d621ed6ad4a07790955447ffe468", + "name": "Steeltoe.InitializrApi", + "url": "https://github.com/SteeltoeOSS/InitializrApi/", + "vendor": "SteeltoeOSS/VMware", + "version": "0.8.0" +} +``` + +## `api/config` + +`api/config` accepts `GET` requests and returns _InitializrService_ configuration. +The returned document includes *all* configuration which can include superfluous details. +Sub-endpoints are available allowing more targeted responses. + +`api/config/projectMetadata` can be used by smart clients, such as the _InitializrWeb_, to assist in creating user interfaces. + +The following endpoints can be used by CLI users to browse project configuration options: + +* `api/config/archiveTypes` +* `api/config/dependencies` +* `api/config/dotNetFrameworks` +* `api/config/dotNetTemplates` +* `api/config/languages` +* `api/config/steeltoeVersions` + +```bash +# sample: list available Steeltoe versions +$ http -p b https://start.steeltoe.io/api/config/steeltoeVersions +[ + { + "id": "2.4.4", + "name": "Steeltoe 2.4.4 Maintenance Release" + }, + { + "id": "2.5.1", + "name": "Steeltoe 2.5.1 Maintenance Release" + }, + { + "id": "3.0.1", + "name": "Steeltoe 3.0.1 Maintenance Release" + } +] + +# sample: list available dependency IDs +$ http https://start.steeltoe.io/api/config/dependencies | jq '.[] .values[] .id' | sort +"actuator" +"amqp" +"azure-spring-cloud" +"cloud-foundry" +"config-server" +"data-mongodb" +"data-redis" +"docker" +"dynamic-logger" +"eureka-client" +"mysql" +"mysql-efcore" +"oauth" +"placeholder" +"postgresql" +"postgresql-efcore" +"random-value" +"sqlserver" +``` + +## `api/project` + +`api/project` accepts `GET` and `POST` requests and returns a project as an archive. + +Projects are configured by using HTTP parameters, such as `name` for the project name and `steeltoeVersion` for the Steeltoe version. +The parameter `dependencies` is a little different than other parameters in that it is set to a comma-separated list of dependency IDs. + +_Note: to get a list of parameters and dependencies, send a `GET` request to `api/`._ + +```bash +# sample: generate a .NET Core App 3.1 project with actuator endpoints and a Redis backend: +$ http https://start.steeltoe.io/api/project dotNetFramework=netcoreapp3.1 dependencies==actuators,redis -d +``` diff --git a/api/v4/initializr/initializr-web.md b/api/v4/initializr/initializr-web.md new file mode 100644 index 00000000..a847def1 --- /dev/null +++ b/api/v4/initializr/initializr-web.md @@ -0,0 +1,61 @@ +# InitializrWeb + +_InitializrWeb_ is a web frontend for an Initializr deployment. +It uses _InitializrApi_-provided project metadata to populate its interface for easy perusal and selection by an end user. +After selecting desired project parameters, an end user uses _InitializrWeb_ to submit project generation requests to the _InitializrApi_. + +## Overview + +![Steeltoe Initializr](./images/default.png) + +The interface is made up of 4 areas: + +* project configuration area +* project action area (bottom) +* UI configuration (right) +* external links (left) + +The remainder of this document focuses on the project configuration and action areas. + +## Configuration + +The configuration area exposes 5 project properties to the end user: + +* name +* C# namespace +* application name +* description +* Steeltoe version +* .NET target framework +* .NET template +* dependencies + +## Actions + +The actions area provides 3 project actions to the end user: + +* generate +* explore +* share + +### Generate + +Clicking "Generate" submits the current configuration to the _InitializrApi_ to generate a project archive. +The resultant project archive is a Zip file named based on the project name. + +![Steeltoe Initializr generate](images/generate.png) + +### Explore + +Clicking "Explore" submits the current configuration to the _InitializrApi_ to generate a project archive. +The resultant project archive is expanded in the UI so that the end user can explore the project. + +![Steeltoe Initializr explore](images/explore.png) + +### Share + +Clicking "Share" displays a URL that represents the current project configuration. +It can be shared with other developers or saved in a bookmark. +Note that the URL is specific to _InitializrWeb_ and cannot be used directly with the _InitializrApi_. + +![Steeltoe Initializr share](images/share.png) diff --git a/api/v4/logging/dynamic-console-logging.md b/api/v4/logging/dynamic-console-logging.md new file mode 100644 index 00000000..381567a0 --- /dev/null +++ b/api/v4/logging/dynamic-console-logging.md @@ -0,0 +1,35 @@ +# Dynamic Console Logging + +This logging provider is a wrapper around the [Microsoft Console Logger](https://learn.microsoft.com/dotnet/core/extensions/logging-providers#console). It allows for querying the active loggers and their minimum levels, as well as then modifying the levels dynamically at runtime via the [loggers actuator](../management/loggers.md). + +> [!CAUTION] +> External tool integration involves sending the fully-qualified logger name over HTTP. Avoid using colons in the name of a logger to prevent invalid HTTP requests. + +## Usage + +Before starting to use Steeltoe provider, you should know how [Logging in .NET](https://learn.microsoft.com/aspnet/core/fundamentals/logging) works, as Steeltoe provides nothing more than a wrapper around the existing Microsoft console logger. + +To use the Steeltoe logging provider, you need to: + +1. Add the appropriate NuGet package reference to your project. +1. Configure logging settings. +1. Add the dynamic logging provider to the logging builder. + +### Add NuGet References + +To use the logging provider, you need to add a reference to the `Steeltoe.Logging.DynamicConsole` NuGet package. + +### Configure Settings + +As mentioned earlier, the Steeltoe Logging provider is a wrapper around the Microsoft Console logging provider. Consequently, you can configure it the same way you would the Microsoft provider. For more details on how this is done, see [Configure logging](https://learn.microsoft.com/aspnet/core/fundamentals/logging#configure-logging). + +### Add the Logging Provider + +To use the provider, you need to add it to the logging builder by using the `AddDynamicConsole()` extension method: + +```csharp +using Steeltoe.Logging.DynamicConsole; + +var builder = WebApplication.CreateBuilder(args); +builder.Logging.AddDynamicConsole(); +``` diff --git a/api/v4/logging/dynamic-serilog-logging.md b/api/v4/logging/dynamic-serilog-logging.md new file mode 100644 index 00000000..6ee13c07 --- /dev/null +++ b/api/v4/logging/dynamic-serilog-logging.md @@ -0,0 +1,129 @@ +# Dynamic Serilog Logging + +This logging provider integrates with [Serilog](https://serilog.net/). It enables logger minimum levels configured via Serilog to be queried and modified at runtime via the [loggers actuator](../management/loggers.md). + +## Usage + +To use the Serilog Dynamic Logger, you need to do the following: + +1. Add the appropriate NuGet package reference to your project. +1. Configure Logging settings. +1. Add the Serilog Dynamic Logger to the logging builder. + +### Add NuGet References + +To use the logging provider, you need to add a reference to the `Steeltoe.Logging.DynamicSerilog` NuGet package. + +### Configure Settings + +As mentioned earlier, the Serilog Dynamic Logger provider extends Serilog. Consequently, you can configure it the same way you would Serilog. For more details on how this is done, see [Serilog-Settings-Configuration](https://github.com/serilog/serilog-settings-configuration). + +```json +{ + "Serilog": { + "MinimumLevel": { + "Default": "Warning", + "Override": { + "Microsoft": "Warning", + "Steeltoe": "Information", + "MyApp": "Verbose" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext}: {Properties}{NewLine} {Message:lj}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} +``` + +Alternatively, configuration can be built from code using the Serilog API: + +```csharp +using Serilog; +using Serilog.Events; + +var serilogConfiguration = new LoggerConfiguration() + .MinimumLevel.Warning() + .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .MinimumLevel.Override("Steeltoe", LogEventLevel.Information) + .MinimumLevel.Override("MyApp", LogEventLevel.Verbose) + .WriteTo.Console(outputTemplate: + "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext}: {Properties}{NewLine} {Message:lj}{NewLine}{Exception}") + .Enrich.FromLogContext(); +``` + +### Add Serilog Dynamic Logger + +To use this logging provider, you need to add it to the logging builder by using the `AddDynamicSerilog()` extension method: + +```csharp +using Steeltoe.Logging.DynamicSerilog; + +var builder = WebApplication.CreateBuilder(args); +builder.Logging.AddDynamicSerilog(); +``` + +If you built the Serilog configuration from code, use the appropriate overload instead: +```csharp +builder.Logging.AddDynamicSerilog(serilogConfiguration); +``` + +### Serilog API usage + +Because dynamic logging is built on the `Microsoft.Extensions.Logging` abstractions, changing log levels dynamically **won't work** if you're using Serilog's static `Log` class directly. + +```csharp +using Serilog; + +// Use ILogger instead. +Log.Warning("DO NOT USE!"); +``` + +Instead, use the injectable `ILogger` interface to log messages, and the `ILoggerFactory` interface to create loggers. + +```csharp +using Steeltoe.Logging.DynamicSerilog; + +var builder = WebApplication.CreateBuilder(args); +builder.Logging.AddDynamicSerilog(); + +var app = builder.Build(); + +var programLogger = app.Services.GetRequiredService>(); +programLogger.LogInformation("Hello from Program."); + +var loggerFactory = app.Services.GetRequiredService(); +var exampleLogger = loggerFactory.CreateLogger("Example"); +exampleLogger.LogInformation("Hello from Example."); +``` + +The Serilog dynamic logger supports the use of logger scopes, as well as Serilog's enrichers and destructuring. + +```csharp +using Serilog.Context; +using Steeltoe.Logging.DynamicSerilog; + +var loggerFactory = app.Services.GetRequiredService(); +var logger = loggerFactory.CreateLogger("Example"); + +// ILogger scopes. +using (logger.BeginScope("ExampleScope")) +{ + logger.LogInformation("Hello from Example."); +} + +// Serilog enrichers. +using (LogContext.PushProperty("SerilogExampleScope", 123)) +{ + logger.LogInformation("Hello from Example."); +} + +// Serilog destructuring. +logger.LogInformation("App started with {ArgCount} arguments.", args.Length); +``` diff --git a/api/v4/logging/index.md b/api/v4/logging/index.md new file mode 100644 index 00000000..0422cbb9 --- /dev/null +++ b/api/v4/logging/index.md @@ -0,0 +1,6 @@ +# Dynamic Logging + +Steeltoe includes two logging providers that enhance existing logger libraries with support for managing minimum log levels at runtime through the [Steeltoe Management logger endpoint](../management/loggers.md) and [recording distributed trace information](../tracing/index.md#log-correlation). + +* [Dynamic Console Logging](./dynamic-console-logging.md) works with `Microsoft.Extensions.Logging.Console`. +* [Dynamic Serilog Logging](./dynamic-serilog-logging.md) works with `Serilog` diff --git a/api/v4/management/cloud-foundry.md b/api/v4/management/cloud-foundry.md new file mode 100644 index 00000000..3781c1e5 --- /dev/null +++ b/api/v4/management/cloud-foundry.md @@ -0,0 +1,81 @@ +# Cloud Foundry Integration + +Integration with [Tanzu Apps Manager](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform/tanzu-platform-for-cloud-foundry/10-0/tpcf/console-index.html) is accomplished by adding the Cloud Foundry management endpoint to your application. + +When used, this endpoint enables the following additional functionality on Cloud Foundry: + +* A variant of the [hypermedia](./hypermedia.md) endpoint is registered at `/cloudfoundryapplication`. +* All endpoints are additionally mapped under the base path `/cloudfoundryapplication`. +* [Authentication and authorization](#security) for your Cloud Foundry environment is added to the request pipeline. + +> [!NOTE] +> The Cloud Foundry integration will not work unless the [Cloud Foundry Configuration Provider](../configuration/cloud-foundry-provider.md) has also been configured. + +## Configure Settings + +Typically, no additional configuration is needed. However, the following table describes the configuration settings that you can apply to the Cloud Foundry endpoint. +Each key must be prefixed with `Management:Endpoints:CloudFoundry`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `""` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | +| `ValidateCertificates` | Whether to validate server certificates. | `true` | +| `ApplicationId` | The ID of the application used in permission checks. | | +| `CloudFoundryApi` | The URL of the Cloud Foundry API. | | + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/cloudfoundryapplication`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container, add a [CORS](#cross-origin-resource-sharing) policy, register security middleware and map its route, use the `AddCloudFoundryActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Configuration.CloudFoundry; +using Steeltoe.Management.Endpoint.Actuators.CloudFoundry; + +var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddCloudFoundry(); +builder.Services.AddCloudFoundryActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +### Cross Origin Resource Sharing + +When viewing an application in Apps Manager, HTTP requests are sent directly to application instances with the bearer token of the logged-in user attached. +The nature of this integration requires the use of Cross Origin Resource Sharing ([CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)). +The policy defined in Steeltoe intends to limit sharing to the minimum required for the endpoints to function, however there is no way for Steeltoe to discover or even guess at what the origin of an Apps Manager instance could be. +As such, the default policy will allow any origin, unless the policy is customized. You should consider [customizing the CORS policy](./using-endpoints.md#customizing-the-cors-policy) to be more specific. + +## Security + +When adding this management endpoint to your application, the Cloud Foundry security middleware is added to the request processing pipeline of your application. +The Cloud Foundry security middleware requires a valid UAA access token to be provided as part of any request to any of the management endpoints. +Additionally, the security middleware evaluates the token to determine whether the authenticated user has permission to access the management endpoint. + +> [!NOTE] +> The Cloud Foundry security middleware is only active when your application is running on Cloud Foundry. + +## External access + +When running in Cloud Foundry, it is still possible to access the endpoints via the [hypermedia](./hypermedia.md) URL, which defaults to `/actuator`. +In other words, you can also access all your endpoints from this URL prefix. For example, the [info](./info.md) endpoint would be accessible at `/actuator/info`. + +While the endpoints provided on the `/cloudfoundryapplication` path are secured as described above, the endpoints provided on the `/actuator` path are not. +For this reason, all endpoints are exposed by default at `/cloudfoundryapplication`, but only health and info are exposed by default at `/actuator`. +In addition, the endpoints may be secured by whatever security mechanism the application itself uses. For more details, see [securing actuators](./using-endpoints.md#securing-endpoints). + +> [!CAUTION] +> Applying an authorization policy on `/actuator` will also impact `/cloudfoundryapplication`, which will break the integration with Apps Manager. +> In order to prevent public access to `/actuator` when running on Cloud Foundry, consider configuring actuators to [use an alternate port](./using-endpoints.md#configure-global-settings). diff --git a/api/v4/management/dbmigrations.md b/api/v4/management/dbmigrations.md new file mode 100644 index 00000000..5f9e24e4 --- /dev/null +++ b/api/v4/management/dbmigrations.md @@ -0,0 +1,61 @@ +# Database Migrations + +The Steeltoe Database Migrations endpoint exposes information about database migrations that are available to an application's data source that has been built with Entity Framework Core (EF Core). EF Core migrations give developers the ability to update an application's database schema while staying consistent with the application's data model without removing any existing data. + +> [!NOTE] +> Please review Microsoft's [EF Core Migrations Overview](https://learn.microsoft.com/ef/core/managing-schemas/migrations) for more in-depth information. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:DbMigrations:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `dbmigrations` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/dbmigrations`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddDbMigrationsActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.DbMigrations; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddDbMigrationsActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +## Sample Output + +This endpoint returns a list of objects representing each registered `DbContext` along with its migrations, grouped by status (pending or applied). + +The response will always be returned as JSON, like this: + +```json +{ + "AppDbContext": { + "pendingMigrations": [ + "20241028091643_AddTable" + ], + "appliedMigrations": [ + "20241028091056_InitialCreate", + "20241028091550_AddDbColumn" + ] + } +} +``` diff --git a/api/v4/management/env.md b/api/v4/management/env.md new file mode 100644 index 00000000..25eb7e47 --- /dev/null +++ b/api/v4/management/env.md @@ -0,0 +1,71 @@ +# Environment + +The Steeltoe Environment endpoint can be used to query the configuration providers and their keys and values currently in use in your application. The endpoint retrieves this information from the application's `IConfiguration`. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:Env:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `env` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | +| `KeysToSanitize` | An array of keys to sanitize. [^1] | `[ "password", "secret", "key", "token", ".*credentials.*", "vcap_services" ]` | + +[^1]: A key can be a simple string that the property must end with, or a regular expression. A case-insensitive match is always performed. Use a single-element empty string to disable sanitization. + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/env`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddEnvironmentActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Environment; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddEnvironmentActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +## Sample Output + +This endpoint returns a list of objects representing information from `IConfiguration`. + +The response will always be returned as JSON, like this: + +```json +{ + "activeProfiles": [ + "Development" + ], + "propertySources": [ + { + "name": "JsonConfigurationProvider: [appsettings.json]", + "properties": { + "AllowedHosts": { + "value": "*" + }, + "Logging:LogLevel:Default": { + "value": "Information" + }, + "Logging:LogLevel:Microsoft.AspNetCore": { + "value": "Warning" + } + } + } + ] +} +``` diff --git a/api/v4/management/health.md b/api/v4/management/health.md new file mode 100644 index 00000000..ca5bfdf5 --- /dev/null +++ b/api/v4/management/health.md @@ -0,0 +1,396 @@ +# Health + +You can use the Steeltoe Health endpoint to query the status of your running application. +It is often used to monitor software and alert someone if a production system goes down. + +Health information is collected from all `IHealthContributor` implementations registered in the application, +as well as from [ASP.NET Core Health Checks](https://learn.microsoft.com/aspnet/core/host-and-deploy/health-checks). +Steeltoe includes several contributors out of the box that you can use. +Other Steeltoe components typically add their own contributors where applicable. +Also, and perhaps more importantly, you can write your own. + +By default, the final application health state is computed by the registered `IHealthAggregator` implementation. +It is responsible for sorting out all of the returned statuses from each `IHealthContributor` and [`IHealthCheck`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.diagnostics.healthchecks.ihealthcheck) and deriving an overall application health state. +The built-in aggregator returns the "worst" status returned from the contributors and checks. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:Health:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `health` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | +| `ShowComponents` | Whether health check components should be included in the response. | `Never` | +| `ShowDetails` | Whether details of health check components should be included in the response. | `Never` | +| `Claim` | The claim required in `HttpContext.User` when `ShowComponents` and/or `ShowDetails` is set to `WhenAuthorized`. | | +| `Role` | The role required in `HttpContext.User` when `ShowComponents` and/or `ShowDetails` is set to `WhenAuthorized`. | | + +The depth of information exposed by the health endpoint depends on the `ShowComponents` and `ShowDetails` properties, which can both be configured with one of the following values: + +| Name | Description | +| --- | --- | +| `Never` | Never shown. | +| `WhenAuthorized` | Shown only to authorized users. | +| `Always` | Always shown. | + +`ShowDetails` only has an effect when `ShowComponents` is set to `Always`, or `WhenAuthorized` and the request is authorized. + +Authorized users can be configured by setting `Claim` or `Role`. +A user is considered to be authorized when they are in the given role or have the specified claim. +The following example uses `Management:Endpoints:Health:Claim`: + +```json +{ + "Management": { + "Endpoints": { + "Health": { + "ShowComponents": "WhenAuthorized", + "ShowDetails": "WhenAuthorized", + "Claim": { + "Type": "health_actuator", + "Value": "see_all" + } + } + } + } +} +``` + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/health`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddHealthActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Health; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHealthActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +By default, the health status is reflected in the HTTP response status code. +For example, when a health check fails, the response status code is `503 Service Unavailable`. +The configuration key `Management:Endpoints:UseStatusCodeFromResponse` can be set to `false`, which makes the health response status code always be `200 OK`. +Clients can overrule this per request by sending an `X-Use-Status-Code-From-Response` HTTP header with the value `true` or `false`. + +> [!TIP] +> By default, health contributors for disk space and ping are activated. They can be turned off through configuration: +> +> ```json +> { +> "Management": { +> "Endpoints": { +> "Health": { +> "DiskSpace": { +> "Enabled": "false" +> }, +> "Ping": { +> "Enabled": "false" +> } +> } +> } +> } +> } +> ``` + +## Sample Output + +This endpoint returns the top-level status, along with the details of the contributors and checks. + +The response will always be returned as JSON, and this is the default value: + +```json +{ + "status": "UP" +} +``` + +When `ShowComponents` and `ShowDetails` are set to `Always`, or when set to `WhenAuthorized` and the request is authorized, the response is more detailed: + +```json +{ + "status": "UP", + "components": { + "ping": { + "status": "UP" + }, + "diskSpace": { + "status": "UP", + "details": { + "total": 1999599824896, + "free": 1330717282304, + "threshold": 10485760, + "path": "C:\\source\\Repository\\src\\Project", + "exists": true + } + } + } +} +``` + +> [!NOTE] +> When using Steeltoe Connectors, Service Discovery, or Config Server in your application, the corresponding health contributors are automatically added to the service container. +> See their corresponding documentation for how to turn them off. + +## Health Groups + +Should you need to check application health based on a subset of health contributors, you may specify the name of the grouping and a comma-separated list of contributors to include like this: + +```json +{ + "Management": { + "Endpoints": { + "Health": { + "Groups": { + "example-group": { + "Include": "Redis,RabbitMQ" + } + } + } + } + } +} +``` + +While group names are case-sensitive, the entries in `Include` are case-insensitive and will only activate health contributors with a matching `Id`, and/or ASP.NET health check registrations with a matching name. + +For any group that has been defined, you may access health information from the group by appending the group name to the HTTP request URL. For example: `/actuator/health/example-group`. + +`ShowComponents` and `ShowDetails` can also be set at the group level, overriding the settings found at the endpoint level. + +```json +{ + "Management": { + "Endpoints": { + "Health": { + "Claim": { + "Type": "health_actuator", + "Value": "see_all" + }, + "Groups": { + "example-group": { + "Include": "Redis,RabbitMQ", + "ShowComponents": "Always", + "ShowDetails": "WhenAuthorized" + } + } + } + } + } +} +``` + +### Kubernetes Health Groups + +Applications deployed on Kubernetes can provide information about their internal state with [Container Probes](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes). +Depending on your [Kubernetes configuration](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/), the kubelet will call those probes and react to the result. + +Steeltoe provides an [`ApplicationAvailability`](https://github.com/SteeltoeOSS/Steeltoe/blob/main/src/Management/src/Endpoint/Actuators/Health/Availability/ApplicationAvailability.cs) class for managing various types of application state. +Out of the box, support is provided for Liveness and Readiness, where each is exposed in a corresponding `IHealthContributor` and health group. +While these health contributors are included, they are disabled by default and must be enabled in configuration (as demonstrated in the example below). + +To change the health contributors that are included in either of the two built-in groups, use the same style of configuration described above. +Please note that this will _replace_ these groupings, so if you would like to _add_ an `IHealthContributor` you will need to include the original entry. +These entries demonstrate enabling the probes, their groups and including disk space in both groups: + +```json +{ + "Management": { + "Endpoints": { + "Health": { + "Liveness": { + "Enabled": "true" + }, + "Readiness": { + "Enabled": "true" + }, + "Groups": { + "liveness": { + "Include": "diskSpace,livenessState" + }, + "readiness": { + "Include": "diskSpace,readinessState" + } + } + } + } + } +} +``` + +#### Liveness + +The "Liveness" state of an application instance tells whether its internal state allows it to work correctly, or recover by itself if it's currently failing. A broken "Liveness" state means that the application is in a state that it cannot recover from, and the infrastructure should restart the application. + +Out of the box, any of Steeltoe's extension methods that set up the health actuator will initialize the liveness state `LivenessState.Correct`. The only other defined state for liveness is `LivenessState.Broken`, though Steeltoe code does not currently cover any conditions that set this state. + +> [!NOTE] +> In general, the "Liveness" state should not depend on external system checks such as a database, queue, or cache server. Including checks on external systems could trigger massive restarts and cascading failures across the platform. + +#### Readiness + +The "Readiness" state of an application instance describes whether the application is ready to handle traffic. A failing "Readiness" state tells the platform that it should not route traffic to the application instance. + +Out of the box, any of Steeltoe's extension methods that set up the health actuator will also register a callback on [`ApplicationStarted`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.hosting.iapplicationlifetime.applicationstarted) to initialize the readiness state to `AcceptingTraffic` when the application has started, and register a callback on [`ApplicationStopping`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.hosting.iapplicationlifetime.applicationstopping) to change the state to `RefusingTraffic` when the application begins to shut down. These are the only defined states for this availability type. + +#### Managing Application Availability State + +Application components can retrieve the current availability state at any time, by requesting `ApplicationAvailability` from the dependency injection container and calling methods on it: + +```csharp +[ApiController] +[Route("[controller]")] +public class AvailabilityController(ApplicationAvailability applicationAvailability) : ControllerBase +{ + [HttpGet] + public string Get() + { + var readinessState = applicationAvailability.GetReadinessState(); + var livenessState = applicationAvailability.GetLivenessState(); + + return $"Readiness state = {readinessState}, Liveness state = {livenessState}"; + } +} +``` + +Additionally, it is possible to subscribe to changes in liveness and readiness by attaching an event handler: + +```csharp +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHealthActuator(); + +var app = builder.Build(); + +var availability = app.Services.GetRequiredService(); +availability.LivenessChanged += (_, args) => Console.WriteLine($"Liveness state changed to {args.NewState}"); +availability.ReadinessChanged += (_, args) => Console.WriteLine($"Readiness state changed to {args.NewState}"); + +app.Run(); +``` + +## Creating a Custom Health Contributor + +If you wish to provide custom health information for your application, create a class that implements the `IHealthContributor` interface and then add it to the service container. + +The following example contributor always returns a `HealthStatus` of `WARNING`: + +```csharp +using Steeltoe.Common.HealthChecks; +using Steeltoe.Management.Endpoint.Actuators.Health; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHealthActuator(); +builder.Services.AddHealthContributor(); + +public class ExampleHealthContributor : IHealthContributor +{ + public string Id => nameof(ExampleHealthContributor); + + public Task CheckHealthAsync(CancellationToken cancellationToken) + { + HealthCheckResult? status = GetStatus(); + return Task.FromResult(status); + } + + private static HealthCheckResult? GetStatus() + { + return new HealthCheckResult + { + Status = HealthStatus.Warning, + Description = "This health check does not check anything" + }; + } +} +``` + +Sending a GET request to `/actuator/health` returns the following response: + +```json +{ + "status":"WARNING" +} +``` + +When `ShowComponents` and `ShowDetails` are set to `Always`, or when set to `WhenAuthorized` and the request is authorized, the response is more detailed: + +```json +{ + "status": "WARNING", + "components": { + "ExampleHealthContributor": { + "status": "WARNING", + "description": "This health check does not check anything" + }, + "ping": { + "status": "UP" + }, + "diskSpace": { + "status": "UP", + "details": { + "total": 1999599824896, + "free": 1330717282304, + "threshold": 10485760, + "path": "C:\\source\\Repository\\src\\Project", + "exists": true + } + } + } +} +``` + +## ASP NET Core Health Checks + +ASP.NET Core also offers [middleware and libraries](https://learn.microsoft.com/aspnet/core/host-and-deploy/health-checks) and abstractions for reporting health. There is wide community support for these abstractions from libraries such as [AspNetCore.Diagnostics.HealthChecks](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks). You can use these community-provided health checks and make them available over the health actuator endpoint (for integration with Cloud Foundry or any other infrastructure that depends on this format). In addition, Steeltoe Connectors expose functionality to get the connection string, which is needed to set up these community health checks. + +For example, to use the Steeltoe MySQL connector, but replace its health contributor with the ASP.NET Core community health check, +use the following code in `Program.cs`: + +```csharp +using Microsoft.Extensions.Options; +using Steeltoe.Connectors.MySql; +using Steeltoe.Management.Endpoint.Actuators.Health; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHealthActuator(); + +// Add the Steeltoe Connector for MySQL, but turn off its health contributor. +builder.AddMySql(null, options => options.EnableHealthChecks = false); + +// Add the community-based ASP.NET health check, obtaining the connection string from Steeltoe. +builder.Services.AddHealthChecks().AddMySql(serviceProvider => +{ + var options = serviceProvider.GetRequiredService>(); + return options.Value.ConnectionString!; +}); +``` + +The code above assumes the following `appsettings.json` configuration, combined with the [Steeltoe docker container for MySQL](https://github.com/SteeltoeOSS/Samples/blob/main/CommonTasks.md#mysql): + +```json +{ + "Steeltoe": { + "Client": { + "MySql": { + "Default": { + "ConnectionString": "SERVER=localhost;Database=steeltoe;UID=steeltoe;PWD=steeltoe" + } + } + } + } +} +``` diff --git a/api/v4/management/heapdump.md b/api/v4/management/heapdump.md new file mode 100644 index 00000000..51cc6276 --- /dev/null +++ b/api/v4/management/heapdump.md @@ -0,0 +1,43 @@ +# Heap Dump + +You can use the Steeltoe Heap Dump endpoint to capture and download a mini-dump of your application. The mini-dump can then be read into Visual Studio for analysis. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:HeapDump:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `heapdump` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | +| `HeapDumpType` | Sets the type of heap dump to capture. | `Full` | + +The `HeapDumpType` setting is supported on Linux and Windows only. +Acceptable values are `Normal`, `WithHeap`, `Triage`, and `Full`. +On macOS, this setting is ignored and a gcdump is always captured. + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/heapdump`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddHeapDumpActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.HeapDump; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHeapDumpActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. diff --git a/api/v4/management/httpexchanges.md b/api/v4/management/httpexchanges.md new file mode 100644 index 00000000..efa337e7 --- /dev/null +++ b/api/v4/management/httpexchanges.md @@ -0,0 +1,186 @@ +# HTTP Exchanges + +The Steeltoe HTTP Exchanges endpoint provides the ability to view the last several requests made of your application. + +When you activate this endpoint, an `IHttpExchangesRepository` implementation is registered that stores HTTP request/response information in memory, that can be retrieved by using the endpoint. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:HttpExchanges:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `httpexchanges` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | +| `Capacity` | Size of the circular buffer of exchanges. | 100 | +| `IncludeRequestHeaders` | Whether to return headers from the HTTP request. | `true` | +| `RequestHeaders` | An array of HTTP request headers to return unredacted, in addition to the default set. | | +| `IncludeResponseHeaders` | Whether to return headers from the HTTP response. | `true` | +| `ResponseHeaders` | An array of HTTP response headers to return unredacted, in addition to the default set. | | +| `IncludePathInfo` | Whether to return the path from the HTTP request URL. | `true` | +| `IncludeQueryString` | Whether to return the query string parameters from the request URL. | `true` | +| `IncludeUserPrincipal` | Whether to return the username from [`HttpContext.User`](https://learn.microsoft.com/dotnet/api/system.security.claims.claimsprincipal). | `false` | +| `IncludeRemoteAddress` | Whether to return the IP address from the sender. | `false` | +| `IncludeSessionId` | Whether to return the user's session ID. | `false` | +| `IncludeTimeTaken` | Whether to return the request duration. | `true` | +| `Reverse` | Whether to return exchanges in reverse order (newest first). | `true` | + +All request and response header values are redacted by default, except for the whitelisted entries below. +To return additional headers unredacted, add them to the `RequestHeaders` or `ResponseHeaders` arrays. + +Whitelist of HTTP request headers: +- Accept +- Accept-Charset +- Accept-Encoding +- Accept-Language +- Allow +- Cache-Control +- Connection +- Content-Encoding +- Content-Length +- Content-Type +- Date +- DNT +- Expect +- Host +- Max-Forwards +- Range +- Sec-WebSocket-Extensions +- Sec-WebSocket-Version +- TE +- Trailer +- Transfer-Encoding +- Upgrade +- User-Agent +- Warning +- X-Requested-With +- X-UA-Compatible + +Whitelist of HTTP response headers: +- Accept-Ranges +- Age +- Allow +- Alt-Svc +- Connection +- Content-Disposition +- Content-Language +- Content-Length +- Content-Location +- Content-Range +- Content-Type +- Date +- Expires +- Last-Modified +- Location +- Server +- Transfer-Encoding +- Upgrade +- X-Powered-By + +> [!NOTE] +> The built-in whitelists are the same as those used by [ASP.NET Core](https://github.com/dotnet/aspnetcore/blob/release/8.0/src/Middleware/HttpLogging/src/HttpLoggingOptions.cs). + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/httpexchanges`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddHttpExchangesActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.HttpExchanges; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHttpExchangesActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +## Sample Output + +This endpoint returns an array of exchanges. + +The response will always be returned as JSON, like this: + +```json +{ + "exchanges": [ + { + "timeTaken": "PT0.1224915S", + "timestamp": "2024-10-31T16:51:10.9575406Z", + "request": { + "method": "GET", + "uri": "https://localhost:7105/hello?q=a", + "headers": { + "Accept": [ + "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" + ], + "Host": [ + "localhost:7105" + ], + "User-Agent": [ + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" + ], + "Accept-Encoding": [ + "gzip, deflate, br, zstd" + ], + "Accept-Language": [ + "en-US,en;q=0.9,nl;q=0.8" + ], + "Upgrade-Insecure-Requests": [ + "******" + ], + "sec-ch-ua": [ + "******" + ], + "sec-ch-ua-mobile": [ + "******" + ], + "sec-ch-ua-platform": [ + "******" + ], + "sec-fetch-site": [ + "******" + ], + "sec-fetch-mode": [ + "******" + ], + "sec-fetch-user": [ + "******" + ], + "sec-fetch-dest": [ + "******" + ], + "priority": [ + "******" + ] + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Thu, 31 Oct 2024 16:51:10 GMT" + ], + "Server": [ + "Kestrel" + ] + } + } + } + ] +} +``` diff --git a/api/v4/management/hypermedia.md b/api/v4/management/hypermedia.md new file mode 100644 index 00000000..11b60d4d --- /dev/null +++ b/api/v4/management/hypermedia.md @@ -0,0 +1,88 @@ +# Hypermedia + +The purpose of this endpoint is to list the available management endpoints configured in your application. +It returns their IDs and the links to them in JSON format. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:Actuator:`. Note this key differs from the convention used by other actuators. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `""` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | + +> [!NOTE] +> This endpoint is exposed automatically because its ID is empty. To reference this actuator in exposure settings, +> first configure a non-empty ID. Because the Path is the same as ID unless specified, set it to empty explicitly: +> ```json +> { +> "Management": { +> "Endpoints": { +> "Actuator": { +> "Id": "hypermedia", +> "Path": "", +> "Exposure": { +> "Exclude": [ "hypermedia" ] +> } +> } +> } +> } +> } +> ``` + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator`. + +> [!NOTE] +> When running on Cloud Foundry, the [Cloud Foundry Actuator](./cloud-foundry.md) should be used instead, +> whose default path is `/cloudfoundryapplication`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddHypermediaActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Hypermedia; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHypermediaActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +## Sample Output + +This endpoint returns a list of management endpoints, including itself. + +The response will always be returned as JSON, like this: + +```json +{ + "type": "steeltoe", + "_links": { + "info": { + "href": "https://localhost:7105/actuator/info", + "templated": false + }, + "health": { + "href": "https://localhost:7105/actuator/health", + "templated": false + }, + "self": { + "href": "https://localhost:7105/actuator", + "templated": false + } + } +} +``` diff --git a/api/v4/management/index.md b/api/v4/management/index.md new file mode 100644 index 00000000..97ccc19e --- /dev/null +++ b/api/v4/management/index.md @@ -0,0 +1,13 @@ +# Management + +This section describes the various application management facilities that Steeltoe provides. + +## Endpoints + +Steeltoe includes a number of optional features that you can add to your applications to aid in monitoring and managing it while it runs in production. These features are implemented as a number of management endpoints (also known as actuators) that you can easily add to your application. + +The way the endpoints are exposed and used depends on the type of technology you choose to expose the functionality of each endpoint. Out of the box, Steeltoe provides several easy ways to expose these endpoints over HTTP in .NET applications. Of course, you can build and use whatever you would like to meet your needs. + +## Management Tasks + +[Steeltoe Management Tasks](./tasks.md) provide a means of running administrative tasks for ASP.NET Core applications with the same context as the running version of your application. The original use case for this feature is managing database migrations with a bound database service on Cloud Foundry, but the framework is extensible for you to create your own tasks. diff --git a/api/v4/management/info.md b/api/v4/management/info.md new file mode 100644 index 00000000..81ea051a --- /dev/null +++ b/api/v4/management/info.md @@ -0,0 +1,155 @@ +# Info + +The Steeltoe Info endpoint exposes information about the running application, such as its version and the Steeltoe version in use. + +Information is collected from all `IInfoContributor` implementations registered in the application. +Steeltoe includes a couple contributor implementations out of the box that you can use. +Also, and perhaps more importantly, you can write your own. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:Info:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `info` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/info`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddInfoActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Info; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddInfoActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +## Built-in Contributors + +### Build info + +This contributor exposes file/version info for both the application and the included version of Steeltoe. + +### Configuration + +This contributor exposes any values below the `Info` configuration key. For example: +```json +{ + "Info": { + "Some": { + "Example": { + "Key": "some-example-value" + } + } + } +} +``` + +> [!TIP] +> When combined with the [Placeholder Configuration Provider](../configuration/placeholder-provider.md), +> compound configuration values can be exposed originating from other places in configuration. + +### Git properties + +Exposes information from the `git.properties` Spring Boot file, if available. +Shows information from git, such as branch/tag name, commit hash, and remote. + +> [!TIP] +> For an example of how to use this contributor within MSBuild using [GitInfo](https://github.com/devlooped/GitInfo), see the [Steeltoe Management sample](https://github.com/SteeltoeOSS/Samples/tree/main/Management/src). + +## Sample Output + +Depending on the registered contributors, this endpoint returns JSON such as this: + +```json +{ + "git": { + "branch": "main", + "build": { + "host": "examplehost", + "time": "2024-10-11T18:44:28.9255701Z", + "user": { + "email": "user@email.com", + "name": "testuser" + }, + "version": "2.1.0" + }, + "commit": { + "id": "90d0870a363fafcb50981b7038608b763e527e05", + "time": "2024-10-08T17:30:57Z" + }, + "remote": { + "origin": { + "url": "https://github.com/SteeltoeOSS/Samples" + } + }, + "tags": "2.1.0-644-g90d0870a" + }, + "Some": { + "Example": { + "Key": "some-example-value" + } + }, + "applicationVersionInfo": { + "ProductName": "ExampleApp", + "FileVersion": "1.0.0.0", + "ProductVersion": "1.0.0+df774c38b734857909d54b796fffbb717eced4a4" + }, + "steeltoeVersionInfo": { + "ProductName": "Steeltoe.Management.Endpoint", + "FileVersion": "4.0.519.27703", + "ProductVersion": "4.0.519-alpha+6c377e2ac3" + }, + "build": { + "version": "1.0.0.0" + } +} +``` + +## Custom Contributors + +If you wish to provide custom information for your application, create a class that implements the `IInfoContributor` interface and then add it to the service container. + +The following example contributor adds the local server time: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Info; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddInfoActuator(); +builder.Services.AddInfoContributor(); + +public class ServerTimeInfoContributor : IInfoContributor +{ + public Task ContributeAsync(InfoBuilder builder, CancellationToken cancellationToken) + { + builder.WithInfo("server-time", DateTime.Now.ToString("O")); + return Task.CompletedTask; + } +} +``` + +Which returns the following JSON fragment in the response: + +```json +{ + "server-time": "2024-11-01T17:03:05.3490351+01:00" +} +``` diff --git a/api/v4/management/loggers.md b/api/v4/management/loggers.md new file mode 100644 index 00000000..ff1ee6ef --- /dev/null +++ b/api/v4/management/loggers.md @@ -0,0 +1,207 @@ +# Loggers + +The Steeltoe Loggers endpoint provides the ability to view and change the minimum logging levels in your application at runtime by using Steeltoe dynamic logging. + +You can view a list of all active loggers in an application and their current minimum levels. Each entry contains the effective minimum level, and optionally the original minimum level if overridden. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:Loggers:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `loggers` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET`, `POST` | + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/loggers`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddInfoActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Loggers; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddLoggersActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +> [!TIP] +> When `AddLoggersActuator` is called, it tries to register [Dynamic Console Logging](../logging/dynamic-console-logging.md). +> If you'd like to use Serilog instead, call `AddDynamicSerilog` *before* `AddLoggersActuator`. + +## Retrieving Minimum Log Levels + +The response below shows the loggers and their minimum levels for the following `appsettings.json`: + +```json +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Steeltoe.Management": "Error" + } + } +} +``` + +To retrieve the currently active loggers and their minimum log levels, send an HTTP `GET` request to `/actuator/loggers`, +which returns the response below: + +```json +{ + "levels": [ + "OFF", + "FATAL", + "ERROR", + "WARN", + "INFO", + "DEBUG", + "TRACE" + ], + "loggers": { + "Default": { + "effectiveLevel": "INFO" + }, + "Microsoft": { + "effectiveLevel": "INFO" + }, + "Microsoft.AspNetCore": { + "effectiveLevel": "WARN" + }, + "Microsoft.AspNetCore.Cors": { + "effectiveLevel": "WARN" + }, + "Microsoft.Extensions.Hosting": { + "effectiveLevel": "INFO" + }, + "Steeltoe": { + "effectiveLevel": "INFO" + }, + "Steeltoe.Management": { + "effectiveLevel": "ERROR" + }, + "Steeltoe.Management.Endpoint": { + "effectiveLevel": "ERROR" + } + } +} +``` + +The response above shows only effective levels, because there are no runtime overrides yet. + +## Modifying Minimum Log Levels + +Minimum log levels can be changed at runtime by adding the category to the URL of a `POST` request and the minimum level to assign in the request body. + +The category is the fully-qualified name of the logger, which works like a prefix. +For example, changing the minimum log level of `Microsoft.AspNetCore` will affect all loggers whose category starts with +`Microsoft.AspNetCore`, such as `Microsoft.AspNetCore` and `Microsoft.AspNetCore.Cors` (but not `Microsoft.AspNetCoreExtra`). + +> [!NOTE] +> [Spring Boot Admin](https://www.baeldung.com/spring-boot-changing-log-level-at-runtime) and [Tanzu Apps Manager](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform/tanzu-platform-for-cloud-foundry/4-0/tpcf/using-actuators.html#manage-log-levels) +> provide a UI to change the minimum levels at runtime. For compatibility, the level names used by this actuator differ from the names used by .NET. +> +> | Actuator level | .NET level | +> | --- | --- | +> | `OFF` | `LogLevel.None` | +> | `FATAL` | `LogLevel.Critical` | +> | `ERROR` | `LogLevel.Error` | +> | `WARN` | `LogLevel.Warning` | +> | `INFO` | `LogLevel.Information` | +> | `DEBUG` | `LogLevel.Debug` | +> | `TRACE` | `LogLevel.Trace` | + +Using the `appsettings.json` from above, change the minimum log level of the `Steeltoe.Management` category to `TRACE` +by sending a POST request to `/actuator/loggers/Steeltoe.Management` with the following request body: + +```json +{ + "configuredLevel": "TRACE" +} +``` + +> [!TIP] +> Because the logger category is part of the request URL, avoid using colons in the name to prevent invalid HTTP requests. + +To verify the change was applied, send a `GET` request to `/actuator/loggers` to see the updated loggers. +The response below shows that the `Steeltoe.Management` logger (and its descendants) now use a minimum level of `TRACE`. +Furthermore, the `Steeltoe.Management` entry contains both `configuredLevel` and `effectiveLevel`, which means the level can be reset. + +```json +{ + "levels": [ + "OFF", + "FATAL", + "ERROR", + "WARN", + "INFO", + "DEBUG", + "TRACE" + ], + "loggers": { + "Default": { + "effectiveLevel": "INFO" + }, + "Microsoft": { + "effectiveLevel": "INFO" + }, + "Microsoft.AspNetCore": { + "effectiveLevel": "WARN" + }, + "Microsoft.AspNetCore.Cors": { + "effectiveLevel": "WARN" + }, + "Microsoft.Extensions.Hosting": { + "effectiveLevel": "INFO" + }, + "Steeltoe": { + "effectiveLevel": "INFO" + }, + "Steeltoe.Management": { + "configuredLevel": "ERROR", + "effectiveLevel": "TRACE" + }, + "Steeltoe.Management.Endpoint": { + "effectiveLevel": "TRACE" + } + } +} +``` + +## Resettings Minimum Log Levels + +To revert back to the original minimum level, send another `POST` request to `/actuator/loggers/Steeltoe.Management`, but with the following request body: + +```json +{ + "configuredLevel": null +} +``` + +To verify the change was applied, send a `GET` request to `/actuator/loggers`, which returns the same JSON response as before overriding the minimum levels. + +## Configuration Changes + +Dynamic log levels in Steeltoe are implemented by wrapping an existing `ILoggerProvider` and intercepting calls to its `CreateLogger` method. +The returned `ILogger` instances are wrapped as well, so that the minimum level can be changed at runtime. + +When changes to `appsettings.json` are saved, existing loggers are updated with the new minimum levels, unless overridden. +A reset of an overridden logger reverts to the updated level from `appsettings.json`. + +> [!TIP] +> The Steeltoe dynamic logging provider can be combined with `BootstrapLoggerFactory` to upgrade loggers after startup. diff --git a/api/v4/management/mappings.md b/api/v4/management/mappings.md new file mode 100644 index 00000000..405dd2b0 --- /dev/null +++ b/api/v4/management/mappings.md @@ -0,0 +1,96 @@ +# Route Mappings + +You can use the Steeltoe Route Mappings actuator to retrieve the HTTP endpoints in your app that originate from ASP.NET Minimal APIs, API/MVC Controllers, Razor Pages and Blazor. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:Mappings:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `mappings` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | +| `IncludeActuators` | Whether to include actuator endpoints in the response. | `true` | + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/mappings`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddRouteMappingsActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.RouteMappings; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddRouteMappingsActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +## Sample Output + +This endpoint returns a list of route mappings and their parameters. + +The response will always be returned as JSON, like this: + +```json +{ + "contexts": { + "application": { + "mappings": { + "dispatcherServlets": { + "dispatcherServlet": [ + { + "handler": "SampleApp.Controllers.WeatherForecastController.Get (SampleApp)", + "predicate": "{GET [WeatherForecast], produces [text/plain || application/json || text/json]}", + "details": { + "handlerMethod": { + "className": "SampleApp.Controllers.WeatherForecastController", + "name": "Get", + "descriptor": "System.Collections.Generic.IEnumerable`1[SampleApp.WeatherForecast] Get()" + }, + "requestMappingConditions": { + "patterns": [ + "WeatherForecast" + ], + "methods": [ + "GET" + ], + "consumes": [], + "produces": [ + { + "mediaType": "text/plain", + "negated": false + }, + { + "mediaType": "application/json", + "negated": false + }, + { + "mediaType": "text/json", + "negated": false + } + ], + "headers": [], + "params": [] + } + } + } + ] + } + } + } + } +} +``` diff --git a/api/v4/management/prometheus.md b/api/v4/management/prometheus.md new file mode 100644 index 00000000..d44a8475 --- /dev/null +++ b/api/v4/management/prometheus.md @@ -0,0 +1,228 @@ +# Prometheus + +You can use the Prometheus endpoint to expose application metrics for collection by an external process. + +The Steeltoe Prometheus endpoint configures the [OpenTelemetry Prometheus Exporter](https://opentelemetry.io/docs/languages/net/exporters/#prometheus) to behave like a Steeltoe management endpoint. + +The Prometheus endpoint does not automatically instrument your application, but does make it easy to export metrics in the Prometheus metrics format, which can be used by tools like [Prometheus Server](https://prometheus.io/) and the [Metric Registrar for Tanzu Platform for Cloud Foundry](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform/tanzu-platform-for-cloud-foundry/10-0/tpcf/metric-registrar-index.html). + +The [Steeltoe Management samples](https://github.com/SteeltoeOSS/Samples/tree/main/Management/src/ActuatorWeb/README.md) can help you understand how to use this tool. + +## Add NuGet Reference + +To use the Prometheus endpoint, you need to add a reference to the `Steeltoe.Management.Prometheus` NuGet package. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:Prometheus:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `prometheus` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | + +> [!NOTE] +> The `AllowedVerbs` setting is inherited from Steeltoe's `EndpointOptions`, but is not intended to work for the Prometheus exporter, which is only registered to respond to `GET` requests. + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/prometheus`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddPrometheusActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Prometheus; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddPrometheusActuator(); +``` + +### Configuring the request pipeline for Prometheus + +In addition to the options described in [using endpoints](./using-endpoints.md), `AddPrometheusActuator` exposes an `Action?` that can be used to configure the branched request pipeline that is used in the underlying OpenTelemetry package. +This pipeline would need to be configured if, as an example, you are configuring an authorization policy. + +```csharp +builder.Services.AddPrometheusActuator(true, pipeline => pipeline.UseAuthorization()); +``` + +## Instrumentation + +In order for the Prometheus endpoint to return metrics, the application and relevant libraries need to be instrumented. +This page will cover the basics for elements that previous versions of Steeltoe configured automatically. +Please refer to the [OpenTelemetry documentation](https://opentelemetry.io/docs/languages/net/instrumentation/) for more detailed information. + +### ASP.NET Core + +To instrument ASP.NET Core for metrics, start by adding a reference to the `OpenTelemetry.Instrumentation.AspNetCore` NuGet package. + +Next, add the instrumentation to the `MeterProviderBuilder`: + +```csharp +using OpenTelemetry.Metrics; + +builder.Services.AddOpenTelemetry().WithMetrics(metrics => metrics.AddAspNetCoreInstrumentation()); +``` + +[Learn more about ASP.NET Core instrumentation for OpenTelemetry](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore) + +### HttpClient + +To instrument `HttpClient`s for metrics, start by adding a reference to the `OpenTelemetry.Instrumentation.Http` NuGet package. + +Next, add the instrumentation to the `MeterProviderBuilder`: + +```csharp +using OpenTelemetry.Metrics; + +builder.Services.AddOpenTelemetry().WithMetrics(metrics => metrics.AddHttpClientInstrumentation()); +``` + +[Learn more about HttpClient instrumentation for OpenTelemetry](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.Http) + +### .NET Runtime + +To instrument the .NET Runtime for metrics, start by adding a reference to the `OpenTelemetry.Instrumentation.Runtime` NuGet package. + +Next, add the instrumentation to the `MeterProviderBuilder`: + +```csharp +using OpenTelemetry.Metrics; + +builder.Services.AddOpenTelemetry().WithMetrics(metrics => metrics.AddRuntimeInstrumentation()); +``` + +[Learn more about Runtime Instrumentation for OpenTelemetry .NET](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.Runtime) + +### Prometheus Server + +You can set up Prometheus to scrape this endpoint by registering your application in the server's configuration. + +As an example, the following `prometheus.yml` file configures metric scraping for a Steeltoe-enabled application listening on port 8091 with the default actuator path: + +```yml +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. The default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + # scrape_timeout is set to the global default (10s). +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: 'steeltoe-prometheus' + metrics_path: '/actuator/prometheus' + scrape_interval: 5s + static_configs: + - targets: ['host.docker.internal:8091'] +``` + +Running the Prometheus server with this configuration lets you view metrics in the built-in UI. +You can then configure other visualization tools, such as [Grafana](https://grafana.com/docs/grafana/latest/features/datasources/prometheus/), to use Prometheus as a data source. + +The following example shows how to run Prometheus in Docker, referencing the configuration file from above: + +```shell +docker run -d --name=prometheus -p 9090:9090 -v ./prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus --config.file=/etc/prometheus/prometheus.yml +``` + +### Tanzu Platform for Cloud Foundry + +To emit custom metrics in Cloud Foundry, use [Metric Registrar](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform/tanzu-platform-for-cloud-foundry/10-0/tpcf/metric-registrar-index.html). + +> [!CAUTION] +> Authenticated endpoints are not supported with Metric Registrar. +> For this scenario, configure actuators to [use an alternate port](./using-endpoints.md#configure-global-settings) and use that private network port to offer the metrics. + +The examples below expect that actuators are mapped to an alternate port (8091 in this case). +The specific port that is used is not important to Steeltoe, it only matters that the binding and Steeltoe configurations match. + +#### Metrics Registrar Plugin + +Install the metrics-registrar plugin and use it to register your endpoint: + +```shell +cf install-plugin -r CF-Community "metric-registrar" +cf register-metrics-endpoint APP-NAME /actuator/prometheus --internal-port 8091 +``` + +> [!CAUTION] +> Due to an issue with the Cloud Foundry CLI plugin interface, some variations on this command do not work on Windows. +> If you are a Windows user, you should either use the metric registrar plugin from WSL or use another method. + +#### Create User Provided Service + +The result of using the metrics registrar plugin is a user-provided service, which can also be created and bound manually. + +```shell +cf create-user-provided-service APP-NAME -l secure-endpoint://:8091/actuator/prometheus +cf bind-service APP-NAME SERVICE-NAME +``` + +## Sample Output + +This endpoint returns information about the instrumented application metrics and their values. + +If no instrumentation has been included, the response will be very short, like this: + +```text +# EOF +``` + +With the addition of [.NET Runtime instrumentation](#net-runtime), the response will be like this: + +```text +# TYPE process_runtime_dotnet_gc_collections_count_total counter +# HELP process_runtime_dotnet_gc_collections_count_total Number of garbage collections that have occurred since process start. +process_runtime_dotnet_gc_collections_count_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0",generation="gen2"} 0 1740147372796 +process_runtime_dotnet_gc_collections_count_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0",generation="gen1"} 0 1740147372796 +process_runtime_dotnet_gc_collections_count_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0",generation="gen0"} 0 1740147372796 +# TYPE process_runtime_dotnet_gc_objects_size_bytes gauge +# UNIT process_runtime_dotnet_gc_objects_size_bytes bytes +# HELP process_runtime_dotnet_gc_objects_size_bytes Count of bytes currently in use by objects in the GC heap that haven't been collected yet. Fragmentation and other GC committed memory pools are excluded. +process_runtime_dotnet_gc_objects_size_bytes{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 8830400 1740147372797 +# TYPE process_runtime_dotnet_gc_allocations_size_bytes_total counter +# UNIT process_runtime_dotnet_gc_allocations_size_bytes_total bytes +# HELP process_runtime_dotnet_gc_allocations_size_bytes_total Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap. +process_runtime_dotnet_gc_allocations_size_bytes_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 8813792 1740147372797 +# TYPE process_runtime_dotnet_gc_duration_nanoseconds_total counter +# UNIT process_runtime_dotnet_gc_duration_nanoseconds_total nanoseconds +# HELP process_runtime_dotnet_gc_duration_nanoseconds_total The total amount of time paused in GC since the process start. +process_runtime_dotnet_gc_duration_nanoseconds_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 0 1740147372797 +# TYPE process_runtime_dotnet_jit_il_compiled_size_bytes_total counter +# UNIT process_runtime_dotnet_jit_il_compiled_size_bytes_total bytes +# HELP process_runtime_dotnet_jit_il_compiled_size_bytes_total Count of bytes of intermediate language that have been compiled since the process start. +process_runtime_dotnet_jit_il_compiled_size_bytes_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 272834 1740147372797 +# TYPE process_runtime_dotnet_jit_methods_compiled_count_total counter +# HELP process_runtime_dotnet_jit_methods_compiled_count_total The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings. +process_runtime_dotnet_jit_methods_compiled_count_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 4597 1740147372797 +# TYPE process_runtime_dotnet_jit_compilation_time_nanoseconds_total counter +# UNIT process_runtime_dotnet_jit_compilation_time_nanoseconds_total nanoseconds +# HELP process_runtime_dotnet_jit_compilation_time_nanoseconds_total The amount of time the JIT compiler has spent compiling methods since the process start. +process_runtime_dotnet_jit_compilation_time_nanoseconds_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 562297300 1740147372797 +# TYPE process_runtime_dotnet_monitor_lock_contention_count_total counter +# HELP process_runtime_dotnet_monitor_lock_contention_count_total The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter(). +process_runtime_dotnet_monitor_lock_contention_count_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 0 1740147372797 +# TYPE process_runtime_dotnet_thread_pool_threads_count gauge +# HELP process_runtime_dotnet_thread_pool_threads_count The number of thread pool threads that currently exist. +process_runtime_dotnet_thread_pool_threads_count{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 5 1740147372797 +# TYPE process_runtime_dotnet_thread_pool_completed_items_count_total counter +# HELP process_runtime_dotnet_thread_pool_completed_items_count_total The number of work items that have been processed by the thread pool since the process start. +process_runtime_dotnet_thread_pool_completed_items_count_total{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 62 1740147372797 +# TYPE process_runtime_dotnet_thread_pool_queue_length gauge +# HELP process_runtime_dotnet_thread_pool_queue_length The number of work items that are currently queued to be processed by the thread pool. +process_runtime_dotnet_thread_pool_queue_length{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 0 1740147372797 +# TYPE process_runtime_dotnet_timer_count gauge +# HELP process_runtime_dotnet_timer_count The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled. +process_runtime_dotnet_timer_count{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 2 1740147372797 +# TYPE process_runtime_dotnet_assemblies_count gauge +# HELP process_runtime_dotnet_assemblies_count The number of .NET assemblies that are currently loaded. +process_runtime_dotnet_assemblies_count{otel_scope_name="OpenTelemetry.Instrumentation.Runtime",otel_scope_version="1.11.0"} 149 1740147372797 +# EOF +``` diff --git a/api/v4/management/refresh.md b/api/v4/management/refresh.md new file mode 100644 index 00000000..d604ec76 --- /dev/null +++ b/api/v4/management/refresh.md @@ -0,0 +1,64 @@ +# Refresh + +You can use the Steeltoe Refresh endpoint to reload the application's configuration and return the new keys currently in use. +The endpoint reloads the configuration using `IConfigurationRoot.Reload()`. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:Refresh:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `refresh` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `POST` | +| `ReturnConfiguration` | Whether to return the configuration after refresh. | `true` | + +> [!NOTE] +> Despite being *possible* to configure this endpoint to respond to `GET` requests, +> this is discouraged because it is not a [Safe HTTP Method](https://developer.mozilla.org/en-US/docs/Glossary/Safe/HTTP). + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/refresh`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddRefreshActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Refresh; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddRefreshActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +## Sample Output + +This endpoint returns an array of keys obtained from `IConfiguration`. + +The response will always be returned as JSON, like this: + +```json +[ + "Management", + "Management:Endpoints", + "Management:Endpoints:Actuator", + "Management:Endpoints:Actuator:Exposure", + "Management:Endpoints:Actuator:Exposure:Include", + "Management:Endpoints:Actuator:Exposure:Include:0", +] +``` + +> [!NOTE] +> If `ReturnConfiguration` is set to `false`, an empty array is returned. diff --git a/api/v4/management/services.md b/api/v4/management/services.md new file mode 100644 index 00000000..6807f661 --- /dev/null +++ b/api/v4/management/services.md @@ -0,0 +1,84 @@ +# Services + +The Steeltoe Services endpoint returns the services registered in the application's dependency container. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:Services:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `beans` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | + +> [!NOTE] +> The `ID` of this endpoint defaults to `beans` for compatibility with the [beans actuator from Spring](https://docs.spring.io/spring-boot/api/rest/actuator/beans.html). + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/beans`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddServicesActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Services; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddServicesActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +## Sample Output + +This endpoint returns the contents of `IServiceCollection`. + +The response will always be returned as JSON, like this: + +```json +{ + "contexts": { + "application": { + "beans": { + "Microsoft.Extensions.Options.IOptions`1": { + "scope": "Singleton", + "type": "Microsoft.Extensions.Options.UnnamedOptionsManager`1[TOptions]", + "resource": "Microsoft.Extensions.Options, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "dependencies": [ + "Microsoft.Extensions.Options.IOptionsFactory`1[TOptions]" + ] + }, + "Microsoft.Extensions.Options.IOptionsSnapshot`1": { + "scope": "Scoped", + "type": "Microsoft.Extensions.Options.OptionsManager`1[TOptions]", + "resource": "Microsoft.Extensions.Options, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "dependencies": [ + "Microsoft.Extensions.Options.IOptionsFactory`1[TOptions]" + ] + }, + "Microsoft.Extensions.Options.IOptionsMonitor`1": { + "scope": "Singleton", + "type": "Microsoft.Extensions.Options.OptionsMonitor`1[TOptions]", + "resource": "Microsoft.Extensions.Options, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "dependencies": [ + "Microsoft.Extensions.Options.IOptionsFactory`1[TOptions]", + "System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Options.IOptionsChangeTokenSource`1[TOptions]]", + "Microsoft.Extensions.Options.IOptionsMonitorCache`1[TOptions]" + ] + } + } + } + } +} +``` diff --git a/api/v4/management/springbootadmin.md b/api/v4/management/springbootadmin.md new file mode 100644 index 00000000..9673347d --- /dev/null +++ b/api/v4/management/springbootadmin.md @@ -0,0 +1,137 @@ +# Spring Boot Admin Client + +The Steeltoe Spring Boot Admin client provides a way to integrate with [Spring Boot Admin Server](https://github.com/codecentric/spring-boot-admin), which enables monitoring and management of applications in any environment. + +## Add NuGet Reference + +Add a reference to the `Steeltoe.Management.Endpoint` NuGet package. + +## Add Spring Boot Admin Client + +The extension method `AddSpringBootAdminClient` adds an `IHostedService` and necessary components to register and un-register the application when it starts up and shuts down. It can be used in `Program.cs` as follows: + +```csharp +using Steeltoe.Management.Endpoint.SpringBootAdminClient; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddSpringBootAdminClient(); +``` + +## Configure Settings + +The following table describes the configuration settings that you can apply to the client. +Each key must be prefixed with `Spring:Boot:Admin:Client:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Url` | The URL of the Spring Boot Admin server. | | +| `ApplicationName` | The name of the Steeltoe app being registered. | computed | +| `BasePath` | Base path to find endpoints for integration. | computed | +| `ValidateCertificates` | Whether server certificates should be validated. | `true` | +| `ConnectionTimeoutMS` | Connection timeout (in milliseconds). | `100_000` | +| `Metadata` | Dictionary of metadata to use when registering. | | + +## Connecting to dockerized Spring Boot Admin Server + +For successful communication between your app and Spring Boot Admin Server running inside a docker container, +a few additional steps are needed: + +- Register your app using `host.docker.internal` + + Once your app has registered itself with Spring Boot Admin Server, the server tries to connect to your app + and send requests to its actuator endpoints. This fails when your app registers itself using `localhost`, + because the server runs in a docker container that has its own network. + Instead, you need to register using the special `host.docker.internal` address, which enables the server inside the container + to connect to your app outside the container. + +- Bind your app to a wildcard address + + By default, your app listens only on `localhost`, which is not accessible from the Spring Boot Admin Server running in a container. + To make the app accessible, bind it to a wildcard address, which allows it to listen on all available network interfaces. + This can be done by updating the `launchSettings.json` file. + +- Use HTTP instead of HTTPS + + The server doesn't trust the self-signed certificate used by your app, so you need to use HTTP instead of HTTPS. + This requires removing `app.UseHttpsRedirection()` from your `Program.cs` file. + +- Register additional actuator endpoints + + For the server to report the app as "UP", you need to add at least the hypermedia and health actuators in `Program.cs`. + +> [!TIP] +> You can use the [Steeltoe docker image for SBA](https://github.com/SteeltoeOSS/Samples/blob/main/CommonTasks.md#spring-boot-admin) for testing purposes. + +Putting it all together, your `appsettings.Development.json` file should look like this: + +```json +{ + "Spring": { + "Application": { + "Name": "ExampleSteeltoeApp" + }, + "Boot": { + "Admin": { + "Client": { + // This is the URL of the Spring Boot Admin Server. + "Url": "http://localhost:9099", + // This is what the Spring Boot Admin Server uses to connect to your app. + "BasePath": "http://host.docker.internal:5258" + } + } + } + } +} +``` + +With the following contents in `launchsettings.json`: + +```json +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + // Listen on all network interfaces by using a wildcard for the hostname. + "applicationUrl": "http://*:5258", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} +``` + +> [!NOTE] +> If you'd like your app to listen on a different port number, replace `5258` in both files above with the desired port. + +And the following code in `Program.cs`: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Health; +using Steeltoe.Management.Endpoint.Actuators.Hypermedia; +using Steeltoe.Management.Endpoint.SpringBootAdminClient; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddSpringBootAdminClient(); +builder.Services.AddHypermediaActuator(); +builder.Services.AddHealthActuator(); + +builder.Services.AddControllers(); + +var app = builder.Build(); + +// In order to avoid trust issues with self-signed certificates, do not automatically redirect to https. +//app.UseHttpsRedirection(); + +app.MapControllers(); + +app.Run(); +``` + +> [!TIP] +> To see all the Spring Boot Admin features in action, replace the `Add*Actuator()` calls in `Program.cs` with `AddAllActuators()` and [expose all endpoints](./using-endpoints.md#exposing-endpoints). diff --git a/api/v4/management/tasks.md b/api/v4/management/tasks.md new file mode 100644 index 00000000..080088e4 --- /dev/null +++ b/api/v4/management/tasks.md @@ -0,0 +1,121 @@ +# Management Tasks + +Steeltoe management tasks provide a way to run administrative tasks for ASP.NET Core applications by supporting an alternate entry point, letting you take advantage of the same configuration, logging, and dependency injection as the running version of your application. The original use case for this feature is managing database migrations with a bound database service on Cloud Foundry, but the framework is extensible for you to create your own tasks. + +## Add NuGet Reference + +To use application tasks, add a reference to the `Steeltoe.Management.Tasks` NuGet package. + +## Registering Tasks + +For simple cases, a code block containing the task logic can be specified inline: + +```csharp +using Steeltoe.Management.Tasks; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddTask("ExampleTaskName", async (serviceProvider, cancellationToken) => +{ + var loggerFactory = serviceProvider.GetRequiredService(); + var logger = loggerFactory.CreateLogger("ExampleTask"); + + await Task.Yield(); + cancellationToken.ThrowIfCancellationRequested(); + logger.LogInformation("Running example task."); +}); +``` + +When the task logic is non-trivial, a class implementing the `IApplicationTask` interface can be defined: + +```csharp +using Steeltoe.Common; +using Steeltoe.Management.Tasks; + +public class ExampleTask(ILogger logger) : IApplicationTask +{ + public async Task RunAsync(CancellationToken cancellationToken) + { + await Task.Yield(); + cancellationToken.ThrowIfCancellationRequested(); + logger.LogInformation("Running example task."); + } +} +``` + +> [!TIP] +> Steeltoe includes the `MigrateDbContextTask` task, which runs database migrations with Entity Framework Core. +> It requires a reference to the `Steeltoe.Connectors.EntityFrameworkCore` NuGet package. + +To register the `ExampleTask` class defined above as a scoped service, use the `AddTask<>` extension method: + +```csharp +using Steeltoe.Management.Tasks; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddTask("ExampleTaskName"); +``` + +> [!NOTE] +> To register as a singleton or transient service, use the overload that additionally takes a `ServiceLifetime` parameter. + +In case task instantiation requires additional logic, a task instance can be specified as well: + +```csharp +using Steeltoe.Management.Tasks; + +var builder = WebApplication.CreateBuilder(args); + +var exampleTask = new ExampleTask(/* ... */); +builder.Services.AddTask("ExampleTaskName", exampleTask); +``` + +Or an inline factory method can be used to instantiate the task: + +```csharp +using Steeltoe.Management.Tasks; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddTask("ExampleTaskName", (serviceProvider, taskName) => +{ + var loggerFactory = serviceProvider.GetRequiredService(); + var logger = loggerFactory.CreateLogger(); + return new ExampleTask(logger); // could pass the task name as a parameter +}); +``` + +## Executing a Task + +Once your task has been defined and added to the service container, the last step is to enable a means of executing the task. +In your `Program.cs` file, replace the call to `app.Run()` with `await app.RunWithTasksAsync()`: + +```csharp +using Steeltoe.Management.Tasks; + +var app = builder.Build(); + +// ... + +await app.RunWithTasksAsync(CancellationToken.None); +``` + +## Specify Task to Execute + +Once all the setup steps have been completed, any invocation of your application with a configuration value for the `RunTask` key +runs that task (and shuts down) instead of starting the web application: + +``` +dotnet run -- RunTask=ExampleTaskName +``` + +As a matter of best practice, we encourage you to provide the `RunTask` value only via a command-line parameter. +However, due to the way .NET configuration works, it does not matter which configuration provider is used to provide the task name. +Invoking the command on Cloud Foundry looks similar to this: + +``` +cf run-task YourAppName "dotnet run -- RunTask=ExampleTaskName" --name ExampleTaskName +``` + +> [!TIP] +> The command line configuration provider is added by default when using `WebApplication.CreateBuilder(args)`. +> If the task does not fire when running from the command line with the `RunTask=` parameter, +> verify that the configuration provider has been added for your application. diff --git a/api/v4/management/threaddump.md b/api/v4/management/threaddump.md new file mode 100644 index 00000000..742ff093 --- /dev/null +++ b/api/v4/management/threaddump.md @@ -0,0 +1,83 @@ +# Thread Dump + +The Steeltoe Thread Dump endpoint can be used to generate a snapshot of information about all the threads in your application. That snapshot includes several bits of information for each thread, including the thread's state, a stack trace, any monitor locks held by the thread, any monitor locks the thread is waiting on, and other details. + +## Configure Settings + +The following table describes the configuration settings that you can apply to the endpoint. +Each key must be prefixed with `Management:Endpoints:ThreadDump:`. + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | `threaddump` | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | `GET` | + +> [!TIP] +> In version 4, the configuration key prefix for this endpoint changed from `Management:Endpoints:Dump:` to `Management:Endpoints:ThreadDump:` + +## Enable HTTP Access + +The URL path to the endpoint is computed by combining the global `Management:Endpoints:Path` setting together with the `Path` setting described in the preceding section. +The default path is `/actuator/threaddump`. + +See the [Exposing Endpoints](./using-endpoints.md#exposing-endpoints) and [HTTP Access](./using-endpoints.md#http-access) sections for the overall steps required to enable HTTP access to endpoints in an ASP.NET Core application. + +To add the actuator to the service container and map its route, use the `AddThreadDumpActuator` extension method. + +Add the following code to `Program.cs` to use the actuator endpoint: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.ThreadDump; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddThreadDumpActuator(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +## Sample Output + +This endpoint returns a list of threads with their state and stack trace. + +The response will always be returned as JSON, like this: + +```json +{ + "threads": [ + { + "blockedCount": 0, + "blockedTime": -1, + "lockOwnerId": -1, + "stackTrace": [ + { + "className": "[NativeClasses]", + "methodName": "[NativeMethods]", + "nativeMethod": true + }, + { + "className": "System!System.Threading.WaitHandle", + "methodName": "WaitOneNoCheck(int32)", + "nativeMethod": false + }, + { + "className": "System!System.Threading.PortableThreadPool+GateThread", + "methodName": "GateThreadStart()", + "nativeMethod": false + } + ], + "threadId": 11848, + "threadName": "Thread-11848", + "threadState": "WAITING", + "waitedCount": 0, + "waitedTime": -1, + "inNative": true, + "suspended": false + } + ] +} +``` diff --git a/api/v4/management/using-endpoints.md b/api/v4/management/using-endpoints.md new file mode 100644 index 00000000..91ff220b --- /dev/null +++ b/api/v4/management/using-endpoints.md @@ -0,0 +1,251 @@ +# Using Endpoints + +Steeltoe provides a basic set of HTTP endpoints (also known as actuators), which are implemented using ASP.NET Core middleware. + +## Reference Materials + +In this section, it is helpful to understand the following: + +* How the [.NET Configuration System](https://learn.microsoft.com/aspnet/core/fundamentals/configuration) works. +* How the [ASP.NET Core Startup](https://learn.microsoft.com/aspnet/core/fundamentals/startup) is used to register services and middleware. + +## Endpoint Listing + +The following table describes the available Steeltoe management endpoints that can be used in an application: + +| ID|Description | +| --- | --- | +| [cloudfoundry](./cloud-foundry.md) | Enables the management endpoint integration with Cloud Foundry. | +| [dbmigrations](./dbmigrations.md) | Provides the ability to see current and pending database migrations for an application data source. | +| [env](./env.md) | Reports the keys and values from the application's configuration. | +| [health](./health.md) | Customizable endpoint that gathers application health information. | +| [heapdump](./heapdump.md) | Generates and downloads a mini-dump of the application (Windows and Linux only). | +| [httpexchanges](./httpexchanges.md) | Gathers recently processed HTTP requests. | +| [hypermedia](./hypermedia.md) | Lists the active management endpoints and their links. | +| [info](./info.md) | Customizable endpoint that gathers arbitrary application information (such as app version). | +| [loggers](./loggers.md) | Gathers existing logger categories and allows changing their minimum levels at runtime. | +| [mappings](./mappings.md) | Reports the configured ASP.NET routes and route templates. | +| [prometheus](./prometheus.md) | Exposes metrics collected via built-in instrumentation of various aspects of the application in the Prometheus format. | +| [refresh](./refresh.md) | Triggers a reload of the application configuration. | +| [services](./services.md) | Lists the contents of the .NET dependency injection service container. | +| [threaddump](./threaddump.md) | Generates and reports a snapshot of the application's threads (Windows only). | + +Each endpoint has an associated ID. When you want to expose an endpoint over HTTP, its ID is used in the mapped URL that exposes the endpoint. For example, the `health` endpoint is mapped to `/actuator/health`. + +## Add NuGet Reference + +To use the management endpoints, you need to add a reference to the `Steeltoe.Management.Endpoints` NuGet package. + +## Configure Global Settings + +Endpoints can be configured using the [.NET Configuration System](https://learn.microsoft.com/aspnet/core/fundamentals/configuration). You can globally configure settings that apply to all endpoints, as well as configure settings that are specific to a particular endpoint. + +All management endpoint settings should be placed under the configuration key prefix `Management:Endpoints`. Any settings found under this prefix apply to all endpoints globally. + +Settings that you want to apply to specific endpoints should be placed under the configuration key prefix `Management:Endpoints:`, where `` is the ID of the endpoint (for example, `Management:Endpoints:Health`). Any settings you apply to a specific endpoint override the configuration settings applied globally. + +The following table describes the configuration settings that you can apply globally: + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether to enable management endpoints. | `true` | +| `Path` | The HTTP route prefix applied to all endpoints. | `/actuator` | +| `Port` | Expose management endpoints on an alternate HTTP port. [^1] | | +| `SslEnabled` | Whether `Port` applies to HTTP or HTTPS requests. [^1] | `false` | +| `UseStatusCodeFromResponse` | Reflect the actuator outcome in the HTTP response status code. | `true` | +| `SerializerOptions` | Customize JSON serialization options. | use camelCase properties | +| `CustomJsonConverters` | Additional [`JsonConverter`](https://learn.microsoft.com/dotnet/standard/serialization/system-text-json/converters-how-to)s to use (see below). | | + +[^1]: Using an alternate port does not apply to `/cloudfoundryapplication` endpoints. + +> [!NOTE] +> When running an application in IIS or with the HWC buildpack, response body content is automatically filtered out when the HTTP response code is 503. Some actuator responses intentionally return a code of 503 in failure scenarios. Setting `UseStatusCodeFromResponse` to `false` will return status code 200 instead. This switch does not affect the status code of responses outside of Steeltoe. + +## Configure Endpoint-specific Settings + +The following table describes the configuration settings that are common to all endpoint-specific settings: + +| Key | Description | Default | +| --- | --- | --- | +| `Enabled` | Whether the endpoint is enabled. | `true` | +| `ID` | The unique ID of the endpoint. | | +| `Path` | The relative path at which the endpoint is exposed. | same as `ID` | +| `RequiredPermissions` | Permissions required to access the endpoint, when running on Cloud Foundry. | `Restricted` | +| `AllowedVerbs` | An array of HTTP verbs the endpoint is exposed at. | | + +### Custom JSON Serialization Options + +The `JsonSerializerOptions` used to serialize actuator responses are configurable, and custom `JsonConverter`s can be used by adding the [assembly-qualified type](https://learn.microsoft.com/dotnet/api/system.type.assemblyqualifiedname"). + +For example, to pretty-print all JSON and serialize `DateTime` values as epoch times: + +```json +{ + "Management": { + "Endpoints": { + "SerializerOptions": { + "WriteIndented": true + }, + "CustomJsonConverters": [ + "Steeltoe.Management.Endpoint.Actuators.Info.EpochSecondsDateTimeConverter" + ] + } + } +} +``` + +## Exposing Endpoints + +Since endpoints may contain sensitive information, only health and info are exposed by default. To change which endpoints are exposed, use the `Include` and `Exclude` properties. + +| Property | Default | +| --- | --- | +| `Exposure:Include` | [`info`, `health`] | +| `Exposure:Exclude` | | + +Each key in the table above must be prefixed with `Management:Endpoints:Actuator`. Use the actuator ID to specify the endpoint. +To expose all endpoints, `*` can be used. For example, to expose everything except `env` and `refresh`, use the following: + +```json +"Management": { + "Endpoints": { + "Actuator":{ + "Exposure": { + "Include": [ "*" ], + "Exclude": [ "env", "refresh"] + } + } + } +} +``` + +> [!NOTE] +> When running on Cloud Foundry, exposure settings *only* have an effect on requests starting with `/actuator`. +> They are ignored for requests starting with `/cloudfoundryapplication`, where access control is [handled differently](./cloud-foundry.md#security). +> Individual endpoints can be turned off by setting `Enabled` to `false`, which applies to both URLs. + +## HTTP Access + +To expose any of the management endpoints over HTTP in an ASP.NET Core application: + +1. Add a NuGet package reference to `Steeltoe.Management.Endpoint`. +1. Configure endpoint settings, as needed (typically in `appsettings.json`). +1. Add the actuator endpoint(s) to the service container. +1. Optional: Add any additional health/info contributors to the service container. +1. Optional: Customize the CORS policy. +1. Optional: Secure endpoints. +1. Optional: Override the middleware pipeline setup. + +> [!CAUTION] +> By default, actuator endpoints are exposed on the same host(s) and port(s) as the application (which can be configured as described [here](https://learn.microsoft.com/aspnet/core/fundamentals/servers/kestrel/endpoints) and [here](https://andrewlock.net/8-ways-to-set-the-urls-for-an-aspnetcore-app/)). +> Use the `Port` and `SslEnabled` settings described above to isolate management endpoints from regular application endpoints. + +The example below adds all actuators: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.All; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddAllActuators(); +``` + +> [!TIP] +> It's recommended to use `AddAllActuators()` instead of adding individual actuators, +> which enables individually turning them on/off at runtime via configuration. + +Alternatively, individual actuators can be added: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Hypermedia; +using Steeltoe.Management.Endpoint.Actuators.Loggers; +using Steeltoe.Management.Endpoint.Actuators.Refresh; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHypermediaActuator().AddLoggersActuator().AddRefreshActuator(); +``` + +> [!NOTE] +> `AddAllActuators()` and `AddLoggingActuator()` automatically configure [Dynamic Console Logging](../logging/dynamic-console-logging.md). To use [Dynamic Serilog Logging](../logging/dynamic-serilog-logging.md), be sure to do so *before* adding actuators. For example: +> +> ```csharp +> using Steeltoe.Logging.DynamicSerilog; +> using Steeltoe.Management.Endpoint.Actuators.All; +> +> var builder = WebApplication.CreateBuilder(args); +> builder.Logging.AddDynamicSerilog(); +> builder.Services.AddAllActuators(); +> ``` + +## Adding additional contributors + +The `health` and `info` endpoints can be extended with custom contributors. For example: + +```csharp +using Steeltoe.Management.Endpoint.Actuators.Health; +using Steeltoe.Management.Endpoint.Actuators.Info; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHealthActuator(); +builder.Services.AddHealthContributor(); +builder.Services.AddInfoActuator(); +builder.Services.AddInfoContributor() +``` + +## Customizing the CORS policy + +By default, any origin is allowed to access the actuator endpoints. To customize the CORS policy, use the `ConfigureActuatorsCorsPolicy` extension method: + +```csharp +using Steeltoe.Management.Endpoint; +using Steeltoe.Management.Endpoint.Actuators.All; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddAllActuators(); +builder.Services.ConfigureActuatorsCorsPolicy(policy => policy.WithOrigins("http://www.example.com")); +``` + +## Securing Endpoints + +Endpoints can be customized with `IEndpointConventionBuilder`. This allows calling [`RequireAuthorization()`](https://learn.microsoft.com/aspnet/core/security/authorization/policies?#apply-policies-to-endpoints) to configure the Authorization middleware: + +```csharp +using Steeltoe.Management.Endpoint; +using Steeltoe.Management.Endpoint.Actuators.All; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddAllActuators(); +builder.Services.ConfigureActuatorEndpoints(endpoints => endpoints.RequireAuthorization()); +``` + +When `RequireAuthorization()` is called without arguments, the default profile is used. Other overloads allow passing a profile or a profile name. + +## Overriding the middleware pipeline setup + +All `Add*Actuator` methods provide an overload that takes a boolean `configureMiddleware`, which enables to skip adding middleware to the ASP.NET Core pipeline. +While this provides full control over the pipeline contents and order, it requires manual addition of the appropriate middleware for actuators to work correctly. + +```csharp +using Steeltoe.Management.Endpoint; +using Steeltoe.Management.Endpoint.Actuators.All; +using Steeltoe.Management.Endpoint.Actuators.CloudFoundry; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddAllActuators(configureMiddleware: false); +await using WebApplication app = builder.Build(); + +app.UseManagementPort(); // required to block actuator requests on the app port +app.UseRouting(); +app.UseActuatorsCorsPolicy(); // required to activate the CORS policy for actuators +app.UseCloudFoundrySecurity(); // required by AddCloudFoundryActuator() +app.UseActuatorEndpoints(); // maps the actuator endpoints + +await app.StartAsync(); +``` + +While the order above must not be changed (and it's not recommended to leave out entries), additional middleware can be inserted as appropriate. + +### Conventional routing + +Applications that use the legacy [conventional routing](https://learn.microsoft.com/aspnet/core/mvc/controllers/routing#conventional-routing) +are still supported by the `Add*Actuator` methods. +However, they won't show up in the [route mappings actuator](./mappings.md) anymore. diff --git a/api/v4/security/certificate.md b/api/v4/security/certificate.md new file mode 100644 index 00000000..d563d67a --- /dev/null +++ b/api/v4/security/certificate.md @@ -0,0 +1,176 @@ +# Resource Protection using Mutual TLS in ASP.NET Core + +Certificate Authentication, also known as Mutual TLS, is a way for a client and server to validate each other's identity. This method is commonly used to secure service-to-service communications. + +This library is a supplement to [ASP.NET Core Certificate Authentication](https://learn.microsoft.com/aspnet/core/security/authentication/certauth), adding functionality that helps you use [Cloud Foundry Instance Identity certificates](https://docs.cloudfoundry.org/devguide/deploy-apps/instance-identity.html) and authorization policies based on certificate data. +Additionally, resources are included for automatically generating certificates for local development that resemble what is found on the platform. + +## Usage + +In order to use this provider, the following steps are required: + +1. Add NuGet package reference +1. Add identity certificates to the configuration +1. Add and use the security provider in the application +1. Secure your endpoints +1. Attach certificate to requests to secured endpoints + +### Add NuGet Reference + +> [!NOTE] +> This step is required on all applications that are sending or receiving certificate-authorized requests. + +To use Certificate Authorization, you need to add a reference to the `Steeltoe.Security.Authorization.Certificate` NuGet package. + +### Add Identity Certificates to Configuration + +> [!NOTE] +> This step is required on all applications that are sending or receiving certificate-authorized requests. + +In a Cloud Foundry environment, instance identity certificates are automatically provisioned (and rotated on a regular basis) for each application instance. +Steeltoe provides the extension method `AddAppInstanceIdentityCertificate` to find the location of the certificate files from the environment variables `CF_INSTANCE_CERT` and `CF_INSTANCE_KEY`. +When running outside of Cloud Foundry, this method will automatically generate similar certificates. +Use the optional parameters to coordinate `orgId` and/or `spaceId` between your applications to facilitate communication when running outside of Cloud Foundry. + +This code adds the certificate paths to the configuration for use later (and generates the instance identity certificate when running outside Cloud Foundry): + +```csharp +using Steeltoe.Common.Certificates; + +const string orgId = "a8fef16f-94c0-49e3-aa0b-ced7c3da6229"; +const string spaceId = "122b942a-d7b9-4839-b26e-836654b9785f"; + +var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddAppInstanceIdentityCertificate(new Guid(orgId), new Guid(spaceId)); +``` + +When running locally, the code shown above will create a chain of self-signed certificates and the application instance identity certificate will have a subject containing an OrgId of `a8fef16f-94c0-49e3-aa0b-ced7c3da6229` and a SpaceId of `122b942a-d7b9-4839-b26e-836654b9785f`. +A root certificate and intermediate certificate are created on disk one level above the current project in a directory named `GeneratedCertificates`. +The root and intermediate certificates will automatically be shared between applications housed within the same solution, so that the applications will be able to trust each other. + +### Add and use Certificate Authentication + +> [!NOTE] +> This section is only required on applications that are receiving certificate-authorized requests. + +Several steps need to happen before certificate authorization policies can be used to secure resources: + +1. Configuration values need to be bound into named `CertificateOptions` +1. Certificate files need to be monitored for changes (to stay up to date when certificates are rotated) +1. Certificate forwarding needs to be configured (so that ASP.NET reads the certificate out of an HTTP Header) +1. Authentication services need to be added +1. Authorization services and policies need to be added +1. Middleware needs to be activated + +Fortunately, all of the requirements can be satisfied with a handful of extension methods: + +```csharp +using Steeltoe.Security.Authorization.Certificate; + +// Register Microsoft's Certificate Authentication library +builder.Services + .AddAuthentication() + .AddCertificate(); + +// Register Microsoft authorization services +builder.Services.AddAuthorizationBuilder() + // Register Steeltoe components and policies requiring org and/or space to match between client and server certificates + .AddOrgAndSpacePolicies(); +``` + +> [!TIP] +> Steeltoe configures the certificate forwarding middleware to look for a certificate in the `X-Client-Cert` HTTP header. +> To change the HTTP header name used for authorization, include it when registering the policy. For example: `.AddOrgAndSpacePolicies("X-Custom-Certificate-Header")`. + +Steeltoe exposes some of the policy-related components directly if more customized scenarios are required: + +```csharp +// AuthorizationPolicyBuilder setup +builder.Services.AddAuthorizationBuilder() + .AddOrgAndSpacePolicies() + .AddDefaultPolicy("sameOrgAndSpace", policy => policy.RequireSameOrg().RequireSameSpace()); + +// Or the equivalent using different syntax +builder.Services.AddAuthorizationBuilder() + .AddOrgAndSpacePolicies() + .AddPolicy("sameOrgAndSpace", policy => policy.AddRequirements(new SameOrgRequirement(), new SameSpaceRequirement())); +``` + +To activate certificate-based authorization in the request pipeline, use the `UseCertificateAuthorization` extension method on `IApplicationBuilder`: + +```csharp +var app = builder.Build(); + +// Steeltoe: Use certificate and header forwarding along with ASP.NET Core Authentication and Authorization middleware +app.UseCertificateAuthorization(); +``` + +### Securing Endpoints + +> [!NOTE] +> This step is only required on applications that are receiving certificate-authorized requests. + +As implied by the name of the extension method `AddOrgAndSpacePolicies` from the previous section on this page, Steeltoe provides policies for validating that a request came from an application in the same org and/or the same space. You can secure endpoints by using the standard ASP.NET Core `Authorize` attribute with these security policies. + +> [!TIP] +> If needed, see the Microsoft documentation on [authorization in ASP.NET Core](https://learn.microsoft.com/aspnet/core/security/authorization/introduction) for a better understanding of how to use these attributes. + +The following example shows a controller using the security attributes with the included policies: + +```csharp +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Steeltoe.Security.Authorization.Certificate; + +[Route("api")] +public class HomeController : ControllerBase +{ + [Authorize(CertificateAuthorizationPolicies.SameOrg)] + [HttpGet("[action]")] + public string SameOrgCheck() + { + return "Certificate is valid and both client and server are in the same org"; + } + + [Authorize(CertificateAuthorizationPolicies.SameSpace)] + [HttpGet("[action]")] + public string SameSpaceCheck() + { + return "Certificate is valid and both client and server are in the same space"; + } + + [Authorize(CertificateAuthorizationPolicies.SameOrg)] + [Authorize(CertificateAuthorizationPolicies.SameSpace)] + [HttpGet("[action]")] + public string SameOrgAndSpaceCheck() + { + return "Certificate is valid and both client and server are in the same org and space"; + } +} +``` + +In the preceding example, when an incoming request is made to the `SameOrgCheck` endpoint, the request is evaluated for the presence of a certificate. If a certificate is not present, the user is denied access. If a certificate is present, its subject is evaluated for the presence of an `org` value, which is then compared with the `org` value in the certificate found on disk where the service is deployed. If the values do not match, the user is denied access. The same process is applied for `SameSpaceCheck`, with the only difference being a check for the `space` value instead of the `org` value. + +### Communicating with Secured Services + +In order to use app instance identity certificates in a client application, services need to be configured, but nothing needs to be activated in the ASP.NET Core request pipeline. + +#### IHttpClientFactory integration + +> [!NOTE] +> This step is only required on applications that are sending certificate-authorized requests. + +For applications that need to send identity certificates in outgoing requests, Steeltoe provides a smooth experience through an extension method on `IHttpClientBuilder` named `AddAppInstanceIdentityCertificate`. +This method invokes code that handles loading certificates from paths defined in the application's configuration, monitors those file paths and their content for changes, and places the certificate in an HTTP header named `X-Client-Cert` on all outbound requests. + +> [!TIP] +> If needed, see the Microsoft documentation on [IHttpClientFactory documentation](https://learn.microsoft.com/aspnet/core/fundamentals/http-requests) for details. + +```csharp +using Steeltoe.Security.Authorization.Certificate; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHttpClient().AddAppInstanceIdentityCertificate(); +``` + +This method has an overload that changes the name of the HTTP header used to pass the certificate. For example: `.AddAppInstanceIdentityCertificate("X-Custom-Certificate-Header")`. diff --git a/api/v4/security/index.md b/api/v4/security/index.md new file mode 100644 index 00000000..32ba3f60 --- /dev/null +++ b/api/v4/security/index.md @@ -0,0 +1,13 @@ +# Cloud Security + +Steeltoe provides several libraries that simplify using Cloud Foundry-based security services (such as [UAA Server](https://github.com/cloudfoundry/uaa), [Single Sign-On for VMware Tanzu](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/single-sign-on-for-tanzu/1-16/sso-tanzu/index.html) and [instance identity certificates](https://docs.cloudfoundry.org/devguide/deploy-apps/instance-identity.html)) for authentication and authorization. + +Choose from the following options when using Cloud Foundry security integration: + +* [Single Sign-on with OpenID Connect](sso-open-id.md) +* [Resource protection with JWT Bearer tokens](jwt-bearer.md) +* [Resource protection using Mutual TLS (Certificate Authorization)](certificate.md) + +In addition to authentication and authorization providers, Steeltoe security offers: + +* [A security provider for using Redis on Cloud Foundry with ASP.NET Core Data Protection Key Ring storage](redis-key-storage-provider.md) diff --git a/api/v4/security/jwt-bearer.md b/api/v4/security/jwt-bearer.md new file mode 100644 index 00000000..3b2a512d --- /dev/null +++ b/api/v4/security/jwt-bearer.md @@ -0,0 +1,219 @@ +# Resource Protection using JWT in ASP.NET Core + +This library is a supplement to ASP.NET Core Security, adding functionality that helps you use Cloud Foundry Security services such as [Single Sign-On for VMware Tanzu](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/single-sign-on-for-tanzu/1-16/sso-tanzu/index.html) or a [UAA Server](https://github.com/cloudfoundry/uaa) for authentication and authorization using JSON Web Tokens (JWT) in ASP.NET Core web applications. + +The [Steeltoe Security samples](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/AuthWeb/README.md) can help you understand how to use this tool. + +General guidance on JWT is beyond the scope of this document and can be found in many other sources (for example, see [Wikipedia](https://en.wikipedia.org/wiki/JSON_Web_Token) or [JWT IO](https://jwt.io/)). + +For the documentation of the underlying Microsoft Jwt Bearer Authentication library, visit the [official documentation](https://learn.microsoft.com/aspnet/core/security/authentication/configure-jwt-bearer-authentication). + +## Usage + +Steps involved in using this library: + +1. Add NuGet references. +1. Configure settings for the security provider. +1. Add and use the security provider in the application. +1. Secure your endpoints. +1. Create an instance of a Cloud Foundry Single Sign-On service and bind it to your application. + +### Add NuGet References + +To use the provider, you need to add a reference to the `Steeltoe.Security.Authentication.JwtBearer` NuGet package. + +Also add a reference to `Steeltoe.Configuration.CloudFoundry`, so that Cloud Foundry service bindings can be read by Steeltoe. + +### Configure Settings + +Since Steeltoe's JWT Bearer library configures Microsoft's JWT Bearer implementation, all available settings can be found in [`Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.authentication.jwtbearer.jwtbeareroptions). + +`JwtBearerOptions` is bound to configuration values found under `Authentication:Schemes:Bearer`. The following example `appsettings.json` shows how to declare the audience for which tokens should be considered valid (such as when a token is issued to a specific web application and then passed to backend services to perform actions on behalf of a user): + +```json +{ + "Authentication": { + "Schemes": { + "Bearer": { + "ValidAudience": "sampleapi" + } + } + } +} +``` + +#### Cloud Foundry Service Bindings + +The Steeltoe package `Steeltoe.Configuration.CloudFoundry` reads Single Sign-On credentials from Cloud Foundry service bindings (`VCAP_SERVICES`) and re-maps them for Microsoft's JWT Bearer library to read. Add the configuration provider to your application with this code: + +```csharp +using Steeltoe.Configuration.CloudFoundry; +using Steeltoe.Configuration.CloudFoundry.ServiceBindings; + +var builder = WebApplication.CreateBuilder(args); + +// Steeltoe: Add Cloud Foundry application and service info to configuration. +builder.AddCloudFoundryConfiguration(); +builder.Configuration.AddCloudFoundryServiceBindings(); +``` + +#### Local UAA + +A UAA server (such as [UAA Server for Steeltoe samples](https://github.com/SteeltoeOSS/Dockerfiles/tree/main/uaa-server)), can be used for local development of applications that will be deployed to Cloud Foundry. Configuration of UAA itself is beyond the scope of this documentation, but configuring your `appsettings.Development.json` to work with a local UAA server is possible with the addition of settings like these: + +```json +{ + "Authentication": { + "Schemes": { + "Bearer": { + "Authority": "http://localhost:8080/uaa", + "ClientId": "steeltoesamplesserver", + "ClientSecret": "server_secret", + "MetadataAddress": "http://localhost:8080/.well-known/openid-configuration", + "RequireHttpsMetadata": false + } + } + } +} +``` + +> [!IMPORTANT] +> If you wish to use the Steeltoe UAA server without modification, some application configuration options will be limited. +> The Steeltoe UAA Server configuration can be found in [uaa.yml](https://github.com/SteeltoeOSS/Dockerfiles/blob/main/uaa-server/uaa.yml#L111). + +### Add and use JWT Bearer Authentication + +Since the majority of the JWT Bearer functionality is provided by Microsoft's libraries, the only difference when using Steeltoe will be the addition of calling `ConfigureJwtBearerForCloudFoundry` on the `AuthenticationBuilder`, as shown in the following example: + +```csharp +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Steeltoe.Security.Authentication.JwtBearer; + +// Add Microsoft Authentication services +builder.Services + .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer() + // Steeltoe: configure JWT to work with UAA/Cloud Foundry + .ConfigureJwtBearerForCloudFoundry(); + +// Register Microsoft Authorization services +builder.Services.AddAuthorizationBuilder() + // Create a named authorization policy that requires the user to have a scope with the same value + .AddPolicy("sampleapi.read", policy => policy.RequireClaim("scope", "sampleapi.read")); +``` + +Activate authentication and authorization services _after_ routing services, but _before_ controller route registrations, with the following code: + +```csharp +var app = builder.Build(); + +app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedHost | ForwardedHeaders.XForwardedProto }); + +app.UseRouting(); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.MapDefaultControllerRoute(); + +app.Run(); +``` + +> [!TIP] +> In the sample code above, `app.UseForwardedHeaders` is used so that any links generated within the application will be compatible with reverse-proxy scenarios, such as when running in Cloud Foundry. + +### Securing Endpoints + +Once the services and middleware have been configured, you can secure endpoints with the standard ASP.NET Core `Authorize` attribute, as follows: + +```csharp +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +[Route("api/[controller]")] +[ApiController] +public class SampleController : ControllerBase +{ + + [HttpGet] + [Authorize(Policy = "sampleapi.read")] + public string Get() + { + return "You have permission to read from the sample API."; + } +} +``` + +In the preceding example, if an incoming GET request is made to the `/api/sample` endpoint and the request does not contain a valid JWT bearer token for a user with a `scope` claim equal to `sampleapi.read`, the request is rejected. + +Review the [Steeltoe Security samples](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/AuthWeb/README.md) for a demonstration of using a user's access token to interact with downstream APIs, focusing on these locations: + +- [Configure ASP.NET Core to save the user's token](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/AuthWeb/appsettings.json#L15) +- [Get the user's token](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/AuthWeb/Controllers/HomeController.cs#L60) +- [Include the token in a downstream request](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/AuthWeb/ApiClients/JwtAuthorizationApiClient.cs#L24) + +### Single Sign-On for VMware Tanzu + +When using Single Sign-On for VMware Tanzu, you will need to identify the service plan to be used before creating a service instance of that plan. +If you do not have an existing service plan, a platform operator may need to create a new plan for you. +The operator should refer to the [Single Sign-On for Tanzu operator guide](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/single-sign-on-for-tanzu/1-16/sso-tanzu/operator-index.html) for information on how to configure plans for developer use. + +Once you have identified the service plan that will be used, create a service instance: + +```shell +cf create-service p-identity SERVICE_PLAN_NAME MY_SERVICE_INSTANCE +``` + +#### Bind and configure with app manifest + +Using a manifest file when you deploy to Cloud Foundry is recommended, and can save some work with the SSO configuration. Review the Single Sign-On documentation for [configuring an app manifest](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/single-sign-on-for-tanzu/1-16/sso-tanzu/config-apps.html#configure-app-manifest). + +Consider this example manifest that names the application, buildpack and configures several properties for the SSO binding: + +```yml +applications: +- name: steeltoesamplesserver + buildpacks: + - dotnet_core_buildpack + env: + GRANT_TYPE: client_credentials + SSO_AUTHORITIES: uaa.resource, sampleapi.read + SSO_RESOURCES: sampleapi.read + SSO_SHOW_ON_HOME_PAGE: "false" + services: + - sampleSSOService +``` + +#### Bind and configure manually + +Alternatively, you can manually bind the instance, restage the app with the Cloud Foundry CLI and later configure the SSO binding yourself with the web interface: + +```shell +# Bind service to your app +cf bind-service MY_APPLICATION MY_SERVICE_INSTANCE + +# Restage the app to pick up change +cf restage MY_APPLICATION +``` + +For further information, refer to the [Single Sign-On for Tanzu developer guide](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/single-sign-on-for-tanzu/1-16/sso-tanzu/developer-index.html) or follow the instructions included in the [Steeltoe Security samples](https://github.com/SteeltoeOSS/Samples/blob/latest/Security/src/AuthWeb/README.md). + +### UAA Server + +If Single Sign-On for Tanzu is not available or desired for your application, you can use UAA as an alternative. + +There is no service broker available to manage service instances or bindings for UAA, so a [user provided service instance](https://docs.cloudfoundry.org/devguide/services/user-provided.html) must be used to hold the credentials. + +The following command is an example of how the binding could be created: + +```shell +cf cups MY_SERVICE_INSTANCE -p '{"auth_domain": "https://uaa.login.sys.cf-app.com","grant_types": [ "authorization_code", "client_credentials" ],"client_secret": "SOME_CLIENT_SECRET","client_id": "SOME_CLIENT_ID"}' +``` + +And the command below is an example of how to bind the service instance to the app: + +```shell +cf bind-service MY_APPLICATION MY_SERVICE_INSTANCE +``` + +For additional information, refer to the [UAA documentation](https://docs.cloudfoundry.org/concepts/architecture/uaa.html). diff --git a/api/v4/security/redis-key-storage-provider.md b/api/v4/security/redis-key-storage-provider.md new file mode 100644 index 00000000..c442e6cb --- /dev/null +++ b/api/v4/security/redis-key-storage-provider.md @@ -0,0 +1,119 @@ +# Redis Key Storage Provider + +The Redis Key Storage Provider is commonly used when secured data needs to be shared between two or more instances of the same application. + +By default, the [data protection system in ASP.NET Core](https://learn.microsoft.com/aspnet/core/security/data-protection/introduction) stores cryptographic keys on the local file system. +Even when not used by the application directly, these cryptographic keys are used for systems like [session state](https://learn.microsoft.com/aspnet/core/fundamentals/app-state#session-state) storage. + +By using the Steeltoe Redis key storage provider, you can easily reconfigure the data protection service to store these keys in Redis instances that are accessible through the [Steeltoe Redis Connector](../connectors/redis.md). + +The [Steeltoe Security samples](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/RedisDataProtection/README.md) can help you understand how and why to use this tool. + +## Usage + +To use this provider: + +1. Add NuGet reference(s). +1. Configure your connection string. +1. Initialize the Steeltoe Connector at startup. +1. Configure the data protection system to persist keys in the Redis database. +1. Add the Cloud Foundry configuration provider. +1. Create a Redis service instance and bind it to your application. + +### Add NuGet References + +To use the provider, you need to add a reference to the `Steeltoe.Security.DataProtection.Redis` NuGet package. + +If you are using Cloud Foundry service bindings, you will also need to add a reference to `Steeltoe.Configuration.CloudFoundry`. + +### Configure connection string + +You must configure a connection string in order to use Redis. +The following example `appsettings.Development.json` uses a local Redis server listening on the default Redis port: + +```json +{ + "Steeltoe": { + "Client": { + "Redis": { + "Default": { + "ConnectionString": "localhost" + } + } + } + } +} +``` + +### Initialize Steeltoe Connector + +Update your `Program.cs` as below to initialize the Connector: + +```csharp +using Steeltoe.Connectors.Redis; + +var builder = WebApplication.CreateBuilder(args); +builder.AddRedis(); +``` + +### Persist Keys to Redis + +There are several steps required to configure key storage in Redis: + +- Add data protection (while the services are added automatically, this step is required in order to access the builder). +- Set the key persistence location to Redis. +- Set an application name so all instances of the application can see the same data. + +These steps can be performed by chaining the method calls together: + +```csharp +using Microsoft.AspNetCore.DataProtection; +using Steeltoe.Security.DataProtection.Redis; + +builder.Services.AddDataProtection().PersistKeysToRedis().SetApplicationName("redis-data-protection-sample"); +``` + +> [!NOTE] +> At this point, the keys used by the `DataProtection` framework are stored in the bound Redis service. +> No additional steps are _required_, but you can also [use data protection in your application](https://learn.microsoft.com/aspnet/core/security/data-protection/consumer-apis/overview). + +### Add Cloud Foundry Configuration + +The Steeltoe package `Steeltoe.Configuration.CloudFoundry` reads Redis credentials from Cloud Foundry service bindings (`VCAP_SERVICES`) and maps them into the application's configuration in a format that the Redis connector can read. +Add the configuration provider to your application with this code: + +```csharp +using Steeltoe.Configuration.CloudFoundry; + +var builder = WebApplication.CreateBuilder(args); +builder.AddCloudFoundryConfiguration(); +``` + +### Cloud Foundry + +To use the Redis data protection key ring provider on Cloud Foundry, [use a supported Redis service](../connectors/redis.md#cloud-foundry) to create and bind an instance of Redis to your application. + +You can complete these steps using the Cloud Foundry command line, as follows: + +```bash +# Push your app +cf push sampleApp --buildpack dotnet_core_buildpack + +# Create Redis service +cf create-service p-redis shared-vm sampleRedisService + +# Bind service to your app +cf bind-service sampleApp sampleRedisService + +# Restage the app to pick up change +cf restage sampleApp +``` + +> [!NOTE] +> The preceding commands are for the Redis service provided by Tanzu Platform for Cloud Foundry. +> If you use a different service, you have to adjust the `create-service` command. + +Once the service is bound to your application, the configuration settings are available in `VCAP_SERVICES`. + +> [!TIP] +> Explore the [Steeltoe sample application](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/RedisDataProtection/README.md) for a demonstration on why this provider is useful. diff --git a/api/v4/security/sso-open-id.md b/api/v4/security/sso-open-id.md new file mode 100644 index 00000000..a8970d80 --- /dev/null +++ b/api/v4/security/sso-open-id.md @@ -0,0 +1,240 @@ +# Single Sign-On with OpenID Connect + +OpenID Connect is commonly used when users should be able to interact with a collection of applications using a single set of credentials for authentication and authorization. + +This library is a supplement to ASP.NET Core Security's OpenID Connect library (`Microsoft.AspNetCore.Authentication.OpenIdConnect`), adding functionality that helps you use Cloud Foundry Security services such as [Single Sign-On for VMware Tanzu](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/single-sign-on-for-tanzu/1-16/sso-tanzu/index.html) or [User Account and Authentication (UAA) Server](https://github.com/cloudfoundry/uaa). + +General guidance on OpenID Connect is beyond the scope of this document and can be found in many other sources (for example, see [OpenID](https://openid.net/developers/how-connect-works/)). +For the documentation of the underlying Microsoft OpenID Connect library, visit the [official documentation](https://learn.microsoft.com/aspnet/core/security/authentication/configure-oidc-web-authentication). + +The [Steeltoe Security samples](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/AuthWeb/README.md) can help you understand how to use this library. + +## Usage + +Steps involved in using this library: + +1. Add NuGet references. +1. Configure settings for the security provider. +1. Add and use the security provider in the application. +1. Secure your endpoints. +1. Create an instance of a Cloud Foundry Single Sign-On service and bind it to your application. + +### Add NuGet References + +To use this package, you will need to add a reference to the NuGet package `Steeltoe.Security.Authentication.OpenIdConnect`. + +Also add a reference to `Steeltoe.Configuration.CloudFoundry`, so that Cloud Foundry service bindings can be read by Steeltoe. + +### Configure Settings + +Since Steeltoe's OpenID Connect library configures Microsoft's OpenID Connect implementation, all available settings can be found in [`Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.authentication.openidconnect.openidconnectoptions) + +`OpenIdConnectOptions` is bound to configuration values found under `Authentication:Schemes:OpenIdConnect`. The following example `appsettings.json` shows how to declare a list of permissions that should be requested for users: + +```json +{ + // Configure OpenID Connect to request specific scopes (permissions) + "Authentication": { + "Schemes": { + "OpenIdConnect": { + "Scope": [ "openid", "sampleapi.read" ] + } + } + } +} +``` + +#### Cloud Foundry Service Bindings + +The Steeltoe package `Steeltoe.Configuration.CloudFoundry` reads Single Sign-On credentials from Cloud Foundry service bindings (`VCAP_SERVICES`) and re-maps them for Microsoft's OpenID Connect to read. Add the configuration provider to your application with this code: + +```csharp +using Steeltoe.Configuration.CloudFoundry; +using Steeltoe.Configuration.CloudFoundry.ServiceBindings; + +var builder = WebApplication.CreateBuilder(args); + +// Steeltoe: Add Cloud Foundry application and service info to configuration. +builder.AddCloudFoundryConfiguration(); +builder.Configuration.AddCloudFoundryServiceBindings(); +``` + +#### Local UAA + +A UAA server (such as [UAA Server for Steeltoe samples](https://github.com/SteeltoeOSS/Dockerfiles/tree/main/uaa-server)) can be used for local development of applications that will be deployed to Cloud Foundry. Configuration of UAA itself is beyond the scope of this documentation, but configuring your `appsettings.Development.json` to work with a local UAA server is possible with the addition of settings like these: + +```json +{ + "Authentication": { + "Schemes": { + "OpenIdConnect": { + "Authority": "http://localhost:8080/uaa", + "ClientId": "steeltoesamplesclient", + "ClientSecret": "client_secret", + "MetadataAddress": "http://localhost:8080/.well-known/openid-configuration", + "RequireHttpsMetadata": false + } + } + } +} +``` + +> [!IMPORTANT] +> If you wish to use the Steeltoe UAA server without modification, some application configuration options will be very limited. +> Because the OpenID Connect authentication flow requires user redirection to known locations, the client `steeltoesamplesclient` is expected to listen at , so you will need to update launchSettings.json accordingly. +> The Steeltoe UAA Server configuration can be found in [uaa.yml](https://github.com/SteeltoeOSS/Dockerfiles/blob/main/uaa-server/uaa.yml#L116). + +### Add and use OpenID Connect + +Since the majority of the OpenID Connect functionality is provided by Microsoft's libraries, the only difference when using Steeltoe will be the addition of calling `ConfigureOpenIdConnectForCloudFoundry` on the `AuthenticationBuilder`, as shown in the following example: + +```csharp +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Steeltoe.Security.Authentication.OpenIdConnect; + +// Add Microsoft Authentication services +builder.Services + .AddAuthentication(options => + { + options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; + }) + .AddCookie(options => + { + options.AccessDeniedPath = new PathString("/Home/AccessDenied"); + }) + .AddOpenIdConnect() + // Steeltoe: configure OpenID Connect to work with UAA/Cloud Foundry + .ConfigureOpenIdConnectForCloudFoundry(); + +// Register Microsoft Authorization services +builder.Services.AddAuthorizationBuilder() + // Create a named authorization policy that requires the user to have a scope with the same value + // which represents the user's permission to read from the sample API + .AddPolicy("sampleapi.read", policy => policy.RequireClaim("scope", "sampleapi.read")); +``` + +Activate authentication and authorization services _after_ routing services, but _before_ controller route registrations, with the following code: + +```csharp +using Microsoft.AspNetCore.HttpOverrides; + +var app = builder.Build(); + +app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedHost | ForwardedHeaders.XForwardedProto }); + +app.UseRouting(); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.MapDefaultControllerRoute(); + +app.Run(); +``` + +> [!TIP] +> In the sample code above, `app.UseForwardedHeaders` is used so that any links generated within the application will be compatible with reverse-proxy scenarios, such as when running in Cloud Foundry. + +### Securing Endpoints + +Once the services and middleware have been configured, you can secure endpoints with the standard ASP.NET Core `Authorize` attribute, as follows: + +```csharp +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +public class HomeController : Controller +{ + [Authorize] + public IActionResult Privacy() + { + return View(); + } + + [Authorize(Policy = "sampleapi.read")] + public string TestGroup() + { + return "You have the 'sampleapi.read' permission."; + } +} +``` + +The preceding example establishes the following security rules: + +* If a user attempts to access the `Privacy` action and the user is not authenticated, the user is redirected to the OAuth server (such as a UAA Server) to log in. +* If an authenticated user attempts to access the `TestGroup` action but does not meet the restrictions established by the referenced policy, the user is denied access. + +> [!TIP] +> The Steeltoe UAA server has several pre-provisioned user accounts. Sign in with `testuser` and password `password` to access resources secured with `sampleapi.read` +> To test with a user that does not have the permission `sampleapi.read`, sign in with the user `customer` and password `password`. +> +> You may want to explore the [Steeltoe Security samples](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/AuthWeb/README.md) for examples of additional basic functionality such as signing out of the application. + +### Single Sign-On for VMware Tanzu + +When using Single Sign-On for VMware Tanzu, you will need to identify the service plan to be used before creating a service instance of that plan. +If you do not have an existing service plan, a platform operator may need to create a new plan for you. +The operator should refer to the [Single Sign-On for Tanzu operator guide](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/single-sign-on-for-tanzu/1-16/sso-tanzu/operator-index.html) for information on how to configure plans for developer use. + +Once you have identified the service plan that will be used, create a service instance: + +```shell +cf create-service p-identity SERVICE_PLAN_NAME MY_SERVICE_INSTANCE +``` + +#### Bind and configure with app manifest + +Using a manifest file when you deploy to Cloud Foundry is recommended, and can save some work with the SSO configuration. Review the Single Sign-On documentation for [configuring an app manifest](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/single-sign-on-for-tanzu/1-16/sso-tanzu/config-apps.html#configure-app-manifest). + +Consider this example manifest that names the application, buildpack and configures several properties for the SSO binding: + +```yml +applications: +- name: steeltoesamplesclient + buildpacks: + - dotnet_core_buildpack + env: + GRANT_TYPE: authorization_code, client_credentials + SSO_AUTHORITIES: uaa.resource, sampleapi.read + SSO_IDENTITY_PROVIDERS: steeltoe-uaa + SSO_SCOPES: openid, profile, sampleapi.read + SSO_SHOW_ON_HOME_PAGE: "true" + services: + - sampleSSOService +``` + +#### Bind and configure manually + +Alternatively, you can manually bind the instance, restage the app with the Cloud Foundry CLI and later configure the SSO binding yourself with the web interface: + +```shell +# Bind service to your app +cf bind-service MY_APPLICATION MY_SERVICE_INSTANCE + +# Restage the app to pick up change +cf restage MY_APPLICATION +``` + +For further information, such as instructions on using the web interface, refer to the [Single Sign-On for Tanzu developer guide](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/single-sign-on-for-tanzu/1-16/sso-tanzu/developer-index.html) or follow the instructions included in the [Steeltoe Security samples](https://github.com/SteeltoeOSS/Samples/blob/main/Security/src/AuthWeb/README.md). + +### UAA Server + +If Single Sign-On for Tanzu is not available or desired for your application, you can use UAA as an alternative. + +There is no service broker available to manage service instances or bindings for UAA, so a [user provided service instance](https://docs.cloudfoundry.org/devguide/services/user-provided.html) should be used to hold the credentials. + +This command is an example of how the binding could be created: + +```shell +cf cups MY_SERVICE_INSTANCE -p '{"auth_domain": "https://uaa.login.sys.cf-app.com","grant_types": [ "authorization_code", "client_credentials" ],"client_secret": "SOME_CLIENT_SECRET","client_id": "SOME_CLIENT_ID"}' +``` + +And this command is an example of how to bind the service instance to the app: + +```shell +cf bind-service MY_APPLICATION MY_SERVICE_INSTANCE +``` + +For additional information, refer to the [UAA documentation](https://docs.cloudfoundry.org/concepts/architecture/uaa.html). diff --git a/api/v4/toc.yml b/api/v4/toc.yml new file mode 100644 index 00000000..dc5e8416 --- /dev/null +++ b/api/v4/toc.yml @@ -0,0 +1,148 @@ +- name: Welcome - v4 + topicHref: welcome/ + items: + - topicHref: welcome/whats-new.md + name: What's new in Steeltoe 4 + items: + - topicHref: welcome/whats-new.md#bootstrap + name: Bootstrap + - topicHref: welcome/whats-new.md#common + name: Common + - topicHref: welcome/whats-new.md#configuration + name: Configuration + - topicHref: welcome/whats-new.md#connectors + name: Connectors + - topicHref: welcome/whats-new.md#discovery + name: Discovery + - topicHref: welcome/whats-new.md#logging + name: Logging + - topicHref: welcome/whats-new.md#management + name: Management + - topicHref: welcome/whats-new.md#security + name: Security + - topicHref: welcome/prerequisites.md + name: Prerequisites + - topicHref: welcome/common-steps.md + name: Common Steps +- name: Application Bootstrapping + topicHref: bootstrap/ +- name: Application Configuration + topicHref: configuration/ + items: + - topicHref: configuration/config-server-provider.md + name: Config Server Provider + - topicHref: configuration/random-value-provider.md + name: Random Value Provider + - topicHref: configuration/placeholder-provider.md + name: Placeholder Provider + - topicHref: configuration/decryption-provider.md + name: Decryption Provider + - topicHref: configuration/cloud-foundry-provider.md + name: Cloud Foundry Provider + - topicHref: configuration/spring-boot-provider.md + name: Spring Boot Provider +- name: Distributed Tracing + topicHref: tracing/ +- name: Dynamic Logging + topicHref: logging/ + items: + - topicHref: logging/dynamic-console-logging.md + name: Console + - topicHref: logging/dynamic-serilog-logging.md + name: Serilog +- name: Management + topicHref: management/ + items: + - topicHref: management/using-endpoints.md + name: Endpoints + items: + - topicHref: management/dbmigrations.md + name: Database Migrations + - topicHref: management/env.md + name: Environment + - topicHref: management/health.md + name: Health + - topicHref: management/heapdump.md + name: Heap Dump + - topicHref: management/httpexchanges.md + name: HTTP Exchanges + - topicHref: management/hypermedia.md + name: Hypermedia + - topicHref: management/info.md + name: Info + - topicHref: management/loggers.md + name: Loggers + - topicHref: management/mappings.md + name: Route Mappings + - topicHref: management/prometheus.md + name: Prometheus + - topicHref: management/refresh.md + name: Refresh + - topicHref: management/services.md + name: Services + - topicHref: management/threaddump.md + name: Thread Dump + - topicHref: management/tasks.md + name: Tasks + - topicHref: management/springbootadmin.md + name: Spring Boot Admin Client + - topicHref: management/cloud-foundry.md + name: Cloud Foundry Integration +- name: Network File Sharing + topicHref: fileshares/ + items: + - topicHref: fileshares/usage.md + name: Usage +- name: Security + topicHref: security/ + items: + - topicHref: security/sso-open-id.md + name: SSO with Open ID Connect + - topicHref: security/jwt-bearer.md + name: JWT Bearer Token + - topicHref: security/certificate.md + name: Certificate (Mutual TLS) + - topicHref: security/redis-key-storage-provider.md + name: Redis Key Storage Provider +- name: Connectors + topicHref: connectors/ + items: + - topicHref: connectors/usage.md + name: Usage + - topicHref: connectors/extensibility.md + name: Extensibility + - topicHref: connectors/mysql.md + name: MySQL + - topicHref: connectors/microsoft-sql-server.md + name: Microsoft SQL Server + - topicHref: connectors/postgresql.md + name: PostgreSQL + - topicHref: connectors/rabbitmq.md + name: RabbitMQ + - topicHref: connectors/mongodb.md + name: MongoDB + - topicHref: connectors/cosmosdb.md + name: CosmosDB + - topicHref: connectors/redis.md + name: Redis +- name: Service Discovery + topicHref: discovery/ + items: + - topicHref: discovery/initialize-discovery-client.md + name: Discovery clients + items: + - topicHref: discovery/configuration-based.md + name: Configuration-based + - topicHref: discovery/hashicorp-consul.md + name: HashiCorp Consul + - topicHref: discovery/netflix-eureka.md + name: Netflix Eureka + - topicHref: discovery/discovering-services.md + name: Discovering services +- name: Initializr + topicHref: initializr/ + items: + - topicHref: initializr/initializr-service.md + name: InitializrService + - topicHref: initializr/initializr-web.md + name: InitializrWeb diff --git a/api/v4/tracing/index.md b/api/v4/tracing/index.md new file mode 100644 index 00000000..dd9535b8 --- /dev/null +++ b/api/v4/tracing/index.md @@ -0,0 +1,253 @@ +# Distributed Tracing + +On the subject of distributed tracing for .NET applications, previous versions of Steeltoe offered either an implementation of OpenCensus or shortcuts for enabling distributed tracing with [OpenTelemetry](https://opentelemetry.io/) to integrate with the Tanzu platform. We painted ourselves into a corner with Steeltoe 3, which has a strong dependency on OpenTelemetry packages. New versions of OpenTelemetry contained breaking changes, which we couldn't adapt to without resorting to reflection. While we do that in other places, reflection is slow, and instrumentation is performance-sensitive. + +By now, OpenTelemetry has evolved to the point that only a few lines of code are needed. So instead of providing a Steeltoe component, the guidance below is offered to accomplish the same. The benefit of that is greater flexibility: when OpenTelemetry changes, there's no need to wait for a new Steeltoe version first. + +Steeltoe continues to directly offer an option for [log correlation](#log-correlation). This page also provides direction for developers looking to achieve the same outcomes Steeltoe has previously provided more directly. + +## Introduction + +As the name implies, distributed tracing is a way of tracing requests through distributed systems. +Distributed tracing is typically accomplished by instrumenting components of the system to recognize and pass along metadata that is specific to a particular action or user request, and using another backend system to reconstruct the flow of the request through that metadata. + +In the parlance of distributed tracing, a "span" is the basic unit of work. For example, sending an HTTP request creates a new span, as does sending a response. +Spans are identified by a unique ID and contain the ID for the "trace" it is part of. +Spans also have other data like descriptions, key-value annotations, the ID of the span that initiated the execution flow, and process IDs. +Spans are started and stopped, and they keep track of their timing information. Once you create a span, you must stop it at some point in the future. +A set of spans form a tree-like structure called a "trace". For example, a trace might be formed by a POST request that adds an item to a shopping cart, which results in calling several backend services. + +## Log correlation + +Log correlation is all about taking log entries from disparate systems and bringing them together using some matching criteria (such as a distributed trace ID). +The process can be easier when important pieces of data are logged in the same format across different systems (such as .NET and Java apps communicating with each other). + +Steeltoe provides the class `TracingLogProcessor`, which is an `IDynamicMessageProcessor` for correlating logs. The processor is built for use with a [Steeltoe Dynamic Logging provider](../logging/index.md). +It enriches log entries with correlation data using the same trace format popularized by [Spring Cloud Sleuth](https://cloud.spring.io/spring-cloud-sleuth/reference/html/#log-correlation), +that include `[,,,,]`. + +Consider this pair of log entries from the [Steeltoe Management sample applications](https://github.com/SteeltoeOSS/Samples/blob/main/Management/src/): + +```text +info: System.Net.Http.HttpClient.ActuatorApiClient.LogicalHandler[100] + [ActuatorWeb,44ed2fe24a051bda2d1a56815448e9fb,8d51b985e3f0fd81,0000000000000000,true] Start processing HTTP request GET http://localhost:5140/weatherForecast?fromDate=2024-12-19&days=1 + +dbug: Microsoft.EntityFrameworkCore.Database.Command[20104] + [ActuatorApi,44ed2fe24a051bda2d1a56815448e9fb,c32846ff227bed40,f315823f4c554816,true] Created DbCommand for 'ExecuteReader' (1ms). +``` + +Log correlation is easiest with a tool such as [Splunk](https://www.splunk.com/en_us/solutions/isolate-cloud-native-problems.html), [SumoLogic](https://www.sumologic.com/lp/log-analytics/) or [DataDog](https://www.datadoghq.com/dg/enterprise/log-management-analytics-security) (this is not an endorsement of any tool, only a pointer to some popular options). + +### Using TracingLogProcessor + +To use the processor, first add a reference to the `Steeltoe.Management.Tracing` NuGet package. + +The only remaining step is to register the processor: + +```csharp +using Steeltoe.Management.Tracing; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddTracingLogProcessor(); +``` + +> [!NOTE] +> This extension method also ensures that implementations of `IApplicationInstanceInfo` and `IDynamicLoggerProvider` have been registered. +> If you wish to customize either of those or use non-default implementations, do so before calling `AddTracingLogProcessor`. + +## OpenTelemetry + +To use OpenTelemetry, start by adding a reference to the `OpenTelemetry.Extensions.Hosting` NuGet package. +Other package references will likely be necessary, but depend on your specific application needs. +This package provides access to `OpenTelemetryBuilder`, which is the main entrypoint to OpenTelemetry. + +### Add Open Telemetry Tracing + +```csharp +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddOpenTelemetry().WithTracing(); +``` + +> [!NOTE] +> At this point, not much has changed for the application - you will need changes to this line to add [instrumentation](#instrumenting-applications) and [exporting of traces](#exporting-distributed-traces). + +### Sampler configuration + +OpenTelemetry Provides the `Sampler` abstraction for configuring when traces should be recorded. +The simplest options are `AlwaysOnSampler` and `AlwaysOffSampler`, with their names describing exactly which traces will be recorded. + +As a replacement for what Steeltoe used to provide for using these samplers, set the environment variable `OTEL_TRACES_SAMPLER` to `always_on` or `always_off`. + +> [!TIP] +> OpenTelemetry is generally built to follow the [options pattern](https://learn.microsoft.com/dotnet/core/extensions/options). +> There are more ways to configure options than demonstrated on this page, these are just examples to get started. + +### Set Application Name + +In order to use the Steeltoe name for your application with OpenTelemetry, call `SetResourceBuilder` and pass in a value from the registered `IApplicationInstanceInfo`: + +```csharp +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; +using Steeltoe.Common; + +builder.Services.ConfigureOpenTelemetryTracerProvider((serviceProvider, tracerProviderBuilder) => +{ + var appInfo = serviceProvider.GetRequiredService(); + tracerProviderBuilder.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(appInfo.ApplicationName!)); +}); +``` + +The above example assumes you are already using some other Steeltoe component which adds `IApplicationInstanceInfo` to the IoC container. If that is not the case, there are two steps to take to register the default implementation: + +1. Add a NuGet package reference to `Steeltoe.Common` +1. Call `AddApplicationInstanceInfo` + +```csharp +using Steeltoe.Common.Extensions; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddApplicationInstanceInfo(); +``` + +### Instrumenting applications + +In order to maximize the benefit of collecting distributed traces, you'll want participation from the core components and frameworks of your application and some 3rd party components. +Some packages in the .NET ecosystem automatically support OpenTelemetry, others can be supported by the [collection of instrumentation libraries](https://opentelemetry.io/ecosystem/registry/?language=dotnet&component=instrumentation). +Steeltoe previously configured the instrumentation libraries for [HttpClient](#httpclient) and [ASP.NET Core](#aspnet-core). + +#### ASP.NET Core + +To instrument requests coming into the application through ASP.NET Core, start by adding a reference to the `OpenTelemetry.Instrumentation.AspNetCore` NuGet package. + +Next, add the instrumentation to the `TracerProviderBuilder` by updating the existing call from above to: + +```csharp +using OpenTelemetry.Trace; + +builder.Services.AddOpenTelemetry().WithTracing(tracerProviderBuilder => tracerProviderBuilder.AddAspNetCoreInstrumentation()); +``` + +In order to replicate the Steeltoe setting `IngressIgnorePattern` (a Regex pattern describing which incoming requests to ignore), configure the `AspNetCoreTraceInstrumentationOptions`: + +```csharp +using System.Text.RegularExpressions; +using OpenTelemetry.Instrumentation.AspNetCore; + +builder.Services.Configure(options => +{ + const string defaultIngressIgnorePattern = @"/actuator/.*|/cloudfoundryapplication/.*|.*\.png|.*\.css|.*\.js|.*\.html|/favicon.ico|.*\.gif"; + Regex ingressPathMatcher = new(defaultIngressIgnorePattern, RegexOptions.Compiled | RegexOptions.CultureInvariant, TimeSpan.FromSeconds(1)); + options.Filter += httpContext => !ingressPathMatcher.IsMatch(httpContext.Request.Path); +}); +``` + +As an alternative to using a regular expression, you can list out the paths to ignore in the Filter property (`Filter` is a `Func?`): + +```csharp +using OpenTelemetry.Instrumentation.AspNetCore; + +builder.Services.Configure(options => +{ + options.Filter += httpContext => + !httpContext.Request.Path.StartsWithSegments("/actuator", StringComparison.OrdinalIgnoreCase) && + !httpContext.Request.Path.StartsWithSegments("/cloudfoundryapplication", StringComparison.OrdinalIgnoreCase); +}); +``` + +> [!TIP] +> By default, the ASP.NET Core instrumentation does not filter out any requests. +> The latter approach above may quickly prove unwieldy if there are many patterns to ignore, such as when listing many file types. + +To learn more about ASP.NET Core instrumentation for OpenTelemetry see [the documentation](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore). + +#### HttpClient + +To instrument requests leaving the application through `HttpClient`, start by adding a reference to the `OpenTelemetry.Instrumentation.Http` NuGet package. + +Next, add the instrumentation to the `TracerProviderBuilder` by updating the existing call from above to: + +```csharp +using OpenTelemetry.Trace; + +builder.Services.AddOpenTelemetry().WithTracing(tracerProviderBuilder => tracerProviderBuilder.AddHttpClientInstrumentation()); +``` + +In order to replicate the Steeltoe setting `EgressIgnorePattern` (a Regex pattern describing which outgoing HTTP requests to ignore), configure the `HttpClientTraceInstrumentationOptions`: + +```csharp +using OpenTelemetry.Instrumentation.Http; +using System.Text.RegularExpressions; + +builder.Services.Configure(options => +{ + const string defaultEgressIgnorePattern = "/api/v2/spans|/v2/apps/.*/permissions"; + Regex egressPathMatcher = new(defaultEgressIgnorePattern, RegexOptions.Compiled | RegexOptions.CultureInvariant, TimeSpan.FromSeconds(1)); + options.FilterHttpRequestMessage += httpRequestMessage => !egressPathMatcher.IsMatch(httpRequestMessage.RequestUri?.PathAndQuery ?? string.Empty); +}); +``` + +To learn more about HttpClient instrumentation for OpenTelemetry see [the documentation](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.Http). + +### Propagating Trace Context + +By default, OpenTelemetry uses the [W3C trace context](https://github.com/w3c/trace-context) for propagating traces. +Some systems like Cloud Foundry may still be configured for the Zipkin standard of [B3 propagation](https://github.com/openzipkin/b3-propagation). + +In order to use B3 propagation, add a reference to the `OpenTelemetry.Extensions.Propagators` NuGet package. + +Next, let the compiler know that the `B3Propagator` should come from the package reference you just added (rather than the deprecated class found in `OpenTelemetry.Context.Propagation`): + +```csharp +using B3Propagator = OpenTelemetry.Extensions.Propagators.B3Propagator; +``` + +Finally, register a `CompositeTextMapPropagator` that includes the `B3Propagator` and `BaggagePropagator`: + +```csharp +using OpenTelemetry; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Trace; + +builder.Services.ConfigureOpenTelemetryTracerProvider((_, _) => +{ + List propagators = + [ + new B3Propagator(), + new BaggagePropagator() + ]; + + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(propagators)); +}); +``` + +### Exporting Distributed Traces + +Previous versions of Steeltoe could automatically configure several different trace exporters, including [Zipkin](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.Zipkin), [OpenTelemetryProtocol (OTLP)](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol) and Jaeger. +The Jaeger exporter has been deprecated in favor of OTLP, which was only minimally configured by Steeltoe and is better described by [the official OTLP exporter documentation](https://opentelemetry.io/docs/languages/net/exporters/#otlp). + +#### Zipkin Server + +To use the Zipkin Exporter, add a reference to the `OpenTelemetry.Exporter.Zipkin` NuGet package. + +Next, use the extension method `AddZipkinExporter` by updating the existing call from above to: + +```csharp +builder.Services.AddOpenTelemetry().WithTracing(tracerProviderBuilder => tracerProviderBuilder.AddZipkinExporter()); +``` + +The Zipkin options class `ZipkinExporterOptions` works nearly the same as Steeltoe settings with the same names in previous releases: + +```csharp +using OpenTelemetry.Exporter; + +builder.Services.Configure(options => +{ + options.Endpoint = new Uri("http://localhost:9411"); + options.MaxPayloadSizeInBytes = 4096; + options.UseShortTraceIds = true; +}); +``` + +> [!TIP] +> The Zipkin endpoint can also be set with the environment variable "OTEL_EXPORTER_ZIPKIN_ENDPOINT". diff --git a/api/v4/welcome/common-steps.md b/api/v4/welcome/common-steps.md new file mode 100644 index 00000000..015a7276 --- /dev/null +++ b/api/v4/welcome/common-steps.md @@ -0,0 +1,63 @@ +# Common Steps + +This section outlines how to work with the Steeltoe sample applications: + +* [Publish Sample](#publish-sample) +* [Push Sample to Cloud Foundry](#cloud-foundry-push-sample) + +## Publish Sample + +This section describes how to publish a sample on Windows, Linux, or macOS. + +### ASP.NET Core + +You can use the `dotnet` CLI to [build and locally publish](https://learn.microsoft.com/dotnet/core/tools/dotnet-publish) the application for the target framework and runtime to which you want to deploy the application: + +* Windows: `dotnet publish --framework net8.0 --runtime win-x64` +* Linux: `dotnet publish --framework net8.0 --runtime linux-x64` +* macOS: `dotnet publish --framework net8.0 --runtime osx-x64` + +> [!TIP] +> Since .NET Core 2.0, the `dotnet publish` command automatically runs NuGet package restore for you. Running `dotnet restore` explicitly is no longer required. + +## Cloud Foundry Push Sample + +This section describes how to use the [Cloud Foundry CLI](https://docs.cloudfoundry.org/cf-cli/install-go-cli.html) to push the published application to Cloud Foundry by using the parameters that match what you selected for framework and runtime: + +```bash +# Push to Linux cell +cf push -f manifest.yml -p bin/Debug/net8.0/linux-x64/publish + +# Push to Windows cell, .NET Core +cf push -f manifest-windows.yml -p bin/Debug/net8.0/win-x64/publish +``` + +> [!NOTE] +> All sample manifests have been defined to bind their application to the services as created earlier. + +### Observe the Logs + +To see the logs as you start the application, use `cf logs your-app-name`. + +On a Linux cell, you should see output that resembles the following during startup: + +```bash +2016-06-01T09:14:14.38-0600 [CELL/0] OUT Creating container +2016-06-01T09:14:15.93-0600 [CELL/0] OUT Successfully created container +2016-06-01T09:14:17.14-0600 [CELL/0] OUT Starting health monitoring of container +2016-06-01T09:14:21.04-0600 [APP/0] OUT Hosting environment: Development +2016-06-01T09:14:21.04-0600 [APP/0] OUT Content root path: /home/vcap/app +2016-06-01T09:14:21.04-0600 [APP/0] OUT Now listening on: http://*:8080 +2016-06-01T09:14:21.04-0600 [APP/0] OUT Application started. Press Ctrl+C to shut down. +2016-06-01T09:14:21.41-0600 [CELL/0] OUT Container became healthy +``` + +On Windows cells, you should see something slightly different with similar information. + +### Reading Configuration Values + +When pushing the application to Cloud Foundry, the settings from service bindings merge with the configuration settings from other configuration mechanisms (such as `appsettings.json`). + +If there are merge conflicts, the last provider added to the configuration takes precedence and overrides all others. + +To manage application settings centrally instead of with individual files, you can use [Steeltoe Configuration](../configuration/index.md) and a tool such as [Spring Cloud Config Server](https://github.com/spring-cloud/spring-cloud-config). diff --git a/api/v4/welcome/index.md b/api/v4/welcome/index.md new file mode 100644 index 00000000..5246ed53 --- /dev/null +++ b/api/v4/welcome/index.md @@ -0,0 +1,41 @@ +# Steeltoe Documentation + +## [What's New](./whats-new.md) + +Lists the new features and changes in Steeltoe v4. + +## [Application Bootstrapping](../bootstrap/index.md) + +Automatically configure many Steeltoe components with a single line of code. + +## [Application Configuration](../configuration/index.md) + +Access external configuration values from Git, the file system, or HashiCorp Vault with Spring Cloud Config. + +## [Distributed Tracing](../tracing/index.md) + +Capture trace data for your microservice application using logs, or by sending to a remote collector service. + +## [Dynamic Logging](../logging/index.md) + +List the active loggers and change their minimum log levels at runtime. + +## [Management](../management/index.md) + +Monitor and manage your application while it runs in production via various HTTP endpoints. + +## [Network File Sharing](../fileshares/index.md) + +Provides a simplified experience for interacting with SMB file shares (Windows only). + +## [Security](../security/index.md) + +Integrate ASP.NET authentication and authorization features in your app, no matter what cloud platform you use. + +## [Connectors](../connectors/index.md) + +Automatically configure connections to common cloud services like databases, message brokers, caches, and more. + +## [Service Discovery](../discovery/index.md) + +Register and discover microservices by interacting with popular service registries. diff --git a/api/v4/welcome/prerequisites.md b/api/v4/welcome/prerequisites.md new file mode 100644 index 00000000..cc5dce2d --- /dev/null +++ b/api/v4/welcome/prerequisites.md @@ -0,0 +1,26 @@ +# Prerequisites + +While not required, we recommend installing one of the development tools ([Visual Studio](https://www.visualstudio.com/) or [Visual Studio Code](https://code.visualstudio.com/)) provided by Microsoft. + +If you plan to develop with [.NET](https://learn.microsoft.com/dotnet/fundamentals) or [ASP.NET Core](https://learn.microsoft.com/aspnet/core), you will need to download and install the latest [.NET SDK](https://dotnet.microsoft.com/download). Additionally, if you do not already know the language and framework well, we recommend you first spend time working through some of the following tutorials from Microsoft: + +* [Getting Started with C#](https://learn.microsoft.com/dotnet/csharp) +* [Getting Started with ASP.NET Core](https://learn.microsoft.com/aspnet/core/getting-started) + +## NuGet Feeds + +When developing applications with Steeltoe, you need to pull the Steeltoe NuGet packages into your project. + +To use the latest *unstable* packages from the developer feed, create a `Nuget.config` file with the contents below. + +```xml + + + + + + + + + +``` diff --git a/api/v4/welcome/whats-new.md b/api/v4/welcome/whats-new.md new file mode 100644 index 00000000..2d60260f --- /dev/null +++ b/api/v4/welcome/whats-new.md @@ -0,0 +1,1496 @@ +# What's new in Steeltoe 4 + +## Overview + +### Introduction + +The Steeltoe project began all the way back in 2016 (before .NET Core 1.0.0 was released) at the request of enterprises experiencing great success with their [Spring Cloud](https://spring.io/cloud) powered applications on [Cloud Foundry](https://www.cloudfoundry.org/). +These organizations were looking for similar outcomes (such as reduced developer toil, easy-to-implement observability, scaling and resiliency) for their .NET applications. +Rather than starting from scratch, Steeltoe took the approach of building clients for Spring Cloud services and porting code from Spring as needed, adapting the codebase to fit with .NET while trying to stay close to the Spring origins. +In order to deliver higher-level Spring project features, Steeltoe libraries grew rapidly with building-block components matching the architecture and conventions in Spring. + +All previous versions of Steeltoe had capability and feature expansion as the main goals, with moderate regard for how well Steeltoe "blends in" with the greater .NET ecosystem. +As a result of this weighting of priorities, Steeltoe was built to land somewhere in between Spring and .NET, inconsistently favoring conventions from one camp or the other, sometimes with the weight of additional lower-level abstractions from Spring. +Add to that the breaking changes needed to adapt to updates in the .NET ecosystem since some of the older Steeltoe components were written, and you can see why it was time for a major overhaul. + +The introduction of [.NET Aspire](https://learn.microsoft.com/dotnet/aspire/get-started/aspire-overview) and the acquisition of VMware by Broadcom +underscored that this is the time to refocus on Steeltoe's core goals and re-evaluate how the desired outcomes are achieved. + +Steeltoe 4 is a major release that brings many improvements and changes to the library. +The goal of this release is to make Steeltoe better integrated in the .NET ecosystem in a more developer-friendly way, compatible +with the latest versions of .NET and third-party libraries/products, and to improve the overall quality of the library. +This document provides an overview of the changes in Steeltoe 4, the impact on existing applications, and serves as the upgrade guide (with a searchable API diff and replacement notes). +Steeltoe 4 requires .NET 8 or higher. + +### Quality of Life improvements + +- Annotated for [nullable reference types](https://learn.microsoft.com/dotnet/csharp/nullable-references) +- Compatible with the latest versions of ASP.NET and third-party libraries +- Compatible with recent versions of Tanzu Platform (Cloud Foundry and Kubernetes) and Spring Boot +- Changes to align with .NET conventions and patterns, extensive review of the public API surface +- Performance and scalability improvements +- Numerous bugfixes +- Cleanup of logging output +- Substantially improved documentation +- Improved test coverage, including interaction between different Steeltoe components +- All samples updated to .NET 8, fully tested and working +- Automated code style validation (Resharper, StyleCop, Sonar, Microsoft CodeAnalysis) + +### General + +- NuGet Packages + - Dropped the Core/Base suffix from package names, which was used to distinguish between NET Standard and .NET Core + - Removed ".Extensions" from NuGet package names +- Extension methods + - Removed host builder extension methods that could be substituted with a single extension method on + `IServiceCollection`, `IConfiguration`, `IConfigurationBuilder`, `ILoggingBuilder` etc. + Their redundancy led to confusion, and required Steeltoe to adapt each time a new host builder is introduced. + - Added support for the new `IHostApplicationBuilder` (which `WebApplicationBuilder` and `HostApplicationBuilder` implement) to the remaining host builder extension methods + - Moved extension methods to the appropriate Steeltoe namespaces to avoid clashes with other libraries +- Public API surface + - Sealed types not designed for inheritance, which improves runtime performance + - Removed various interfaces that weren't general-purpose, types not designed for inheritance/reuse made internal + - Changed methods containing optional parameters with default values to overloaded methods + - Made more methods async and expanded usage of `CancellationToken`, both as a parameter and internally + - Enhanced method input validation to prevent downstream `NullReferenceException`s + - Applied C#/.NET naming conventions, for example: renamed `HealthStatus.OUT_OF_SERVICE` to `HealthStatus.OutOfService` +- Configuration + - Added support in Steeltoe packages for auto-completion in `appsettings.json` (without needing a schema reference, which currently only works in Visual Studio for SDK-style web projects), updated global Steeltoe JSON schema + - Changed nearly all configuration settings to be reloadable without app restart, now more consistently exposed via ASP.NET Options pattern +- Up-to-date + - Extensively tested with the latest versions of dependent packages, database drivers and third-party products + (including Tanzu, Cloud Foundry, Config Server, Consul, Eureka, RabbitMQ, Redis, OpenTelemetry, Grafana, Prometheus, Zipkin, Spring Boot Admin) + - Refreshed dev-local Docker images for Config Server, Eureka, UAA and Spring Boot Admin + - Steeltoe no longer depends on legacy technologies, such as binary serialization and Newtonsoft.Json + +### Removed components + +- Everything that interacts with the Kubernetes API directly, because the features were not well-defined, + test coverage was minimal, and the Steeltoe team believes these packages aren't widely used +- CredHub client, because we have no _known_ use cases since the introduction of the [CredHub Service Broker](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/credhub-service-broker/services/credhub-sb/index.html) +- CircuitBreaker, because [Polly](https://github.com/App-vNext/Polly) provides similar features and is widely used in .NET apps +- Messaging/Integration/Stream, because usage and implementation are too complicated and the adoption rate is very low +- Spring Expression Language (SpEL), because it was added for Stream and doesn't support many C# language features + +> [!NOTE] +> The components that have been removed from Steeltoe 4 are not _expected_ to have a significant impact due to low adoption (based on NuGet package downloads). +> If the loss of any of this functionality _is_ a problem for you, please [open an issue](https://github.com/SteeltoeOSS/Steeltoe/issues/new) and tell us more. + +### Package name changes + +| Steeltoe 3.x | Steeltoe 4.x | +| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| Steeltoe.Bootstrap.Autoconfig | Steeltoe.Bootstrap.AutoConfiguration | +| Steeltoe.CircuitBreaker.* | - | +| Steeltoe.Common.Abstractions | Steeltoe.Common | +| Steeltoe.Common.Expression | - | +| Steeltoe.Common.Hosting | Steeltoe.Common.Logging | +| Steeltoe.Common.Http | Steeltoe.Discovery.HttpClients | +| Steeltoe.Common.Kubernetes | - | +| Steeltoe.Common.Retry | - | +| Steeltoe.Common.Security | Steeltoe.Common.Certificates | +| Steeltoe.Common.Utils | - | +| Steeltoe.Connector.* | Steeltoe.Connectors | +| Steeltoe.Connector.EFCore | Steeltoe.Connectors.EntityFrameworkCore | +| Steeltoe.Connector.EF6Core | - | +| Steeltoe.Discovery.Abstractions | Steeltoe.Common | +| Steeltoe.Discovery.ClientBase | Steeltoe.Discovery.HttpClients | +| Steeltoe.Discovery.ClientCore | Steeltoe.Discovery.HttpClients | +| Steeltoe.Discovery.Kubernetes | - | +| Steeltoe.Extensions.Configuration.Abstractions | Steeltoe.Configuration.Abstractions | +| Steeltoe.Extensions.Configuration.CloudFoundryBase | Steeltoe.Configuration.CloudFoundry | +| Steeltoe.Extensions.Configuration.CloudFoundryCore | Steeltoe.Configuration.CloudFoundry | +| Steeltoe.Extensions.Configuration.ConfigServerBase | Steeltoe.Configuration.ConfigServer | +| Steeltoe.Extensions.Configuration.ConfigServerCore | Steeltoe.Configuration.ConfigServer | +| Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding | Steeltoe.Configuration.Kubernetes.ServiceBindings | +| Steeltoe.Extensions.Configuration.KubernetesBase | - | +| Steeltoe.Extensions.Configuration.KubernetesCore | - | +| Steeltoe.Extensions.Configuration.PlaceholderBase | Steeltoe.Configuration.Placeholder | +| Steeltoe.Extensions.Configuration.PlaceholderCore | Steeltoe.Configuration.Placeholder | +| Steeltoe.Extensions.Configuration.RandomValueBase | Steeltoe.Configuration.RandomValue | +| Steeltoe.Extensions.Configuration.SpringBootBase | Steeltoe.Configuration.SpringBoot | +| Steeltoe.Extensions.Configuration.SpringBootCore | Steeltoe.Configuration.SpringBoot | +| Steeltoe.Extensions.Logging.Abstractions | Steeltoe.Logging.Abstractions | +| Steeltoe.Extensions.Logging.DynamicLogger | Steeltoe.Logging.DynamicConsole | +| Steeltoe.Extensions.Logging.DynamicSerilogBase | Steeltoe.Logging.DynamicSerilog | +| Steeltoe.Extensions.Logging.DynamicSerilogCore | Steeltoe.Logging.DynamicSerilog | +| Steeltoe.Integration.* | - | +| Steeltoe.Management.CloudFoundryCore | Steeltoe.Management.Endpoint | +| Steeltoe.Management.Diagnostics | Steeltoe.Management.Endpoint | +| Steeltoe.Management.EndpointBase | Steeltoe.Management.Endpoint | +| Steeltoe.Management.EndpointCore | Steeltoe.Management.Endpoint | +| Steeltoe.Management.KubernetesCore | - | +| Steeltoe.Management.OpenTelemetryBase | Steeltoe.Management.Endpoint, Steeltoe.Management.Prometheus | +| Steeltoe.Management.TaskCore | Steeltoe.Management.Tasks | +| Steeltoe.Management.TracingBase | Steeltoe.Management.Tracing | +| Steeltoe.Management.TracingCore | Steeltoe.Management.Tracing | +| Steeltoe.Messaging.* | - | +| Steeltoe.Security.Authentication.CloudFoundryBase | Steeltoe.Security.Authentication.JwtBearer, Steeltoe.Security.Authentication.OpenIdConnect, Steeltoe.Security.Authorization.Certificate | +| Steeltoe.Security.Authentication.CloudFoundryCore | Steeltoe.Security.Authentication.JwtBearer, Steeltoe.Security.Authentication.OpenIdConnect, Steeltoe.Security.Authorization.Certificate | +| Steeltoe.Security.Authentication.MtlsCore | Steeltoe.Security.Authorization.Certificate | +| Steeltoe.Security.DataProtection.CredHubBase | - | +| Steeltoe.Security.DataProtection.CredHubCore | - | +| Steeltoe.Security.DataProtection.RedisCore | Steeltoe.Security.DataProtection.Redis | +| Steeltoe.Stream.* | - | + +The following sections provide details on the changes per Steeltoe component, as well as tips on how to migrate to Steeltoe 4. + +## Bootstrap + +### Behavior changes + +- Unified handling for all host builder types (there were omissions in some cases, due to duplicate code not kept in sync) +- Added wire-up of Steeltoe.Configuration.SpringBoot, Steeltoe.Configuration.Encryption and Steeltoe.Logging.DynamicConsole +- Removed wire-up of client certificate authentication, which was done only partly +- When no `ILoggerFactory` is specified, `BootstrapLoggerFactory` is used by default (pass `NullLoggerFactory.Instance` to disable) +- Ignore casing when comparing assembly names (bugfix) + +### NuGet Package changes + +| Source | Change | Replacement | Notes | +| ----------------------------- | ------ | ------------------------------------ | ----- | +| Steeltoe.Bootstrap.Autoconfig | Moved | Steeltoe.Bootstrap.AutoConfiguration | | + +### API changes + +| Source | Kind | Package | Change | Replacement | Notes | +| -------------------------------------------------- | --------- | ----------------------------- | ------- | ------------------------------------------------------------ | --------------------------------------------------------- | +| `Steeltoe.Bootstrap.Autoconfig.SteeltoeAssemblies` | Type | Steeltoe.Bootstrap.Autoconfig | Renamed | `Steeltoe.Bootstrap.AutoConfiguration.SteeltoeAssemblyNames` | Updated members to new/changed assembly names | +| `Steeltoe.Connector` | Namespace | Steeltoe.Bootstrap.Autoconfig | Removed | None | Type locators have been replaced with internal-only shims | + +### Notable PRs + +- https://github.com/SteeltoeOSS/Steeltoe/pull/1434 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1352 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1325 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1223 + +### Documentation + +For more information, see the updated [Bootstrap documentation](../bootstrap/index.md). + +## Common + +### Behavior changes + +- Removed various APIs that were used internally, but not designed for extensibility/reuse +- Dynamically loading custom types for connectors and service discovery is no longer possible +- Removed Spring Expression Language (SpEL) support +- Removed `UseCloudHosting` (impossible to reliably detect bound ports in all cases, while Cloud Foundry usually [^1] sets the port automatically) +- Greater flexibility in using Bootstrap logger, bugfixes +- Certificates are no longer read from OS-specific store, which proved to not work reliably (store paths in configuration instead) + +### NuGet Package changes + +| Source | Change | Replacement | Notes | +| ---------------------------- | ------- | ---------------------------- | ---------------------------------------------------------- | +| Steeltoe.Common.Abstractions | Moved | Steeltoe.Common package | | +| Steeltoe.Common.Certificates | Added | | Support for handling X509 certificates | +| Steeltoe.Common.Expression | Removed | None | Existed for SpEL support, which has been removed | +| Steeltoe.Common.Kubernetes | Removed | None | | +| Steeltoe.Common.Logging | Added | | Provides `BootstrapLoggerFactory` | +| Steeltoe.Common.Retry | Removed | None | Existed for Messaging support, which has been removed | +| Steeltoe.Common.Security | Moved | Steeltoe.Common.Certificates | | +| Steeltoe.Common.Utils | Removed | None | Contained internal helpers not designed for external usage | + +### API changes + +| Source | Kind | Package | Change | Replacement | Notes | +| ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | ------------------------------ | --------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | +| `Microsoft.Extensions.DependencyInjection.ConfigurationServiceInstanceProviderServiceCollectionExtensions.AddConfigurationDiscoveryClient` | Extension method | Steeltoe.Common [Abstractions] | Moved | Steeltoe.Discovery.Configuration package | | +| `Steeltoe.Common.ApplicationInstanceInfo` | Type | Steeltoe.Common [Abstractions] | Members removed | None | Removed members that only apply to Cloud Foundry | +| `Steeltoe.Common.Attributes` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Dynamically loading custom types for connectors/discovery is no longer possible | +| `Steeltoe.Common.Availability` | Namespace | Steeltoe.Common [Abstractions] | Moved | Steeltoe.Management.Endpoint package | | +| `Steeltoe.Common.Availability.AvailabilityHealthContributor` | Type | Steeltoe.Common [Abstractions] | Removed | None | Made internal | +| `Steeltoe.Common.Availability.LivenessHealthContributor` | Type | Steeltoe.Common [Abstractions] | Removed | None | Made internal | +| `Steeltoe.Common.Availability.ReadinessHealthContributor` | Type | Steeltoe.Common [Abstractions] | Removed | None | Made internal | +| `Steeltoe.Common.CasingConventions.EnumExtensions.ToSnakeCaseString` | Extension method | Steeltoe.Common | Added | | Use to convert between .NET and Java enum member naming styles | +| `Steeltoe.Common.CasingConventions.SnakeCaseAllCapsEnumMemberJsonConverter` | Type | Steeltoe.Common | Added | | Use to convert between .NET and Java enum member naming styles | +| `Steeltoe.Common.ConcurrentDictionaryExtensions.GetOrAddEx` | Extension method | Steeltoe.Common [Abstractions] | Removed | None | Existed to support components which have been removed | +| `Steeltoe.Common.Configuration.ConfigurationValuesHelper` | Type | Steeltoe.Common [Abstractions] | Removed | None | Refactored to use ASP.NET Options pattern instead | +| `Steeltoe.Common.Configuration.PropertyPlaceholderHelper` | Type | Steeltoe.Common [Abstractions] | Made internal | None | Placeholder substitution is handled in Steeltoe.Configuration.Placeholder package | +| `Steeltoe.Common.Contexts` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed for SpEL support, which has been removed | +| `Steeltoe.Common.Converter` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed for SpEL support, which has been removed | +| `Steeltoe.Common.Discovery` | Namespace | Steeltoe.Common [Abstractions] | Moved | Steeltoe.Discovery.HttpClients package | | +| `Steeltoe.Common.Discovery.ConfigurationServiceInstance` | Type | Steeltoe.Common [Abstractions] | Moved | Steeltoe.Discovery.Configuration package | | +| `Steeltoe.Common.Discovery.ConfigurationServiceInstanceProvider` | Type | Steeltoe.Common [Abstractions] | Moved | ConfigurationDiscoveryOptions in Steeltoe.Discovery.Configuration package | | +| `Steeltoe.Common.Discovery.IServiceInstanceProvider` | Type | Steeltoe.Common [Abstractions] | Moved | `Steeltoe.Common.Discovery.IDiscoveryClient` | | +| `Steeltoe.Common.Discovery.IServiceInstanceProviderExtensions` | Type | Steeltoe.Common [Abstractions] | Made internal | None | Caching is handled in Steeltoe.Discovery.HttpClients package | +| `Steeltoe.Common.Discovery.IServiceRegistry<>` | Type | Steeltoe.Common [Abstractions] | Removed | None | This abstraction is no longer needed | +| `Steeltoe.Common.Discovery.SerializableIServiceInstance` | Type | Steeltoe.Common [Abstractions] | Removed | `Steeltoe.Discovery.Configuration.ConfigurationServiceInstance` | | +| `Steeltoe.Common.Expression` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed for SpEL support, which has been removed | +| `Steeltoe.Common.Extensions.UriExtensions` | Type | Steeltoe.Common [Abstractions] | Made internal | None | Internally used to mask URIs in logs | +| `Steeltoe.Common.IApplicationInstanceInfo` | Type | Steeltoe.Common [Abstractions] | Members removed | Type-check for `CloudFoundryApplicationOptions` at runtime | Removed members that only apply to Cloud Foundry | +| `Steeltoe.Common.IApplicationTask.Name` | Property | Steeltoe.Common [Abstractions] | Removed | None | Specify task name during registration | +| `Steeltoe.Common.ICertificateSource` | Type | Steeltoe.Common [Abstractions] | Removed | `IServiceCollection.ConfigureCertificateOptions()` in Steeltoe.Common.Certificates package | Certificate paths are now stored in `IConfiguration` to detect changes | +| `Steeltoe.Common.IHttpClientHandlerProvider` | Type | Steeltoe.Common [Abstractions] | Removed | `HttpClientHandlerFactory` in Steeltoe.Common.Http package | Should use `HttpMessageHandler` pipeline in `HttpClientFactory` instead | +| `Steeltoe.Common.IServiceCollectionExtensions.RegisterDefaultApplicationInstanceInfo` | Extension method | Steeltoe.Common [Abstractions] | Renamed | `AddApplicationInstanceInfo` | | +| `Steeltoe.Common.IServiceProviderExtensions.GetApplicationInstanceInfo` | Extension method | Steeltoe.Common [Abstractions] | Removed | `IServiceProvider.GetRequiredService()` | Has become redundant | +| `Steeltoe.Common.Json.JsonIgnoreEmptyCollectionAttribute` | Type | Steeltoe.Common | Added | | Annotation to exclude a collection during JSON serialization when empty | +| `Steeltoe.Common.Json.JsonSerializerOptionsExtensions.AddJsonIgnoreEmptyCollection` | Extension method | Steeltoe.Common | Added | | Configures JsonSerializerOptions to exclude empty collections | +| `Steeltoe.Common.Lifecycle` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed for SpEL support, which has been removed | +| `Steeltoe.Common.LoadBalancer.ILoadBalancer` | Type | Steeltoe.Common [Abstractions] | Moved | `ILoadBalancer` in Steeltoe.Discovery.HttpClients package | | +| `Steeltoe.Common.Logging.IBoostrapLoggerFactory` | Type | Steeltoe.Common [Abstractions] | Removed | `BootstrapLoggerFactory.CreateConsole()` in Steeltoe.Common.Logging package | | +| `Steeltoe.Common.Net.DnsTools` | Type | Steeltoe.Common [Abstractions] | Made internal | None | Internally used to resolve host names and IP addresses | +| `Steeltoe.Common.Net.HostInfo` | Type | Steeltoe.Common [Abstractions] | Made internal | None | Internally used to resolve host names and IP addresses | +| `Steeltoe.Common.Net.InetUtils` | Type | Steeltoe.Common [Abstractions] | Made internal | None | Internally used to resolve host names and IP addresses | +| `Steeltoe.Common.Options.AbstractOptions` | Type | Steeltoe.Common [Abstractions] | Removed | None | Refactored to use ASP.NET Options pattern instead | +| `Steeltoe.Common.Options.CertificateOptions` | Type | Steeltoe.Common [Abstractions] | Moved | Steeltoe.Common.Certificates package | | +| `Steeltoe.Common.Order` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed to support components which have been removed | +| `Steeltoe.Common.Platform.IsFullFramework` | Property | Steeltoe.Common [Abstractions] | Removed | None | Support for .NET Framework is no longer available | +| `Steeltoe.Common.Platform.IsNetCore` | Property | Steeltoe.Common [Abstractions] | Removed | None | This enum member is no longer needed | +| `Steeltoe.Common.Reflection` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed to support Type Locators, which have been replaced with internal-only shims | +| `Steeltoe.Common.Retry` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed for Messaging support, which has been removed | +| `Steeltoe.Common.SecurityUtilities` | Type | Steeltoe.Common [Abstractions] | Removed | None | Internally used to sanitize line breaks in logs | +| `Steeltoe.Common.Services` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed to support components which have been removed | +| `Steeltoe.Common.SteeltoeComponent` | Type | Steeltoe.Common [Abstractions] | Removed | None | This enum is no longer needed | +| `Steeltoe.Common.Transaction` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed for Messaging support, which has been removed | +| `Steeltoe.Common.Util` | Namespace | Steeltoe.Common [Abstractions] | Removed | None | Existed to support components which have been removed | +| `Steeltoe.Common.Certificates.CertificateConfigurationExtensions.AddAppInstanceIdentityCertificate` | Extension method | Steeltoe.Common.Certificates | Added | | Register/generate identity certificate for Cloud Foundry authentication | +| `Steeltoe.Common.Certificates.CertificateOptions` | Type | Steeltoe.Common.Certificates | Added | | Provides access to loaded certificate using ASP.NET Options pattern | +| `Steeltoe.Common.Certificates.CertificateServiceCollectionExtensions.ConfigureCertificateOptions` | Extension method | Steeltoe.Common.Certificates | Added | | Bind named certificate from `IConfiguration` and monitor for changes | +| `Steeltoe.Common.Hosting.BootstrapLoggerHostedService` | Type | Steeltoe.Common.Hosting | Made internal | None | Moved to Steeltoe.Common.Logging package | +| `Steeltoe.Common.Hosting.HostBuilderExtensions.UseCloudHosting` | Extension method | Steeltoe.Common.Hosting | Removed | Specify ports explicitly [^1] | Feature dropped, impossible to reliably detect bound ports in all cases | +| `Microsoft.Extensions.DependencyInjection.LoadBalancerHttpClientBuilderExtensions.AddLoadBalancer` | Extension method | Steeltoe.Common.Http | Moved | `AddServiceDiscovery()` in Steeltoe.Discovery.HttpClients package | | +| `Microsoft.Extensions.DependencyInjection.LoadBalancerHttpClientBuilderExtensions.AddRandomLoadBalancer` | Extension method | Steeltoe.Common.Http | Moved | `AddServiceDiscovery()` in Steeltoe.Discovery.HttpClients package | | +| `Microsoft.Extensions.DependencyInjection.LoadBalancerHttpClientBuilderExtensions.AddRoundRobinLoadBalancer` | Extension method | Steeltoe.Common.Http | Moved | `AddServiceDiscovery()` in Steeltoe.Discovery.HttpClients package | | +| `Steeltoe.Common.Discovery.DiscoveryHttpClientHandler` | Type | Steeltoe.Common.Http | Removed | `DiscoveryHttpClientHandler` in Steeltoe.Discovery.HttpClients package | | +| `Steeltoe.Common.Discovery.DiscoveryHttpClientHandlerBase` | Type | Steeltoe.Common.Http | Removed | `DiscoveryHttpClientHandler` in Steeltoe.Discovery.HttpClients package | | +| `Steeltoe.Common.Http.ClientCertificateHttpHandler` | Type | Steeltoe.Common.Http | Removed | None | Rotating certificates in OS-level certificate store proved to be unreliable | +| `Steeltoe.Common.Http.ClientCertificateHttpHandlerProvider` | Type | Steeltoe.Common.Http | Removed | None | Refactored to internal `ClientCertificateHttpClientHandlerConfigurer` | +| `Steeltoe.Common.Http.Discovery.DiscoveryHttpClientBuilderExtensions.AddServiceDiscovery` | Extension method | Steeltoe.Common.Http | Moved | `AddServiceDiscovery()` in Steeltoe.Discovery.HttpClients package | | +| `Steeltoe.Common.Http.Discovery.DiscoveryHttpMessageHandler` | Type | Steeltoe.Common.Http | Removed | `DiscoveryHttpDelegatingHandler<>` in Steeltoe.Discovery.HttpClients package | | +| `Steeltoe.Common.Http.HttpClientHelper` | Type | Steeltoe.Common.Http | Removed | None | Refactored handling of client certificates | +| `Steeltoe.Common.Http.HttpClientPooling.HttpClientHandlerFactory` | Type | Steeltoe.Common.Http | Added | | Enables to mock request/response from tests | +| `Steeltoe.Common.Http.LoadBalancer.LoadBalancerDelegatingHandler` | Type | Steeltoe.Common.Http | Moved | `DiscoveryHttpDelegatingHandler<>` in Steeltoe.Discovery.HttpClients package | | +| `Steeltoe.Common.Http.LoadBalancer.LoadBalancerHttpClientHandler` | Type | Steeltoe.Common.Http | Moved | `DiscoveryHttpClientHandler` in Steeltoe.Discovery.HttpClients package | | +| `Steeltoe.Common.Http.Serialization.BoolStringJsonConverter` | Type | Steeltoe.Common.Http | Removed | None | Made internal, moved to Steeltoe.Discovery.Eureka package | +| `Steeltoe.Common.Http.Serialization.LongStringJsonConverter` | Type | Steeltoe.Common.Http | Removed | None | Made internal, moved to Steeltoe.Discovery.Eureka package | +| `Steeltoe.Common.Logging.BootstrapLoggerFactory` | Type | Steeltoe.Common.Logging | Added | | Writes startup logs to console before logging has initialized | +| `Steeltoe.Common.Logging.BootstrapLoggerServiceCollectionExtensions.UpgradeBootstrapLoggerFactory` | Extension method | Steeltoe.Common.Logging | Added | | Upgrades existing loggers once app has started | +| `Steeltoe.Common.Net.IMPR` | Type | Steeltoe.Common.Net | Removed | None | Renamed to internal type `IMultipleProviderRouter` (existed for testing only) | +| `Steeltoe.Common.Net.WindowsNetworkFileShare.GetLastError` | Method | Steeltoe.Common.Net | Removed | None | Now throws `IOException` on error | +| `Steeltoe.Common.Net.WindowsNetworkFileShare.NetResource` | Type | Steeltoe.Common.Net | Removed | None | Nested type used internally for P/Invoke, should not be public | +| `Steeltoe.Common.Net.WindowsNetworkFileShare.ResourceDisplaytype` | Type | Steeltoe.Common.Net | Removed | None | Nested type used internally for P/Invoke, should not be public | +| `Steeltoe.Common.Net.WindowsNetworkFileShare.ResourceScope` | Type | Steeltoe.Common.Net | Removed | None | Nested type used internally for P/Invoke, should not be public | +| `Steeltoe.Common.Net.WindowsNetworkFileShare.ResourceType` | Type | Steeltoe.Common.Net | Removed | None | Nested type used internally for P/Invoke, should not be public | +| `Steeltoe.Common.Security.CertificateProvider` | Type | Steeltoe.Common.Security | Removed | Store certificate paths in `IConfiguration` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Common.Security.CertificateRotationService` | Type | Steeltoe.Common.Security | Removed | None | Rotating certificates in OS-level certificate store proved to be unreliable | +| `Steeltoe.Common.Security.CertificateSource` | Type | Steeltoe.Common.Security | Removed | Store certificate paths in `IConfiguration` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Common.Security.ConfigurationExtensions.AddCertificateFile` | Extension method | Steeltoe.Common.Security | Removed | `CertificateServiceCollectionExtensions.ConfigureCertificateOptions()` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Common.Security.ConfigurationExtensions.AddPemFiles` | Extension method | Steeltoe.Common.Security | Removed | `CertificateServiceCollectionExtensions.ConfigureCertificateOptions()` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Common.Security.ConfigureCertificateOptions` | Type | Steeltoe.Common.Security | Removed | Store certificate paths in `IConfiguration` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Common.Security.ICertificateRotationService` | Type | Steeltoe.Common.Security | Removed | None | Rotating certificates in OS-level certificate store proved to be unreliable | +| `Steeltoe.Common.Security.LocalCertificateWriter` | Type | Steeltoe.Common.Security | Removed | `CertificateConfigurationExtensions.AddAppInstanceIdentityCertificate()` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Common.Security.PemCertificateProvider` | Type | Steeltoe.Common.Security | Removed | Store certificate paths in `IConfiguration` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Common.Security.PemCertificateSource` | Type | Steeltoe.Common.Security | Removed | Store certificate paths in `IConfiguration` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Common.Security.PemConfigureCertificateOptions` | Type | Steeltoe.Common.Security | Removed | Store certificate paths in `IConfiguration` | Refactored to use ASP.NET Options pattern | + +[^1]: When using the binary buildpack, specify port bindings in an [environment variable](https://learn.microsoft.com/aspnet/core/fundamentals/servers/kestrel/endpoints#specify-ports-only) or on the command-line: `--urls=http://0.0.0.0:%PORT%`. + +### Notable PRs + +- https://github.com/SteeltoeOSS/Steeltoe/pull/1342 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1334 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1330 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1327 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1321 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1306 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1247 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1246 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1080 + +## Configuration + +### Behavior changes + +- Placeholder substitution changed internally (wrapping and taking ownership of sources), should be added as late as possible +- To improve performance, Config Server provider doesn't substitute placeholders by default anymore + - Call `AddPlaceholderResolver()` *before* `AddConfigServer()` to substitute info to connect to Config Server + - Call `AddPlaceholderResolver()` *after* `AddConfigServer()` to substitute placeholders in settings from all providers including Config Server + - Call `AddPlaceholderResolver()` *before and after* `AddConfigServer()` to substitute placeholders in both sources +- Added trace-level logging in placeholder provider to diagnose substitution +- New configuration provider to decrypt settings in Config Server (should be added as late as possible) +- Reduced noise in Config Server logging +- Universal configuration of client certificates, using ASP.NET Options pattern (named, with fallback to default) +- Added support for reading from [Application Configuration Service for VMware Tanzu](https://techdocs.broadcom.com/us/en/vmware-tanzu/standalone-components/application-configuration-service-for-tanzu/2-4/app-config-service/overview.html) on Kubernetes +- Improved support for ASP.NET Options pattern, responding to configuration changes at runtime +- Removed configuration provider that directly interacts with the Kubernetes API + +### NuGet Package changes + +| Steeltoe.Extensions.Configuration.Abstractions | Renamed | Steeltoe.Configuration.Abstractions | | +| ----------------------------------------------------------- | ------- | ------------------------------------------------- | ----------------------------------------------- | +| Steeltoe.Extensions.Configuration.CloudFoundryBase | Renamed | Steeltoe.Configuration.CloudFoundry | | +| Steeltoe.Extensions.Configuration.CloudFoundryCore | Renamed | Steeltoe.Configuration.CloudFoundry | | +| Steeltoe.Extensions.Configuration.ConfigServerBase | Renamed | Steeltoe.Configuration.ConfigServer | | +| Steeltoe.Extensions.Configuration.ConfigServerCore | Renamed | Steeltoe.Configuration.ConfigServer | | +| Steeltoe.Configuration.Encryption | Added | | Provides decryption of `IConfiguration` entries | +| Steeltoe.Extensions.Configuration.KubernetesBase | Removed | None | | +| Steeltoe.Extensions.Configuration.KubernetesCore | Removed | None | | +| Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding | Renamed | Steeltoe.Configuration.Kubernetes.ServiceBindings | | +| Steeltoe.Extensions.Configuration.PlaceholderBase | Renamed | Steeltoe.Configuration.Placeholder | | +| Steeltoe.Extensions.Configuration.PlaceholderCore | Renamed | Steeltoe.Configuration.Placeholder | | +| Steeltoe.Extensions.Configuration.RandomValueBase | Renamed | Steeltoe.Configuration.RandomValue | | +| Steeltoe.Extensions.Configuration.RandomValueCore | Renamed | Steeltoe.Configuration.RandomValue | | +| Steeltoe.Extensions.Configuration.SpringBootBase | Renamed | Steeltoe.Configuration.SpringBoot | | +| Steeltoe.Extensions.Configuration.SpringBootCore | Renamed | Steeltoe.Configuration.SpringBoot | | + +### API changes + +| Source | Kind | Package | Change | Replacement | Notes | +| ------------------------------------------------------------------------------------------------------------------------- | ---------------- | ---------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | +| `Steeltoe.Configuration.ICompositeConfigurationSource` | Type | Steeltoe.Configuration.Abstractions | Added | | Building block for configuration providers | +| `Steeltoe.Extensions.Configuration.AbstractServiceOptions` | Type | Steeltoe.Extensions.Configuration.Abstractions | Removed | `CloudFoundryService` in Steeltoe.Configuration.CloudFoundry package | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Extensions.Configuration.AbstractServiceOptions.GetInstancesOfType` | Method | Steeltoe.Extensions.Configuration.Abstractions | Moved | `CloudFoundryServicesOptions.GetServicesOfType` in Steeltoe.Configuration.CloudFoundry package | | +| `Steeltoe.Extensions.Configuration.AbstractServiceOptions.GetServicesList` | Method | Steeltoe.Extensions.Configuration.Abstractions | Moved | `CloudFoundryServicesOptions.GetAllServices` in Steeltoe.Configuration.CloudFoundry package | | +| `Steeltoe.Extensions.Configuration.Credential` | Type | Steeltoe.Extensions.Configuration.Abstractions | Moved | `CloudFoundryCredentials` in Steeltoe.Configuration.CloudFoundry package | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Extensions.Configuration.CredentialConverter` | Type | Steeltoe.Extensions.Configuration.Abstractions | Removed | None | Moved to internal type `CredentialsConverter` | +| `Steeltoe.Extensions.Configuration.IPlaceholderResolverProvider` | Type | Steeltoe.Extensions.Configuration.Abstractions | Removed | `PlaceholderConfigurationProvider` in Steeltoe.Configuration.Placeholder package | | +| `Steeltoe.Extensions.Configuration.IServiceCollectionExtensions.GetServicesInfo` | Extension method | Steeltoe.Extensions.Configuration.Abstractions | Removed | `IServiceProvider.GetRequiredService>()` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Extensions.Configuration.IServicesInfo` | Type | Steeltoe.Extensions.Configuration.Abstractions | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Extensions.Configuration.Service` | Type | Steeltoe.Extensions.Configuration.Abstractions | Moved | `CloudFoundryService` in Steeltoe.Configuration.CloudFoundry package | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Extensions.Configuration.ServicesOptions` | Type | Steeltoe.Extensions.Configuration.Abstractions | Moved | `CloudFoundryServicesOptions` in Steeltoe.Configuration.CloudFoundry package | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Configuration.CloudFoundry.CloudFoundryApplicationOptions.OrganizationId` | Property | Steeltoe.Configuration.CloudFoundry | Added | | | +| `Steeltoe.Configuration.CloudFoundry.CloudFoundryApplicationOptions.OrganizationName` | Property | Steeltoe.Configuration.CloudFoundry | Added | | | +| `Steeltoe.Configuration.CloudFoundry.CloudFoundryApplicationOptions.ProcessId` | Property | Steeltoe.Configuration.CloudFoundry | Added | | | +| `Steeltoe.Configuration.CloudFoundry.CloudFoundryApplicationOptions.ProcessType` | Property | Steeltoe.Configuration.CloudFoundry | Added | | | +| `Steeltoe.Configuration.CloudFoundry.CloudFoundryApplicationOptions.StartedAtTimestamp` | Property | Steeltoe.Configuration.CloudFoundry | Added | | | +| `Steeltoe.Configuration.CloudFoundry.CloudFoundryService` | Type | Steeltoe.Configuration.CloudFoundry | Added | | A service object in VCAP_SERVICES | +| `Steeltoe.Configuration.CloudFoundry.ServiceBindings.ConfigurationBuilderExtensions.AddCloudFoundryServiceBindings` | Extension method | Steeltoe.Configuration.CloudFoundry | Added | | Post-processor based API for reading VCAP_SERVICES into `IConfiguration` | +| `Steeltoe.Configuration.CloudFoundry.ServiceBindings.IServiceBindingsReader` | Type | Steeltoe.Configuration.CloudFoundry | Added | | Enables to provide VCAP_SERVICES from tests | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.Application_Uris` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `CloudFoundryApplicationOptions.Uris` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.Application_Version` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `CloudFoundryApplicationOptions.ApplicationVersion` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.CF_Api` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `CloudFoundryApplicationOptions.Api` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.DiskLimit` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Removed | `CloudFoundryApplicationOptions.Limits.Disk` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.FileDescriptorLimit` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Removed | `CloudFoundryApplicationOptions.Limits.FileDescriptor` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.Instance_Index` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `CloudFoundryApplicationOptions.InstanceIndex` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.Instance_IP` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `CloudFoundryApplicationOptions.InstanceIP` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.Internal_IP` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `CloudFoundryApplicationOptions.InternalIP` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.MemoryLimit` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Removed | `CloudFoundryApplicationOptions.Limits.Memory` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryApplicationOptions.Space_Id` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `CloudFoundryApplicationOptions.SpaceId` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryConfigurationProvider` | Type | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryConfigurationSource` | Type | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryEnvironmentSettingsReader` | Type | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Removed | None | Made internal, not designed for reuse/extensibility | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryMemorySettingsReader` | Type | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Removed | None | Made internal, used for unit tests only | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryServiceCollectionExtensions.ConfigureCloudFoundryOptions` | Extension method | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Removed | `CloudFoundryHostBuilderExtensions.AddCloudFoundryConfiguration` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.CloudFoundryServiceCollectionExtensions.ConfigureCloudFoundryService` | Extension method | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Removed | None | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.IServiceCollectionExtensions.RegisterCloudFoundryApplicationInstanceInfo` | Extension method | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `CloudFoundryServiceCollectionExtensions.AddCloudFoundryOptions` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.Limits` | Type | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `ApplicationLimits` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.Limits.Fds` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `ApplicationLimits.FileDescriptor` | | +| `Steeltoe.Extensions.Configuration.CloudFoundry.Limits.Mem` | Property | Steeltoe.Extensions.Configuration.CloudFoundry [Base/Core] | Renamed | `ApplicationLimits.Memory` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettings` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Renamed | `ConfigServerClientOptions` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettings.ClientCertificate` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | Store certificate paths in `IConfiguration` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettings.RawUri` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Uri` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Renamed | `ConfigServerClientOptions` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.Access_Token_Uri` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.AccessTokenUri` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.Client_Id` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.ClientId` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.Client_Secret` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.ClientSecret` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.DiscoveryEnabled` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Discovery.Enabled` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.DiscoveryServiceId` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Discovery.ServiceId` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.Env` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Environment` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.HealthEnabled` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Health.Enabled` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.HealthTimeToLive` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Health.TimeToLive` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.RetryAttempts` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Retry.MaxAttempts` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.RetryEnabled` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Retry.Enabled` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.RetryInitialInterval` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Retry.InitialInterval` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.RetryMaxInterval` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Retry.MaxInterval` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.RetryMultiplier` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.Retry.Multiplier` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerClientSettingsOptions.Validate_Certificates` | Property | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | `ConfigServerClientOptions.ValidateCertificates` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerConfigurationProvider` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | None | Made internal, not designed for reuse/extensibility | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerConfigurationSource` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | None | Made internal, not designed for reuse/extensibility | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerHealthContributor` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | None | Made internal, not designed for reuse/extensibility | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigServerHostedService.ConfigServerHostedService` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | None | Made internal, not designed for reuse/extensibility | +| `Steeltoe.Extensions.Configuration.ConfigServer.ConfigurationSettingsHelper` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Extensions.Configuration.ConfigServer.SpringCloudConfigDiscovery` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Renamed | `ConfigServerDiscoveryOptions` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.SpringCloudConfigHealth` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Renamed | `ConfigServerHealthOptions` | | +| `Steeltoe.Extensions.Configuration.ConfigServer.SpringCloudConfigRetry` | Type | Steeltoe.Extensions.Configuration.ConfigServer [Base/Core] | Renamed | `ConfigServerRetryOptions` | | +| `Steeltoe.Configuration.Encryption.Cryptography.DecryptionException` | Type | Steeltoe.Configuration.Encryption | Added | | Thrown when unable to decrypt | +| `Steeltoe.Configuration.Encryption.Cryptography.ITextDecryptor` | Type | Steeltoe.Configuration.Encryption | Added | | Provides pluggable decryption algorithms | +| `Steeltoe.Configuration.Encryption.DecryptionConfigurationBuilderExtensions.AddDecryption` | Extension method | Steeltoe.Configuration.Encryption | Added | | Activates decryption | +| `Steeltoe.Configuration.Kubernetes.ServiceBindings.IServiceBindingsReader` | Type | Steeltoe.Configuration.Kubernetes.ServiceBindings | Added | | Enables to provide bindings from tests | +| `Steeltoe.Extensions.Configuration.Placeholder.PlaceholderResolverConfigurationExtensions.AddPlaceholderResolver` | Extension method | Steeltoe.Extensions.Configuration.Placeholder [Base/Core] | Moved | `PlaceholderConfigurationBuilderExtensions.AddPlaceholderResolver` | | +| `Steeltoe.Extensions.Configuration.Placeholder.PlaceholderResolverExtensions.AddPlaceholderResolver` | Extension method | Steeltoe.Extensions.Configuration.Placeholder [Base/Core] | Removed | `IConfigurationBuilder.AddPlaceholderResolver()` | | +| `Steeltoe.Extensions.Configuration.Placeholder.PlaceholderResolverProvider` | Type | Steeltoe.Extensions.Configuration.Placeholder [Base/Core] | Removed | None | Renamed to internal `PlaceholderConfigurationProvider` | +| `Steeltoe.Extensions.Configuration.Placeholder.PlaceholderResolverSource` | Type | Steeltoe.Extensions.Configuration.Placeholder [Base/Core] | Removed | None | Renamed to internal `PlaceholderConfigurationSource` | +| `Steeltoe.Extensions.Configuration.RandomValue.RandomValueProvider` | Type | Steeltoe.Extensions.Configuration.RandomValue [Base/Core] | Removed | None | Made internal, not designed for reuse/extensibility | +| `Steeltoe.Extensions.Configuration.RandomValue.RandomValueSource` | Type | Steeltoe.Extensions.Configuration.RandomValue [Base/Core] | Removed | None | Made internal, not designed for reuse/extensibility | +| `Steeltoe.Extensions.Configuration.SpringBoot.SpringBootCmdProvider` | Type | Steeltoe.Extensions.Configuration.SpringBoot [Base/Core] | Removed | None | Renamed to internal `SpringBootCommandLineProvider` | +| `Steeltoe.Extensions.Configuration.SpringBoot.SpringBootCmdSource` | Type | Steeltoe.Extensions.Configuration.SpringBoot [Base/Core] | Removed | None | Renamed to internal `SpringBootCommandLineSource` | +| `Steeltoe.Extensions.Configuration.SpringBoot.SpringBootConfigurationBuilderExtensions.AddSpringBootCmd` | Extension method | Steeltoe.Extensions.Configuration.SpringBoot [Base/Core] | Renamed | `SpringBootConfigurationBuilderExtensions.AddSpringBootFromCommandLine` | | +| `Steeltoe.Extensions.Configuration.SpringBoot.SpringBootConfigurationBuilderExtensions.AddSpringBootEnv` | Extension method | Steeltoe.Extensions.Configuration.SpringBoot [Base/Core] | Renamed | `SpringBootConfigurationBuilderExtensions.AddSpringBootFromEnvironmentVariable` | | +| `Steeltoe.Extensions.Configuration.SpringBoot.SpringBootEnvProvider` | Type | Steeltoe.Extensions.Configuration.SpringBoot [Base/Core] | Removed | None | Renamed to internal `SpringBootEnvironmentVariableProvider` | +| `Steeltoe.Extensions.Configuration.SpringBoot.SpringBootEnvSource` | Type | Steeltoe.Extensions.Configuration.SpringBoot [Base/Core] | Removed | None | Renamed to internal `SpringBootEnvironmentVariableSource` | +| `Steeltoe.Extensions.Configuration.SpringBoot.SpringBootHostBuilderExtensions.AddSpringBootConfiguration` | Extension method | Steeltoe.Extensions.Configuration.SpringBoot [Base/Core] | Removed | `builder.Configuration.AddSpringBootFromCommandLine/EnvironmentVariable()` | Redundant | + +### Notable PRs + +- https://github.com/SteeltoeOSS/Steeltoe/pull/1360 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1355 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1339 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1306 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1277 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1276 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1243 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1228 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1196 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1183 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1179 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1149 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1099 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1097 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1008 + +### Documentation + +For more information, see the updated [Configuration documentation](../configuration/index.md) and +[Configuration samples](https://github.com/SteeltoeOSS/Samples/tree/main/Configuration). + +## Connectors + +### Behavior changes + +- Universal configuration and API shape for single/multiple (named) service bindings + - ADO.NET API: `builder.Add*()`, inject `ConnectorFactory` (driver-specific connection/client instances are no longer registered) + - EF Core API: must call `builder.Add*()` first. Example: `builder.AddMySql(); builder.Services.AddDbContext((serviceProvider, options) => options.UseMySql(serviceProvider));` + - The structure of configuration has changed severely to accommodate multiple named service bindings in a unified way +- Compatible with the latest versions of Tanzu, Cloud Foundry and .NET database drivers +- Added [Cloud Native Binding](https://github.com/servicebinding/spec) support (used by Tanzu Platform for Kubernetes, formerly TAP) for MongoDB, MySQL, PostgreSQL, RabbitMQ and Redis +- Leverage .NET connection strings (agnostic to the driver-specific parameters) via + [ASP.NET Options pattern](https://learn.microsoft.com/aspnet/core/fundamentals/configuration/options) +- Connection string from appsettings.json is preserved, replacing parameters from cloud bindings +- No more defaults for missing connection parameters that are required by drivers +- Provide injectable (named) `IOptions` that expose the merged connection string, respond to configuration changes at runtime +- Provide an injectable factory to obtain a (named) driver-specific connection/client instance (such as `NpgsqlConnection`, `IMongoClient`, `IConnectionMultiplexer`, etc) +- Automatic connection lifetime management, depending on driver-specific best practices +- Earlier limitations on health check registration with Entity Framework Core no longer apply +- Reflection-based code replaced by internal-only shims +- Various fixes in handling special characters in connection parameters +- Removed support for Oracle databases (community-contributed, no way to test it, no Cloud Foundry support) +- Further details at https://github.com/SteeltoeOSS/Steeltoe/issues/638#issuecomment-1584303824 + +### NuGet Package changes + +| Source | Change | Replacement | Notes | +| -------------------------------- | ------- | --------------------------------------- | ----------------------------------------------- | +| Steeltoe.Connector.Abstractions | Removed | None | Redundant after refactorings | +| Steeltoe.Connector.CloudFoundry | Removed | None | Redundant after refactorings | +| Steeltoe.Connector.ConnectorBase | Renamed | Steeltoe.Connectors | | +| Steeltoe.Connector.ConnectorCore | Renamed | Steeltoe.Connectors | | +| Steeltoe.Connector.EF6Core | Removed | | Entity Framework 6 is no longer being developed | +| Steeltoe.Connector.EFCore | Renamed | Steeltoe.Connectors.EntityFrameworkCore | | + +### API changes + +| Source | Kind | Package | Change | Replacement | Notes | +| -------------------------------------------------------------------------------------------------- | ---------------- | ---------------------------------------- | ------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | +| `Steeltoe.Connector.AbstractServiceConnectorOptions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Redundant after refactorings | +| `Steeltoe.Connector.ConnectionStringConfigurationSource` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use connection string in configuration | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.ConnectionStringManager` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `IServiceProvider.GetRequiredService>()` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.ConnectorException` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Catch `IOException`/`InvalidOperationException`/`ArgumentException`/`OperationCanceledException` | Standard .NET exceptions are thrown | +| `Steeltoe.Connector.ConnectorIOptions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Redundant after refactorings | +| `Steeltoe.Connector.CosmosDb.CosmosDbConnectionInfo` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use connection string in configuration | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.CosmosDb.CosmosDbConnectorFactory` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Registered in service container using `builder.AddCosmosDb()` | +| `Steeltoe.Connector.CosmosDb.CosmosDbConnectorOptions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `CosmosDbOptions` | Provides connection string | +| `Steeltoe.Connector.CosmosDb.CosmosDbProviderConfigurer` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.CosmosDb.CosmosDbReadOnlyConnectionInfo` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use connection string in configuration | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.CosmosDb.CosmosDbTypeLocator` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Type locators have been replaced with internal-only shims | +| `Steeltoe.Connector.Hystrix` | Namespace | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Hystrix (circuit breaker) support was removed | +| `Steeltoe.Connector.IConfigurationExtensions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Redundant after refactorings | +| `Steeltoe.Connector.MongoDb.MongoDbConnectionInfo` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use connection string in configuration | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.MongoDb.MongoDbConnectorFactory` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Registered in service container using `builder.AddMongoDb()` | +| `Steeltoe.Connector.MongoDb.MongoDbConnectorOptions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `MongoDbOptions` | Provides connection string | +| `Steeltoe.Connector.MongoDb.MongoDbHealthContributor` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorAddOptionsBuilder.EnableHealthChecks` | Made internal | +| `Steeltoe.Connector.MongoDb.MongoDbProviderConfigurer` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.MongoDb.MongoDbProviderServiceCollectionExtensions.AddMongoClient` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Moved | `IHostApplicationBuilder.AddMongoDb()` | | +| `Steeltoe.Connector.MongoDb.MongoDbTypeLocator` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Type locators have been replaced with internal-only shims | +| `Steeltoe.Connector.MySql.EF6` | Namespace | Steeltoe.Connector.Connector [Base/Core] | Removed | Use Steeltoe.Connectors.EntityFrameworkCore package | Entity Framework 6 is no longer being developed | +| `Steeltoe.Connector.MySql.MySqlConnectionInfo` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use connection string in configuration | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.MySql.MySqlProviderConfigurer` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.MySql.MySqlProviderConnectorFactory` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Registered in service container using `builder.AddMySql()` | +| `Steeltoe.Connector.MySql.MySqlProviderConnectorOptions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `MySqlOptions` | Provides connection string | +| `Steeltoe.Connector.MySql.MySqlProviderServiceCollectionExtensions.AddMySqlConnection` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Moved | `IHostApplicationBuilder.AddMySql()` | | +| `Steeltoe.Connector.MySql.MySqlServiceCollectionExtensions.AddMySqlHealthContributor` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorAddOptionsBuilder.EnableHealthChecks` | | +| `Steeltoe.Connector.MySql.MySqlTypeLocator` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Type locators have been replaced with internal-only shims | +| `Steeltoe.Connector.OAuth` | Namespace | Steeltoe.Connector.Connector [Base/Core] | Removed | Use Steeltoe.Security.Authentication packages | Redundant after refactorings | +| `Steeltoe.Connector.Oracle` | Namespace | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Support for Oracle databases was removed | +| `Steeltoe.Connector.PostgreSql.PostgresConnectionInfo` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use connection string in configuration | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.PostgreSql.PostgresProviderConfigurer` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.PostgreSql.PostgresProviderConnectorFactory` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Registered in service container using `builder.AddPostgreSql()` | +| `Steeltoe.Connector.PostgreSql.PostgresProviderConnectorOptions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `PostgreSqlOptions` | Provides connection string | +| `Steeltoe.Connector.PostgreSql.PostgresProviderServiceCollectionExtensions.AddPostgresConnection` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Moved | `IHostApplicationBuilder.AddPostgreSql()` | | +| `Steeltoe.Connector.PostgreSql.PostgreSqlTypeLocator` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Type locators have been replaced with internal-only shims | +| `Steeltoe.Connector.PostgreSql.PostgresServiceCollectionExtensions.AddPostgresHealthContributor` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorAddOptionsBuilder.EnableHealthChecks` | | +| `Steeltoe.Connector.RabbitMQ.RabbitMQConnectionInfo` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use connection string in configuration | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.RabbitMQ.RabbitMQHealthContributor` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorAddOptionsBuilder.EnableHealthChecks` | | +| `Steeltoe.Connector.RabbitMQ.RabbitMQProviderConfigurer` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.RabbitMQ.RabbitMQProviderConnectorFactory` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Registered in service container using `builder.AddRabbitMQ()` | +| `Steeltoe.Connector.RabbitMQ.RabbitMQProviderConnectorOptions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `RabbitMQOptions` | Provides connection string | +| `Steeltoe.Connector.RabbitMQ.RabbitMQProviderServiceCollectionExtensions.AddRabbitMQConnection` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Moved | `IHostApplicationBuilder.AddRabbitMQ()` | | +| `Steeltoe.Connector.RabbitMQ.RabbitMQTypeLocator` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Type locators have been replaced with internal-only shims | +| `Steeltoe.Connector.Redis.RedisCacheConfigurationExtensions.CreateRedisServiceConnectorFactory` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Registered in service container using `builder.AddRedis()` | +| `Steeltoe.Connector.Redis.RedisCacheConfigurer` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.Redis.RedisCacheConnectorOptions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `RedisOptions` | Provides connection string | +| `Steeltoe.Connector.Redis.RedisCacheServiceCollectionExtensions.AddDistributedRedisCache` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Moved | `IHostApplicationBuilder.AddRedis()` | Auto-adds `ConnectionMultiplexer` if Microsoft.Extensions.Caching.StackExchangeRedis package is referenced | +| `Steeltoe.Connector.Redis.RedisCacheServiceCollectionExtensions.AddRedisConnectionMultiplexer` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Moved | `IHostApplicationBuilder.AddRedis()` | Auto-adds `ConnectionMultiplexer` if Microsoft.Extensions.Caching.StackExchangeRedis package is referenced | +| `Steeltoe.Connector.Redis.RedisConnectionInfo` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use connection string in configuration | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.Redis.RedisHealthContributor` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorAddOptionsBuilder.EnableHealthChecks` | | +| `Steeltoe.Connector.Redis.RedisServiceConnectorFactory` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Registered in service container using `builder.AddRedis()` | +| `Steeltoe.Connector.Redis.RedisTypeLocator` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Type locators have been replaced with internal-only shims | +| `Steeltoe.Connector.RelationalDbHealthContributor` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Made internal, renamed to `RelationalDatabaseHealthContributor` | +| `Steeltoe.Connector.ServiceInfoCreator` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Loading connectors from assemblies was dropped | +| `Steeltoe.Connector.Services` | Namespace | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Loading connectors from assemblies was dropped | +| `Steeltoe.Connector.Services.SsoServiceInfoFactory` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use Steeltoe.Security.Authentication packages | Redundant after refactorings | +| `Steeltoe.Connector.SqlServer.EF6` | Namespace | Steeltoe.Connector.Connector [Base/Core] | Removed | Use Steeltoe.Connectors.EntityFrameworkCore package | Entity Framework 6 is no longer being developed | +| `Steeltoe.Connector.SqlServer.SqlServerConnectionInfo` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | Use connection string in configuration | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.SqlServer.SqlServerProviderConfigurer` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Connector.SqlServer.SqlServerProviderConnectorFactory` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorFactory` | Registered in service container using `builder.AddSqlServer()` | +| `Steeltoe.Connector.SqlServer.SqlServerProviderConnectorOptions` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | `SqlServerOptions` | Provides connection string | +| `Steeltoe.Connector.SqlServer.SqlServerProviderServiceCollectionExtensions.AddSqlServerConnection` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Moved | `IHostApplicationBuilder.AddSqlServer()` | | +| `Steeltoe.Connector.SqlServer.SqlServerServiceCollectionExtensions.AddSqlServerHealthContributor` | Extension method | Steeltoe.Connector.Connector [Base/Core] | Removed | `ConnectorAddOptionsBuilder.EnableHealthChecks` | | +| `Steeltoe.Connector.SqlServer.SqlServerTypeLocator` | Type | Steeltoe.Connector.Connector [Base/Core] | Removed | None | Type locators have been replaced with internal-only shims | +| `Steeltoe.Connectors.ConnectionStringOptions` | Type | Steeltoe.Connectors | Added | | Base type for driver-specific connection string | +| `Steeltoe.Connectors.Connector` | Type | Steeltoe.Connectors | Added | | Returned by `ConnectorFactory` | +| `Steeltoe.Connectors.ConnectorAddOptionsBuilder` | Type | Steeltoe.Connectors | Added | | Connector configuration settings | +| `Steeltoe.Connectors.ConnectorConfigureOptionsBuilder` | Type | Steeltoe.Connectors | Added | | Connector configuration settings | +| `Steeltoe.Connectors.ConnectorCreateConnection` | Type | Steeltoe.Connectors | Added | | Delegate to customize connecting | +| `Steeltoe.Connectors.ConnectorCreateHealthContributor` | Type | Steeltoe.Connectors | Added | | Delegate to create health contributor | +| `Steeltoe.Connectors.ConnectorFactory` | Type | Steeltoe.Connectors | Added | | Injectable, access connection string or driver-specific connection | +| `Steeltoe.Connectors.CosmosDb.CosmosDbConfigurationBuilderExtensions.ConfigureCosmosDb` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.CosmosDb.CosmosDbHostApplicationBuilderExtensions.AddCosmosDb` | Extension method | Steeltoe.Connectors | Added | | Activates the CosmosDB connector | +| `Steeltoe.Connectors.CosmosDb.CosmosDbOptions` | Type | Steeltoe.Connectors | Added | | Provides connection string and database name | +| `Steeltoe.Connectors.CosmosDb.CosmosDbServiceCollectionExtensions.AddCosmosDb` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.MongoDb.MongoDbConfigurationBuilderExtensions.ConfigureMongoDb` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.MongoDb.MongoDbHostApplicationBuilderExtensions.AddMongoDb` | Extension method | Steeltoe.Connectors | Added | | Activates the MongoDB connector | +| `Steeltoe.Connectors.MongoDb.MongoDbOptions` | Type | Steeltoe.Connectors | Added | | Provides connection string and database name | +| `Steeltoe.Connectors.MongoDb.MongoDbServiceCollectionExtensions.AddMongoDb` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.MySql.MySqlConfigurationBuilderExtensions.ConfigureMySql` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.MySql.MySqlHostApplicationBuilderExtensions.AddMySql` | Extension method | Steeltoe.Connectors | Added | | Activates the MySQL connector | +| `Steeltoe.Connectors.MySql.MySqlOptions` | Type | Steeltoe.Connectors | Added | | Provides connection string | +| `Steeltoe.Connectors.MySql.MySqlServiceCollectionExtensions.AddMySql` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.PostgreSql.PostgreSqlConfigurationBuilderExtensions.ConfigurePostgreSql` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.PostgreSql.PostgreSqlHostApplicationBuilderExtensions.AddPostgreSql` | Extension method | Steeltoe.Connectors | Added | | Activates the PostgreSQL connector | +| `Steeltoe.Connectors.PostgreSql.PostgreSqlOptions` | Type | Steeltoe.Connectors | Added | | Provides connection string | +| `Steeltoe.Connectors.PostgreSql.PostgreSqlServiceCollectionExtensions.AddPostgreSql` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.RabbitMQ.RabbitMQConfigurationBuilderExtensions.ConfigureRabbitMQ` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.RabbitMQ.RabbitMQHostApplicationBuilderExtensions.AddRabbitMQ` | Extension method | Steeltoe.Connectors | Added | | Activates the RabbitMQ connector | +| `Steeltoe.Connectors.RabbitMQ.RabbitMQOptions` | Type | Steeltoe.Connectors | Added | | Provides connection string | +| `Steeltoe.Connectors.RabbitMQ.RabbitMQServiceCollectionExtensions.AddRabbitMQ` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.Redis.RedisConfigurationBuilderExtensions.ConfigureRedis` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.Redis.RedisHostApplicationBuilderExtensions.AddRedis` | Extension method | Steeltoe.Connectors | Added | | Activates the Redis connector | +| `Steeltoe.Connectors.Redis.RedisOptions` | Type | Steeltoe.Connectors | Added | | Provides connection string | +| `Steeltoe.Connectors.Redis.RedisServiceCollectionExtensions.AddRedis` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.SqlServer.SqlServerConfigurationBuilderExtensions.ConfigureSqlServer` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connectors.SqlServer.SqlServerHostApplicationBuilderExtensions.AddSqlServer` | Extension method | Steeltoe.Connectors | Added | | Activates the Microsoft SQL Server connector | +| `Steeltoe.Connectors.SqlServer.SqlServerOptions` | Type | Steeltoe.Connectors | Added | | Provides connection string | +| `Steeltoe.Connectors.SqlServer.SqlServerServiceCollectionExtensions.AddSqlServer` | Extension method | Steeltoe.Connectors | Added | | To support legacy host builders | +| `Steeltoe.Connector.EFCore.EntityFrameworkCoreTypeLocator` | Type | Steeltoe.Connector.EFCore | Removed | | Type locators have been replaced with internal-only shims | +| `Steeltoe.Connector.MySql.EFCore.MySqlDbContextOptionsExtensions.UseMySql` | Extension method | Steeltoe.Connector.EFCore | Moved | `MySqlDbContextOptionsBuilderExtensions.UseMySql` | Takes an `IServiceProvider`, requires call to `builder.AddMySql()` first | +| `Steeltoe.Connector.MySql.EFCore.MySqlDbContextOptionsExtensions.UseMySql` | Extension method | Steeltoe.Connector.EFCore | Removed | | Redundant | +| `Steeltoe.Connector.Oracle.EFCore.OracleDbContextOptionsExtensions.UseOracle` | Extension method | Steeltoe.Connector.EFCore | Removed | | Support for Oracle databases was removed | +| `Steeltoe.Connector.PostgreSql.EFCore.PostgresDbContextOptionsExtensions.FindUseNpgsqlMethod` | Extension method | Steeltoe.Connector.EFCore | Removed | | Redundant after refactorings | +| `Steeltoe.Connector.PostgreSql.EFCore.PostgresDbContextOptionsExtensions.UseNpgsql` | Extension method | Steeltoe.Connector.EFCore | Moved | `PostgreSqlDbContextOptionsBuilderExtensions.UseNpgsql` | Takes an `IServiceProvider`, requires call to `builder.AddPostgreSql()` first | +| `Steeltoe.Connector.PostgreSql.EFCore.PostgresDbContextOptionsExtensions.UseNpgsql` | Extension method | Steeltoe.Connector.EFCore | Removed | | Redundant | +| `Steeltoe.Connector.SqlServer.EFCore.SqlServerDbContextOptionsExtensions.UseSqlServer` | Extension method | Steeltoe.Connector.EFCore | Moved | `SqlServerDbContextOptionsBuilderExtensions.UseSqlServer` | Takes an `IServiceProvider`, requires call to `builder.AddSqlServer()` first | +| `Steeltoe.Connector.SqlServer.EFCore.SqlServerDbContextOptionsExtensions.UseSqlServer` | Extension method | Steeltoe.Connector.EFCore | Removed | | Redundant | + +### Notable PRs + +- https://github.com/SteeltoeOSS/Steeltoe/pull/1325 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1172 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1143 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1139 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1131 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1128 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1124 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1121 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1119 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1117 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1112 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1110 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1089 + +### Documentation + +For more information, see the updated [Connectors documentation](../configuration/index.md) and +[Configuration samples](https://github.com/SteeltoeOSS/Samples/tree/main/Connectors). + +--- + +## Discovery + +### Behavior changes + +- Multiple discovery clients (one per type) can be active +- Simplified API: Use `IServiceCollection.Add*DiscoveryClient()` to register, `IHttpClientBuilder.AddServiceDiscovery()` to consume +- Refactored configuration to use ASP.NET Options pattern, responding to changes at runtime nearly everywhere +- Async all-the-way where possible +- More reliable cross-platform detection of local hostname and IP address +- Now supports global service discovery: `services.ConfigureHttpClientDefaults(builder => builder.AddServiceDiscovery())` +- Config Server discovery-first can now query Consul, Eureka and Configuration-based +- Improved detection of port bindings, including support for new ASP.NET [environment variables](https://learn.microsoft.com/aspnet/core/release-notes/aspnetcore-8.0#http_ports-and-https_ports-config-keys) +- HTTP handlers now depend on a load balancer, which delegates to multiple discovery clients +- Major improvements in documentation, samples cover more use cases +- Eureka: API reduced to what Steeltoe needs for service discovery (too many unanswered questions to provide generic client) +- Eureka: Added support for ASP.NET dynamic port bindings +- Eureka: Optimized communication to Eureka server +- Eureka: Made resilient to concurrent changes, fixing race conditions and lost updates +- Eureka: Made types returned from server immutable; use `EurekaApplicationInfoManager.UpdateInstance()` to change local instance +- Eureka: Server communication via `HttpClientFactory` (allows custom handlers, telemetry, respond to DNS changes, etc) +- Eureka: Client certificate watched in `IConfiguration`, can be shared with other `HttpClient`s +- Eureka: Health handler (to determine local instance status) now runs both contributors and ASP.NET health checks +- Eureka: Prefer secure port when both secure/non-secure are returned from Eureka +- Eureka: Support comma-separated list of multiple names in setting `Eureka:Instance:VipAddress` and `Eureka:Instance:SecureVipAddress` +- Eureka: Improved handling of the various registration methods on Cloud Foundry + +### NuGet Package changes + +| Source | Change | Replacement | Notes | +| -------------------------------- | ------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| Steeltoe.Discovery.Abstractions | Removed | Steeltoe.Common package | No longer needed (except for `IDiscoveryClient`, which moved to Steeltoe.Common package) | +| Steeltoe.Discovery.ClientBase | Removed | Steeltoe.Discovery.HttpClients, Steeltoe.Discovery.Configuration packages | Configuration-based discovery moved to Steeltoe.Discovery.Configuration package | +| Steeltoe.Discovery.ClientCore | Removed | Steeltoe.Discovery.HttpClients package | | +| Steeltoe.Discovery.Configuration | Added | | Provides a configuration-based discovery client | +| Steeltoe.Discovery.HttpClients | Added | | Provides consumption of `IDiscoveryClient`(s) in `HttpClient`/`HttpClientFactory` pipeline | +| Steeltoe.Discovery.Kubernetes | Removed | None | | + +### API changes + +| Source | Kind | Package | Change | Replacement | Notes | +| -------------------------------------------------------------------------------------------------------------- | ---------------- | ------------------------------------- | --------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | +| `Steeltoe.Discovery.Client.ConfigurationUrlHelpers` | Type | Steeltoe.Discovery.Client [Base/Core] | Removed | None | Similar logic moved to internal `ConfigurationExtensions.GetListenAddresses` | +| `Steeltoe.Discovery.Client.DiscoveryApplicationBuilderExtensions.UseDiscoveryClient` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IServiceCollection.Add\*DiscoveryClient()` extension method | | +| `Steeltoe.Discovery.Client.DiscoveryClientBuilder` | Type | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IServiceCollection.Add\*DiscoveryClient()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryClientStartupFilter` | Type | Steeltoe.Discovery.Client [Base/Core] | Removed | None | No longer needed | +| `Steeltoe.Discovery.Client.DiscoveryHostBuilderExtensions.AddDiscoveryClient` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IServiceCollection.Add\*DiscoveryClient()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryHostBuilderExtensions.AddServiceDiscovery` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IHttpClientBuilder.AddServiceDiscovery()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryServiceCollectionExtensions.AddDiscoveryClient` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IServiceCollection.Add\*DiscoveryClient()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryServiceCollectionExtensions.AddServiceDiscovery` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IHttpClientBuilder.AddServiceDiscovery()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryServiceCollectionExtensions.ApplicationLifecycle` | Type | Steeltoe.Discovery.Client [Base/Core] | Removed | None | No longer needed | +| `Steeltoe.Discovery.Client.DiscoveryServiceCollectionExtensions.GetNamedDiscoveryServiceInfo` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Inject `IEnumerable` | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryServiceCollectionExtensions.GetSingletonDiscoveryServiceInfo` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Inject `IEnumerable` | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryWebApplicationBuilderExtensions.AddDiscoveryClient` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IServiceCollection.Add\*DiscoveryClient()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryWebApplicationBuilderExtensions.AddServiceDiscovery` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IHttpClientBuilder.AddServiceDiscovery()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryWebHostBuilderExtensions.AddDiscoveryClient` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IServiceCollection.Add\*DiscoveryClient()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.DiscoveryWebHostBuilderExtensions.AddServiceDiscovery` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IHttpClientBuilder.AddServiceDiscovery()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.IDiscoveryClientExtension` | Type | Steeltoe.Discovery.Client [Base/Core] | Removed | Implement `IDiscoveryClient` directly, add it to service container | Refactored to simpler API | +| `Steeltoe.Discovery.Client.SimpleClients.ConfigurationDiscoveryClient` | Type | Steeltoe.Discovery.Client [Base/Core] | Moved | `ConfigurationDiscoveryClient` in Steeltoe.Discovery.Configuration package | | +| `Steeltoe.Discovery.Client.SimpleClients.ConfigurationDiscoveryClientBuilderExtensions.UseConfiguredInstances` | Extension method | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IServiceCollection.AddConfigurationDiscoveryClient()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.Client.SimpleClients.ConfigurationDiscoveryClientExtension` | Type | Steeltoe.Discovery.Client [Base/Core] | Removed | Call `IServiceCollection.AddConfigurationDiscoveryClient()` extension method | Refactored to simpler API | +| `Steeltoe.Discovery.DiscoveryClientAssemblyAttribute` | Type | Steeltoe.Discovery.Client [Base/Core] | Removed | None | Dynamically loading custom discovery clients is no longer possible | +| `Steeltoe.Discovery.Configuration.ConfigurationDiscoveryClient` | Type | Steeltoe.Discovery.Configuration | Added | | Reads service instances from configuration | +| `Steeltoe.Discovery.Configuration.ConfigurationDiscoveryOptions` | Type | Steeltoe.Discovery.Configuration | Added | | Options type for service instances in `IConfiguration` | +| `Steeltoe.Discovery.Configuration.ConfigurationServiceCollectionExtensions.AddConfigurationDiscoveryClient` | Extension method | Steeltoe.Discovery.Configuration | Added | | Activates configuration-based discovery client | +| `Steeltoe.Discovery.Configuration.ConfigurationServiceInstance` | Type | Steeltoe.Discovery.Configuration | Added | | Implements `IServiceInstance` for configuration-based discovery | +| `Steeltoe.Discovery.HttpClients.DiscoveryHttpClientBuilderExtensions.AddServiceDiscovery` | Extension method | Steeltoe.Discovery.HttpClients | Added | | Activates service discovery using the randomized load balancer | +| `Steeltoe.Discovery.HttpClients.DiscoveryHttpClientBuilderExtensions.AddServiceDiscovery` | Extension method | Steeltoe.Discovery.HttpClients | Added | | Activates service discovery using a custom ILoadBalancer | +| `Steeltoe.Discovery.HttpClients.DiscoveryHttpClientHandler` | Type | Steeltoe.Discovery.HttpClients | Added | | An `HttpClientHandler` (for `HttpClient`) that load-balances over service instances | +| `Steeltoe.Discovery.HttpClients.DiscoveryHttpDelegatingHandler` | Type | Steeltoe.Discovery.HttpClients | Added | | An `DelegatingHandler` (for `IHttpClientFactory`) that load-balances over service instances | +| `Steeltoe.Discovery.HttpClients.LoadBalancers.ILoadBalancer` | Type | Steeltoe.Discovery.HttpClients | Added | | Chooses a service instance obtained from discovery client(s) | +| `Steeltoe.Discovery.HttpClients.LoadBalancers.RandomLoadBalancer` | Type | Steeltoe.Discovery.HttpClients | Added | | Chooses a random service instance obtained from discovery client(s) | +| `Steeltoe.Discovery.HttpClients.LoadBalancers.RoundRobinLoadBalancer` | Type | Steeltoe.Discovery.HttpClients | Added | | Chooses a service instance obtained from discovery client(s) using round robin | +| `Steeltoe.Discovery.HttpClients.LoadBalancers.ServiceInstancesResolver` | Type | Steeltoe.Discovery.HttpClients | Added | | Used by load balancers to retrieve service instances from discovery clients | +| `Steeltoe.Discovery.Consul.ConsulClientFactory` | Type | Steeltoe.Discovery.Consul | Removed | Use Consul package directly | No longer needed | +| `Steeltoe.Discovery.Consul.ConsulDiscoveryClientBuilderExtensions.UseConsul` | Extension method | Steeltoe.Discovery.Consul | Removed | Call `IServiceCollection.AddConsulDiscoveryClient()` extension method | | +| `Steeltoe.Discovery.Consul.ConsulDiscoveryClientExtension` | Type | Steeltoe.Discovery.Consul | Removed | Call `IServiceCollection.AddConsulDiscoveryClient()` extension method | | +| `Steeltoe.Discovery.Consul.ConsulOptions` | Type | Steeltoe.Discovery.Consul | Moved | `Steeltoe.Discovery.Consul.Configuration.ConsulOptions` | | +| `Steeltoe.Discovery.Consul.ConsulPostConfigurer` | Type | Steeltoe.Discovery.Consul | Removed | None | Moved to internal type `PostConfigureConsulDiscoveryOptions` | +| `Steeltoe.Discovery.Consul.ConsulServiceCollectionExtensions.AddConsulDiscoveryClient` | Extension method | Steeltoe.Discovery.Consul | Added | | Activates the Consul discovery client | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryClient.Dispose` | Method | Steeltoe.Discovery.Consul | Removed | Call `ShutdownAsync()` before `IServiceProvider` is disposed | `ShutdownAsync()` is called by internal `DiscoveryClientHostedService` | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryClient.EnsureAssemblyIsLoaded` | Method | Steeltoe.Discovery.Consul | Removed | None | No longer needed | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions` | Type | Steeltoe.Discovery.Consul | Moved | `Steeltoe.Discovery.Consul.Configuration.ConsulDiscoveryOptions` | | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.ApplyConfigUrls` | Method | Steeltoe.Discovery.Consul | Removed | None | Refactored to internal logic, happens automatically based on settings | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.ApplyNetUtils` | Method | Steeltoe.Discovery.Consul | Removed | None | Refactored to internal logic, happens automatically based on settings | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.CacheTTL` | Property | Steeltoe.Discovery.Consul | Removed | Use caching provided by `ServiceInstancesResolver` | | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.IpAddress` | Property | Steeltoe.Discovery.Consul | Renamed | `ConsulDiscoveryOptions.IPAddress` | | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.IsHeartBeatEnabled` | Property | Steeltoe.Discovery.Consul | Removed | `ConsulDiscoveryOptions.Heartbeat.Enabled` | | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.IsRetryEnabled` | Property | Steeltoe.Discovery.Consul | Removed | `ConsulDiscoveryOptions.Retry.Enabled` | | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.NetUtils` | Property | Steeltoe.Discovery.Consul | Removed | None | OS-based network APIs are no longer pluggable | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.PreferAgentAddress` | Property | Steeltoe.Discovery.Consul | Removed | None | Undocumented and did not work | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.PreferIpAddress` | Property | Steeltoe.Discovery.Consul | Renamed | `ConsulDiscoveryOptions.PreferIPAddress` | | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.TagsAsMetadata` | Property | Steeltoe.Discovery.Consul | Removed | Configure `Tags` and `Metadata` directly | Redundant | +| `Steeltoe.Discovery.Consul.Discovery.ConsulDiscoveryOptions.UseNetUtils` | Property | Steeltoe.Discovery.Consul | Renamed | `ConsulDiscoveryOptions.UseNetworkInterfaces` | | +| `Steeltoe.Discovery.Consul.Discovery.ConsulHealthContributor` | Type | Steeltoe.Discovery.Consul | Removed | None | Made internal, not designed for reuse/extensibility | +| `Steeltoe.Discovery.Consul.Discovery.ConsulHeartbeatOptions` | Type | Steeltoe.Discovery.Consul | Moved | `Steeltoe.Discovery.Consul.Configuration.ConsulHeartbeatOptions` | | +| `Steeltoe.Discovery.Consul.Discovery.ConsulRetryOptions` | Type | Steeltoe.Discovery.Consul | Moved | `Steeltoe.Discovery.Consul.Configuration.ConsulRetryOptions` | | +| `Steeltoe.Discovery.Consul.Discovery.ConsulServiceInstance` | Type | Steeltoe.Discovery.Consul | Removed | None | Made internal | +| `Steeltoe.Discovery.Consul.Discovery.IConsulDiscoveryClient` | Type | Steeltoe.Discovery.Consul | Removed | `Steeltoe.Discovery.Consul.ConsulDiscoveryClient` | | +| `Steeltoe.Discovery.Consul.Discovery.IScheduler` | Type | Steeltoe.Discovery.Consul | Removed | None | Custom implementations are no longer possible | +| `Steeltoe.Discovery.Consul.Discovery.TtlScheduler` | Type | Steeltoe.Discovery.Consul | Removed | None | Made internal | +| `Steeltoe.Discovery.Consul.Registry.ConsulRegistration` | Type | Steeltoe.Discovery.Consul | Removed | None | Made internal | +| `Steeltoe.Discovery.Consul.Registry.ConsulServiceRegistrar` | Type | Steeltoe.Discovery.Consul | Removed | Use Consul package directly | Made internal | +| `Steeltoe.Discovery.Consul.Registry.ConsulServiceRegistry` | Type | Steeltoe.Discovery.Consul | Removed | Use Consul package directly | Made internal | +| `Steeltoe.Discovery.Consul.Registry.IConsulRegistration` | Type | Steeltoe.Discovery.Consul | Removed | None | Custom implementations are no longer possible | +| `Steeltoe.Discovery.Consul.Registry.IConsulServiceRegistrar` | Type | Steeltoe.Discovery.Consul | Removed | None | Custom implementations are no longer possible | +| `Steeltoe.Discovery.Consul.Registry.IConsulServiceRegistry` | Type | Steeltoe.Discovery.Consul | Removed | None | Custom implementations are no longer possible | +| `Steeltoe.Discovery.Consul.Registry.IServiceRegistrar` | Type | Steeltoe.Discovery.Consul | Removed | None | Custom implementations are no longer possible | +| `Steeltoe.Discovery.Consul.Util.ConsulServerUtils` | Type | Steeltoe.Discovery.Consul | Removed | None | Made internal | +| `Steeltoe.Discovery.Consul.Util.DateTimeConversions` | Type | Steeltoe.Discovery.Consul | Removed | None | Made internal | +| `Steeltoe.Discovery.Eureka.AppInfo.Application` | Type | Steeltoe.Discovery.Eureka | Renamed | `Steeltoe.Discovery.Eureka.AppInfo.ApplicationInfo` | | +| `Steeltoe.Discovery.Eureka.AppInfo.Application.Count` | Property | Steeltoe.Discovery.Eureka | Removed | `ApplicationInfo.Instances.Count` | Redundant | +| `Steeltoe.Discovery.Eureka.AppInfo.Application.GetInstance` | Method | Steeltoe.Discovery.Eureka | Removed | Find entry in `ApplicationInfo.Instances` | Made internal | +| `Steeltoe.Discovery.Eureka.AppInfo.Applications` | Type | Steeltoe.Discovery.Eureka | Renamed | `Steeltoe.Discovery.Eureka.AppInfo.ApplicationInfoCollection` | Now implements `IReadOnlyCollection` | +| `Steeltoe.Discovery.Eureka.AppInfo.Applications.GetInstancesBySecureVirtualHostName` | Method | Steeltoe.Discovery.Eureka | Removed | Enumerate via collection interface | Renamed to internal `GetInstancesBySecureVipAddress` | +| `Steeltoe.Discovery.Eureka.AppInfo.Applications.GetInstancesByVirtualHostName` | Method | Steeltoe.Discovery.Eureka | Removed | Enumerate via collection interface | Renamed to internal `GetInstancesByVipAddress` | +| `Steeltoe.Discovery.Eureka.AppInfo.Applications.GetRegisteredApplication` | Method | Steeltoe.Discovery.Eureka | Removed | Enumerate via collection interface | Made internal | +| `Steeltoe.Discovery.Eureka.AppInfo.Applications.GetRegisteredApplications` | Method | Steeltoe.Discovery.Eureka | Removed | Enumerate via collection interface | Redundant | +| `Steeltoe.Discovery.Eureka.AppInfo.DataCenterInfo` | Type | Steeltoe.Discovery.Eureka | Moved | `Steeltoe.Discovery.Eureka.Configuration.DataCenterInfo` | | +| `Steeltoe.Discovery.Eureka.AppInfo.IDataCenterInfo` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.Configuration.DataCenterInfo` | | +| `Steeltoe.Discovery.Eureka.AppInfo.InstanceInfo.Actiontype` | Property | Steeltoe.Discovery.Eureka | Renamed | `InstanceInfo.ActionType` | | +| `Steeltoe.Discovery.Eureka.AppInfo.InstanceInfo.AsgName` | Property | Steeltoe.Discovery.Eureka | Renamed | `InstanceInfo.AutoScalingGroupName` | | +| `Steeltoe.Discovery.Eureka.AppInfo.InstanceInfo.EffectiveStatus` | Property | Steeltoe.Discovery.Eureka | Added | | Calculated based on `Status` and `OverriddenStatus` | +| `Steeltoe.Discovery.Eureka.AppInfo.InstanceInfo.IpAddr` | Property | Steeltoe.Discovery.Eureka | Renamed | `InstanceInfo.IPAddress` | | +| `Steeltoe.Discovery.Eureka.AppInfo.InstanceInfo.IsUnsecurePortEnabled` | Property | Steeltoe.Discovery.Eureka | Renamed | `InstanceInfo.IsNonSecurePortEnabled` | | +| `Steeltoe.Discovery.Eureka.AppInfo.InstanceInfo.LastDirtyTimestamp` | Property | Steeltoe.Discovery.Eureka | Renamed | `InstanceInfo.LastDirtyTimeUtc` | Changed type from `long` to `DateTime` | +| `Steeltoe.Discovery.Eureka.AppInfo.InstanceInfo.LastUpdatedTimestamp` | Property | Steeltoe.Discovery.Eureka | Renamed | `InstanceInfo.LastUpdatedTimeUtc` | Changed type from `long` to `DateTime` | +| `Steeltoe.Discovery.Eureka.AppInfo.InstanceInfo.Port` | Property | Steeltoe.Discovery.Eureka | Renamed | `InstanceInfo.NonSecurePort` | | +| `Steeltoe.Discovery.Eureka.AppInfo.InstanceStatus` | Type | Steeltoe.Discovery.Eureka | Members changed | | Reordered enum members (0 = Unknown) | +| `Steeltoe.Discovery.Eureka.AppInfo.LeaseInfo.DurationInSecs` | Property | Steeltoe.Discovery.Eureka | Renamed | `LeaseInfo.Duration` | Changed type from `int` to `TimeSpan` | +| `Steeltoe.Discovery.Eureka.AppInfo.LeaseInfo.EvictionTimestamp` | Property | Steeltoe.Discovery.Eureka | Renamed | `LeaseInfo.EvictionTimeUtc` | Changed type from `long` to `DateTime` | +| `Steeltoe.Discovery.Eureka.AppInfo.LeaseInfo.LastRenewalTimestamp` | Property | Steeltoe.Discovery.Eureka | Renamed | `LeaseInfo.LastRenewalTimeUtc` | Changed type from `long` to `DateTime` | +| `Steeltoe.Discovery.Eureka.AppInfo.LeaseInfo.LastRenewalTimestampLegacy` | Property | Steeltoe.Discovery.Eureka | Removed | None | Legacy syntax handled internally | +| `Steeltoe.Discovery.Eureka.AppInfo.LeaseInfo.RegistrationTimestamp` | Property | Steeltoe.Discovery.Eureka | Renamed | `LeaseInfo.RegistrationTimeUtc` | Changed type from `long` to `DateTime` | +| `Steeltoe.Discovery.Eureka.AppInfo.LeaseInfo.RenewalIntervalInSecs` | Property | Steeltoe.Discovery.Eureka | Renamed | `LeaseInfo.RenewalInterval` | Changed type from `int` to `TimeSpan` | +| `Steeltoe.Discovery.Eureka.AppInfo.LeaseInfo.ServiceUpTimestamp` | Property | Steeltoe.Discovery.Eureka | Renamed | `LeaseInfo.ServiceUpTimeUtc` | Changed type from `long` to `DateTime` | +| `Steeltoe.Discovery.Eureka.ApplicationInfoManager` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.EurekaApplicationInfoManager` | | +| `Steeltoe.Discovery.Eureka.ApplicationsFetchedEventArgs` | Type | Steeltoe.Discovery.Eureka | Added | | List of apps for `EurekaDiscoveryClient.ApplicationsFetched` event | +| `Steeltoe.Discovery.Eureka.DiscoveryClient` | Type | Steeltoe.Discovery.Eureka | Removed | `EurekaDiscoveryClient` | | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.Applications` | Property | Steeltoe.Discovery.Eureka | Removed | Subscribe to `EurekaDiscoveryClient.ApplicationsFetched` event | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.FetchFullRegistryAsync` | Method | Steeltoe.Discovery.Eureka | Removed | Subscribe to `EurekaDiscoveryClient.ApplicationsFetched` event | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.FetchRegistryAsync` | Method | Steeltoe.Discovery.Eureka | Removed | Subscribe to `EurekaDiscoveryClient.ApplicationsFetched` event | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.FetchRegistryDeltaAsync` | Method | Steeltoe.Discovery.Eureka | Removed | Subscribe to `EurekaDiscoveryClient.ApplicationsFetched` event | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.GetApplication` | Method | Steeltoe.Discovery.Eureka | Removed | Subscribe to `EurekaDiscoveryClient.ApplicationsFetched` event | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.GetInstanceById` | Method | Steeltoe.Discovery.Eureka | Removed | Subscribe to `EurekaDiscoveryClient.ApplicationsFetched` event | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.GetInstanceRemoteStatus` | Method | Steeltoe.Discovery.Eureka | Removed | Subscribe to `EurekaDiscoveryClient.ApplicationsFetched` event | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.GetInstancesByVipAddress` | Method | Steeltoe.Discovery.Eureka | Removed | Subscribe to `EurekaDiscoveryClient.ApplicationsFetched` event | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.GetInstancesByVipAddressAndAppName` | Method | Steeltoe.Discovery.Eureka | Removed | Subscribe to `EurekaDiscoveryClient.ApplicationsFetched` event | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.GetNextServerFromEureka` | Method | Steeltoe.Discovery.Eureka | Removed | None | Refactored to internal `EurekaServiceUriStateManager` | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.HealthCheckHandler` | Property | Steeltoe.Discovery.Eureka | Removed | Implement `IHealthCheckHandler`, add it to service container | | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.HttpClient` | Property | Steeltoe.Discovery.Eureka | Removed | None | | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.Initialize` | Method | Steeltoe.Discovery.Eureka | Removed | None | No longer needed | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.InitializeAsync` | Method | Steeltoe.Discovery.Eureka | Removed | None | No longer needed | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.LastGoodDeltaRegistryFetchTimestamp` | Property | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.LastGoodFullRegistryFetchTimestamp` | Property | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.LastGoodHeartbeatTimestamp` | Property | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.LastGoodRegisterTimestamp` | Property | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.LastGoodRegistryFetchTimestamp` | Property | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.LastRemoteInstanceStatus` | Property | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.OnApplicationsChange` | Event | Steeltoe.Discovery.Eureka | Removed | `EurekaDiscoveryClient.ApplicationsFetched` | Was raised after every fetch, even if nothing changed | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.RefreshInstanceInfo` | Method | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.RegisterAsync` | Method | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.RegisterDirtyInstanceInfo` | Method | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.RenewAsync` | Method | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.StartTimer` | Method | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryClient.UnregisterAsync` | Method | Steeltoe.Discovery.Eureka | Removed | None | Made internal to guarantee correctness | +| `Steeltoe.Discovery.Eureka.DiscoveryManager` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient` | | +| `Steeltoe.Discovery.Eureka.EurekaApplicationInfoManager.Instance` | Property | Steeltoe.Discovery.Eureka | Added | | Gets immutable snapshot of the local service instance | +| `Steeltoe.Discovery.Eureka.EurekaApplicationInfoManager.InstanceConfig` | Property | Steeltoe.Discovery.Eureka | Removed | `IOptionsMonitor.CurrentValue` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Discovery.Eureka.EurekaApplicationInfoManager.UpdateInstance` | Method | Steeltoe.Discovery.Eureka | Added | | Enables to change local instance from code (synced with configuration) | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.Configuration.EurekaClientOptions` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.EurekaServerConnectTimeoutSeconds` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Server.ConnectTimeoutSeconds` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.EurekaServerRetryCount` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Server.RetryCount` | Default changed from 3 attempts to 2 retries (bugfix) | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.EurekaServerServiceUrls` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.EurekaServerServiceUrls` | Now supports comma-delimited list of URLs | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.HealthCheckEnabled` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Health.CheckEnabled` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.HealthContribEnabled` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Health.ContributorEnabled` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.HealthMonitoredApps` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Health.MonitoredApps` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.ProxyHost` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Server.ProxyHost` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.ProxyPassword` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Server.ProxyPassword` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.ProxyPort` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Server.ProxyPort` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.ProxyUserName` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Server.ProxyUserName` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.ShouldDisableDelta` | Property | Steeltoe.Discovery.Eureka | Moved | `EurekaClientOptions.IsFetchDeltaDisabled` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.ShouldGZipContent` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaClientOptions.Server.ShouldGZipContent` | | +| `Steeltoe.Discovery.Eureka.EurekaClientConfig.ShouldOnDemandUpdateStatusChange` | Property | Steeltoe.Discovery.Eureka | Removed | None | Always sends batch of local updates to Eureka server immediately | +| `Steeltoe.Discovery.Eureka.EurekaClientOptions` | Type | Steeltoe.Discovery.Eureka | Moved | `Steeltoe.Discovery.Eureka.Configuration.EurekaClientOptions` | | +| `Steeltoe.Discovery.Eureka.EurekaClientOptions.CacheTTL` | Property | Steeltoe.Discovery.Eureka | Removed | Use caching provided by `ServiceInstancesResolver` | | +| `Steeltoe.Discovery.Eureka.EurekaClientOptions.EurekaHealthConfig` | Type | Steeltoe.Discovery.Eureka | Moved | `Steeltoe.Discovery.Eureka.Configuration.EurekaHealthOptions` | | +| `Steeltoe.Discovery.Eureka.EurekaClientOptions.EurekaHealthConfig.Enabled` | Property | Steeltoe.Discovery.Eureka | Renamed | `EurekaHealthOptions.ContributorEnabled` | | +| `Steeltoe.Discovery.Eureka.EurekaClientOptions.EurekaServerConfig` | Type | Steeltoe.Discovery.Eureka | Moved | `Steeltoe.Discovery.Eureka.Configuration.EurekaServerOptions` | | +| `Steeltoe.Discovery.Eureka.EurekaClientOptions.ServiceUrl` | Property | Steeltoe.Discovery.Eureka | Renamed | `EurekaClientOptions.EurekaServerServiceUrls` | | +| `Steeltoe.Discovery.Eureka.EurekaClientOptions.Validate_Certificates` | Property | Steeltoe.Discovery.Eureka | Renamed | `EurekaClientOptions.ValidateCertificates` | | +| `Steeltoe.Discovery.Eureka.EurekaClientService` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient` | | +| `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient.ApplicationsFetched` | Event | Steeltoe.Discovery.Eureka | Added | | Resulting set (with delta applied), invoked from ThreadPool thread | +| `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient.ClientConfig` | Property | Steeltoe.Discovery.Eureka | Removed | `IOptionsMonitor.CurrentValue` | Refactored to use ASP.NET Options pattern | +| `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient.EnsureAssemblyIsLoaded` | Method | Steeltoe.Discovery.Eureka | Removed | None | No longer needed | +| `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient.GetInstances` | Method | Steeltoe.Discovery.Eureka | Renamed | `EurekaDiscoveryClient.GetInstancesAsync` | | +| `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient.GetServices` | Method | Steeltoe.Discovery.Eureka | Renamed | `EurekaDiscoveryClient.GetServiceIdsAsync` | | +| `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient.Services` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaDiscoveryClient.GetServiceIdsAsync` | | +| `Steeltoe.Discovery.Eureka.EurekaDiscoveryClientBuilderExtension` | Type | Steeltoe.Discovery.Eureka | Removed | Call `IServiceCollection.AddEurekaDiscoveryClient()` extension method | | +| `Steeltoe.Discovery.Eureka.EurekaDiscoveryClientExtension` | Type | Steeltoe.Discovery.Eureka | Removed | Call `IServiceCollection.AddEurekaDiscoveryClient()` extension method | | +| `Steeltoe.Discovery.Eureka.EurekaDiscoveryManager` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient` | | +| `Steeltoe.Discovery.Eureka.EurekaHealthCheckHandler` | Type | Steeltoe.Discovery.Eureka | Removed | Configure `EurekaClientOptions.Health.CheckEnabled` | Made internal | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.Configuration.EurekaInstanceOptions` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig.ApplyNetUtils` | Method | Steeltoe.Discovery.Eureka | Removed | None | Refactored to internal logic, happens automatically based on settings | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig.ASGName` | Property | Steeltoe.Discovery.Eureka | Removed | `EurekaInstanceOptions.AutoScalingGroupName` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig.DefaultAddressResolutionOrder` | Property | Steeltoe.Discovery.Eureka | Removed | None | Property was never used | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig.NetUtils` | Property | Steeltoe.Discovery.Eureka | Removed | None | OS-based network APIs are no longer pluggable | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig.PreferIpAddress` | Property | Steeltoe.Discovery.Eureka | Moved | `EurekaInstanceOptions.PreferIPAddress` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig.SecurePortEnabled` | Property | Steeltoe.Discovery.Eureka | Moved | `EurekaInstanceOptions.IsSecurePortEnabled` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig.SecureVirtualHostName` | Property | Steeltoe.Discovery.Eureka | Moved | `EurekaInstanceOptions.SecureVipAddress` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig.UseNetUtils` | Property | Steeltoe.Discovery.Eureka | Moved | `EurekaInstanceOptions.UseNetworkInterfaces` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceConfig.VirtualHostName` | Property | Steeltoe.Discovery.Eureka | Moved | `EurekaInstanceOptions.VipAddress` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceOptions` | Type | Steeltoe.Discovery.Eureka | Moved | `Steeltoe.Discovery.Eureka.Configuration.EurekaInstanceOptions` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceOptions.AppGroup` | Property | Steeltoe.Discovery.Eureka | Renamed | `EurekaInstanceOptions.AppGroupName` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceOptions.ApplyConfigUrls` | Method | Steeltoe.Discovery.Eureka | Removed | None | Refactored to internal logic, happens automatically based on settings | +| `Steeltoe.Discovery.Eureka.EurekaInstanceOptions.GetHostName` | Method | Steeltoe.Discovery.Eureka | Removed | None | Refactored to internal handling | +| `Steeltoe.Discovery.Eureka.EurekaInstanceOptions.InstanceEnabledOnInit` | Property | Steeltoe.Discovery.Eureka | Renamed | `EurekaInstanceOptions.IsInstanceEnabledOnInit` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceOptions.IpAddress` | Property | Steeltoe.Discovery.Eureka | Renamed | `EurekaInstanceOptions.IPAddress` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceOptions.NonSecurePortEnabled` | Property | Steeltoe.Discovery.Eureka | Renamed | `EurekaInstanceOptions.IsNonSecurePortEnabled` | | +| `Steeltoe.Discovery.Eureka.EurekaInstanceOptions.Port` | Property | Steeltoe.Discovery.Eureka | Renamed | `EurekaInstanceOptions.NonSecurePort` | | +| `Steeltoe.Discovery.Eureka.EurekaPostConfigurer` | Type | Steeltoe.Discovery.Eureka | Removed | None | Refactored to internal type `PostConfigureEurekaInstanceOptions` | +| `Steeltoe.Discovery.Eureka.EurekaServerHealthContributor` | Type | Steeltoe.Discovery.Eureka | Removed | Configure `EurekaClientOptions.Health.ContributorEnabled` | Made internal | +| `Steeltoe.Discovery.Eureka.EurekaServiceCollectionExtensions.AddEurekaDiscoveryClient` | Extension method | Steeltoe.Discovery.Eureka | Added | | Activates the Eureka discovery client | +| `Steeltoe.Discovery.Eureka.EurekaServiceInstance` | Type | Steeltoe.Discovery.Eureka | Removed | `IServiceInstance` | Made internal, implementation detail | +| `Steeltoe.Discovery.Eureka.EurekaServiceUriStateManager` | Type | Steeltoe.Discovery.Eureka | Added | | Load-balances over multiple Eureka servers | +| `Steeltoe.Discovery.Eureka.HealthCheckHandlerProvider` | Type | Steeltoe.Discovery.Eureka | Added | | Run contributors and ASP.NET health checks to determine local instance status | +| `Steeltoe.Discovery.Eureka.IEurekaClient` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient` | | +| `Steeltoe.Discovery.Eureka.IEurekaClientConfig` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.Configuration.EurekaClientOptions` | | +| `Steeltoe.Discovery.Eureka.IEurekaInstanceConfig` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.Configuration.EurekaInstanceOptions` | | +| `Steeltoe.Discovery.Eureka.ILookupService` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.EurekaDiscoveryClient` | | +| `Steeltoe.Discovery.Eureka.ScopedEurekaHealthCheckHandler` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.IHealthCheckHandler` | Moved to internal type `EurekaHealthCheckHandler` | +| `Steeltoe.Discovery.Eureka.StatusChangedArgs` | Type | Steeltoe.Discovery.Eureka | Removed | `EurekaApplicationInfoManager.UpdateInstance()` | | +| `Steeltoe.Discovery.Eureka.StatusChangedHandler` | Type | Steeltoe.Discovery.Eureka | Removed | `EurekaApplicationInfoManager.UpdateInstance()` | Refactored to internal `EurekaApplicationInfoManager.InstanceChanged` event | +| `Steeltoe.Discovery.Eureka.ThisServiceInstance` | Type | Steeltoe.Discovery.Eureka | Removed | None | No longer needed | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpClient` | Type | Steeltoe.Discovery.Eureka | Moved | `Steeltoe.Discovery.Eureka.EurekaClient` | | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpClient.DeleteStatusOverrideAsync` | Method | Steeltoe.Discovery.Eureka | Removed | None | Not needed for service discovery | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpClient.GetApplicationAsync` | Method | Steeltoe.Discovery.Eureka | Removed | None | Not needed for service discovery | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpClient.GetInstanceAsync` | Method | Steeltoe.Discovery.Eureka | Removed | None | Not needed for service discovery | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpClient.GetSecureVipAsync` | Method | Steeltoe.Discovery.Eureka | Removed | `EurekaClient.GetByVipAsync` | Identical implementation | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpClient.GetVipAsync` | Method | Steeltoe.Discovery.Eureka | Renamed | `EurekaClient.GetByVipAsync` | | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpClient.SendHeartBeatAsync` | Method | Steeltoe.Discovery.Eureka | Renamed | `EurekaClient.HeartbeatAsync` | | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpClient.Shutdown` | Method | Steeltoe.Discovery.Eureka | Renamed | `EurekaClient.DeregisterAsync` | | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpClient.StatusUpdateAsync` | Method | Steeltoe.Discovery.Eureka | Removed | None | Not needed for service discovery | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpResponse` | Type | Steeltoe.Discovery.Eureka | Removed | None | No longer needed | +| `Steeltoe.Discovery.Eureka.Transport.EurekaHttpResponse` | Type | Steeltoe.Discovery.Eureka | Removed | None | No longer needed | +| `Steeltoe.Discovery.Eureka.Transport.IEurekaHttpClient` | Type | Steeltoe.Discovery.Eureka | Removed | `Steeltoe.Discovery.Eureka.EurekaClient` | | +| `Steeltoe.Discovery.Eureka.Util.DateTimeConversions` | Type | Steeltoe.Discovery.Eureka | Removed | None | Made internal | + +### Notable PRs + +- https://github.com/SteeltoeOSS/Steeltoe/pull/1372 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1350 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1308 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1301 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1300 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1299 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1292 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1280 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1247 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1167 + +### Documentation + +For more information, see the updated [Discovery documentation](../discovery/index.md) and +[Discovery samples](https://github.com/SteeltoeOSS/Samples/tree/main/Discovery). + +## Logging + +### Behavior changes + +- Simplified API: `builder.Logging.AddDynamicSerilog()` +- Monitors and adapts to changes in `IConfiguration` (restores to changed minimum level after reset) +- Optimized for performance: faster updates, uses less memory +- Improved reliability: no more stale reads, race conditions and lost updates +- Fix default minimum log level to be Information instead of None +- Fix category name comparisons to be case-sensitive +- Fix namespace matching in categories: "Ab" is not a descendant of "A" +- Fix broken reset of levels when changed earlier (should revert to configured instead of default) +- Fix mismatches between the levels returned vs. the levels truly active in `ILoggers` +- Fix crash with latest version of Spring Boot Admin +- Fixed: console-specific rules should win over global rules in `appsettings.json` +- Serilog: fix crash when no default category is configured +- Serilog: Configured overrides were ignored when no default level was configured + +### NuGet Package changes + +| Source | Kind | Package | Change | Replacement | Notes | +| ---------------------------------------------- | ------- | ------- | ------- | ------------------------------- | ----- | +| Steeltoe.Extensions.Logging.Abstractions | Package | | Renamed | Steeltoe.Logging.Abstractions | | +| Steeltoe.Extensions.Logging.DynamicLogger | Package | | Renamed | Steeltoe.Logging.DynamicConsole | | +| Steeltoe.Extensions.Logging.DynamicSerilogBase | Package | | Renamed | Steeltoe.Logging.DynamicSerilog | | +| Steeltoe.Extensions.Logging.DynamicSerilogCore | Package | | Renamed | Steeltoe.Logging.DynamicSerilog | | + +### API changes + +| Source | Kind | Package | Change | Replacement | Notes | +| ----------------------------------------------------------------------------------------------------- | ---------------- | ------------------------------------------------------ | ------- | -------------------------------------------------------------- | ------------------------------------------------------------------- | +| `Steeltoe.Extensions.Logging.DynamicLoggerConfiguration` | Type | Steeltoe.Extensions.Logging.Abstractions | Renamed | `Steeltoe.Logging.DynamicLoggerState` | Represents logger state, is unrelated to `IConfiguration` | +| `Steeltoe.Extensions.Logging.DynamicLoggerConfiguration.ConfiguredLevel` | Property | Steeltoe.Extensions.Logging.Abstractions | Renamed | `DynamicLoggerState.BackupMinLevel` | The minimum level before override | +| `Steeltoe.Extensions.Logging.DynamicLoggerConfiguration.EffectiveLevel` | Property | Steeltoe.Extensions.Logging.Abstractions | Renamed | `DynamicLoggerState.EffectiveMinLevel` | The active minimum level, taking overrides into account | +| `Steeltoe.Extensions.Logging.DynamicLoggerConfiguration.Name` | Property | Steeltoe.Extensions.Logging.Abstractions | Renamed | `DynamicLoggerState.CategoryName` | | +| `Steeltoe.Extensions.Logging.DynamicLoggerProviderBase` | Type | Steeltoe.Extensions.Logging.Abstractions | Renamed | `Steeltoe.Logging.DynamicLoggerProvider` | | +| `Steeltoe.Extensions.Logging.DynamicLoggerProviderBase.GetLoggerConfigurations` | Method | Steeltoe.Extensions.Logging.Abstractions | Renamed | `DynamicLoggerProvider.GetLogLevels` | | +| `Steeltoe.Extensions.Logging.IDynamicLoggerProvider.GetLoggerConfigurations` | Method | Steeltoe.Extensions.Logging.Abstractions | Renamed | `IDynamicLoggerProvider.GetLogLevels` | | +| `Steeltoe.Extensions.Logging.ILoggerConfiguration` | Type | Steeltoe.Extensions.Logging.Abstractions | Removed | `Steeltoe.Logging.DynamicLoggerState` | | +| `Steeltoe.Extensions.Logging.InitialLevels` | Type | Steeltoe.Extensions.Logging.Abstractions | Renamed | `Steeltoe.Logging.LogLevelsConfiguration` | | +| `Steeltoe.Extensions.Logging.MessageProcessingLogger.Delegate` | Property | Steeltoe.Extensions.Logging.Abstractions | Renamed | `MessageProcessingLogger.InnerLogger` | | +| `Steeltoe.Extensions.Logging.MessageProcessingLogger.Filter` | Property | Steeltoe.Extensions.Logging.Abstractions | Removed | None | Refactored to handle internally | +| `Steeltoe.Extensions.Logging.MessageProcessingLogger.Name` | Property | Steeltoe.Extensions.Logging.Abstractions | Removed | None | No longer needed | +| `Steeltoe.Extensions.Logging.MessageProcessingLogger.WriteMessage` | Method | Steeltoe.Extensions.Logging.Abstractions | Removed | None | Refactored to handle internally | +| `Steeltoe.Extensions.Logging.StructuredMessageProcessingLogger` | Type | Steeltoe.Extensions.Logging.Abstractions | Removed | `Steeltoe.Logging.MessageProcessingLogger` | No longer needed | +| `Steeltoe.Logging.DynamicLoggerProvider.CreateMessageProcessingLogger` | Method | Steeltoe.Logging.Abstractions | Added | | Provides creation of `MessageProcessingLogger` in derived types | +| `Steeltoe.Logging.DynamicLoggerProvider.GetFilter` | Method | Steeltoe.Logging.Abstractions | Added | | Provides access to filter callback in derived types | +| `Steeltoe.Logging.DynamicLoggerProvider.InnerLoggerProvider` | Property | Steeltoe.Logging.Abstractions | Added | | Provides access to wrapped ILogger in derived types | +| `Steeltoe.Logging.DynamicLoggerProvider.MessageProcessors` | Property | Steeltoe.Logging.Abstractions | Added | | Provides access to processors in derived types | +| `Steeltoe.Logging.DynamicLoggerProvider.RefreshConfiguration` | Method | Steeltoe.Logging.Abstractions | Added | | Applies changes from `IConfiguration` | +| `Steeltoe.Logging.IDynamicLoggerProvider.RefreshConfiguration` | Method | Steeltoe.Logging.Abstractions | Added | | Applies changes from `IConfiguration` | +| `Steeltoe.Logging.LoggerFilter` | Type | Steeltoe.Logging.Abstractions | Added | | Delegate to simplify signatures | +| `Steeltoe.Logging.MessageProcessingLogger.ChangeFilter` | Method | Steeltoe.Logging.Abstractions | Added | | Called by `DynamicLoggerProvider` when effective level changes | +| `Steeltoe.Logging.MessageProcessingLogger.MessageProcessors` | Property | Steeltoe.Logging.Abstractions | Added | | Provides access to processors in derived types | +| `Steeltoe.Extensions.Logging.DynamicConsoleLoggerProvider` | Type | Steeltoe.Extensions.Logging.DynamicLogger | Moved | `Steeltoe.Logging.DynamicConsole.DynamicConsoleLoggerProvider` | | +| `Steeltoe.Extensions.Logging.DynamicLoggerHostBuilderExtensions.AddDynamicLogging` | Extension method | Steeltoe.Extensions.Logging.DynamicLogger | Removed | `LoggingBuilderExtensions.AddDynamicConsole` | | +| `Steeltoe.Extensions.Logging.DynamicLoggingBuilder.AddDynamicConsole` | Extension method | Steeltoe.Extensions.Logging.DynamicLogger | Moved | `LoggingBuilderExtensions.AddDynamicConsole` | | +| `Steeltoe.Extensions.Logging.DynamicSerilog.ISerilogOptions` | Type | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | `Steeltoe.Logging.DynamicSerilog.SerilogOptions` | Redundant, there's only one Serilog product | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogDynamicLoggerFactory` | Type | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | `DynamicSerilogLoggerProvider` | No longer needed | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogDynamicProvider` | Type | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Renamed | `DynamicSerilogLoggerProvider` | | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogHostBuilderExtensions.AddDynamicSerilog` | Extension method | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | `ILoggingBuilder.AddDynamicSerilog()` | | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogHostBuilderExtensions.UseSerilogDynamicConsole` | Extension method | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | `ILoggingBuilder.AddDynamicSerilog()` | | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogLoggingBuilderExtensions.AddSerilogDynamicConsole` | Extension method | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | `ILoggingBuilder.AddDynamicSerilog()` | | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogOptions.ConfigPath` | Property | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | None | No longer needed | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogOptions.FullnameExclusions` | Property | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | None | No longer needed | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogOptions.SubloggerConfigKeyExclusions` | Property | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | None | No longer needed | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogWebApplicationBuilderExtensions.AddDynamicSerilog` | Extension method | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | `ILoggingBuilder.AddDynamicSerilog()` | | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogWebHostBuilderExtensions.AddDynamicSerilog` | Extension method | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | `ILoggingBuilder.AddDynamicSerilog()` | | +| `Steeltoe.Extensions.Logging.DynamicSerilog.SerilogWebHostBuilderExtensions.UseSerilogDynamicConsole` | Extension method | Steeltoe.Extensions.Logging.DynamicSerilog [Base/Core] | Removed | `ILoggingBuilder.AddDynamicSerilog()` | | +| `Steeltoe.Logging.DynamicSerilog.SerilogMessageProcessingLogger` | Type | Steeltoe.Logging.DynamicSerilog | Added | | Preserve structured logs with `IDynamicMessageProcessor` in Serilog | + +### Notable PRs + +- https://github.com/SteeltoeOSS/Steeltoe/pull/1468 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1403 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1216 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1024 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1064 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1038 +- https://github.com/SteeltoeOSS/Steeltoe/pull/991 + +### Documentation + +For more information, see the updated [Logging documentation](../logging/index.md). + +## Management + +### Behavior changes + +- Unified configuration for `/actuator` and `/cloudfoundryapplication` +- Reduced required code for using an actuator to a single `IServiceCollection` extension method (configures middleware by default) +- Cleaner extensibility model for third-party actuators +- Fail at startup when actuators are used on Cloud Foundry without security +- Improved security and redaction of sensitive data in responses and logs +- Actuators can be turned on/off or bound to different verbs at runtime via configuration +- Simplified content negotiation, updated all actuators to support latest Spring media type +- New actuator `/beans` that lists the contents of the .NET dependency container, including support for keyed services +- Update health checks and actuator to align with latest Spring, hide details by default, contributors can be turned on/off at runtime via configuration +- Update `/mappings` actuator to include endpoints from Minimal APIs, Razor Pages and Blazor, with richer metadata and improved compatibility with Spring +- Heap dumps are enabled by default in Cloud Foundry on Linux +- Improved Prometheus exporter that works with latest OpenTelemetry +- Various fixes for interoperability with latest Spring Boot Admin +- Unified `/traces` and `/httptraces` actuators to `/httpexchanges` to align with latest Spring +- WaveFront, Zipkin and Jaeger support was removed (use OpenTelemetry directly) +- Metrics endpoint was removed (use OpenTelemetry directly) +- Kubernetes actuator was removed + +### NuGet Package changes + +| Source | Change | Replacement | Notes | +| ------------------------------------- | ------- | ------------------------------ | ------------------------------------ | +| Steeltoe.Management.CloudFoundryCore | Moved | Steeltoe.Management.Endpoint | Contained the Cloud Foundry actuator | +| Steeltoe.Management.Diagnostics | Moved | Steeltoe.Management.Endpoint | Contained code for taking heap dumps | +| Steeltoe.Management.EndpointBase | Renamed | Steeltoe.Management.Endpoint | | +| Steeltoe.Management.EndpointCore | Renamed | Steeltoe.Management.Endpoint | | +| Steeltoe.Management.KubernetesCore | Removed | None | | +| Steeltoe.Management.OpenTelemetryBase | Removed | Steeltoe.Management.Prometheus | WaveFront exporter was removed | +| Steeltoe.Management.Prometheus | Added | | Provides the Prometheus actuator | +| Steeltoe.Management.TaskCore | Renamed | Steeltoe.Management.Tasks | | +| Steeltoe.Management.TracingBase | Renamed | Steeltoe.Management.Tracing | | +| Steeltoe.Management.TracingCore | Renamed | Steeltoe.Management.Tracing | | + +### API changes + +| Source | Kind | Package | Change | Replacement | Notes | +| ---------------------------------------------------------------------------------------------------------------------------- | ---------------- | ---------------------------------------- | ------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `Microsoft.Diagnostics.Runtime.Interop.IMAGE_FILE_MACHINE` | Type | Steeltoe.Management.Diagnostics | Removed | None | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddActuatorEndpointMapping` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | `Steeltoe.Management.Endpoint.ApplicationBuilderExtensions.UseActuatorEndpoints` | Only needed when setting up middleware manually | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddCloudFoundryActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddCloudFoundryActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddDbMigrationsActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddDbMigrationsActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddEnvActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddEnvironmentActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddHealthActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddHealthActuator()` with `.AddHealthContributor()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddHeapDumpActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddHeapDumpActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddHypermediaActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddHypermediaActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddInfoActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddInfoActuator()` with `.AddInfoContributor()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddLoggersActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddLoggersActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddMappingsActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddRouteMappingsActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddMetricsActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Metrics actuator has been removed | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddOpenTelemetryMetricsForSteeltoe` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | Use OpenTelemetry packages directly | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddPrometheusActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `AddPrometheusActuator` in Steeltoe.Management.Prometheus package | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddRefreshActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddRefreshActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddSpringBootAdminClient` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddSpringBootAdminClient()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddThreadDumpActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddThreadDumpActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.AddTraceActuatorServices` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddHttpExchangesActuator()` | | +| `Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.ConfigureSteeltoeMetrics` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | Use OpenTelemetry packages directly | | +| `Steeltoe.Common.Diagnostics.DiagnosticHelpers` | Type | Steeltoe.Management.Abstractions | Removed | None | No longer needed | +| `Steeltoe.Common.Diagnostics.DiagnosticObserver` | Type | Steeltoe.Management.Abstractions | Removed | None | Made internal, moved to Steeltoe.Management.Endpoint package | +| `Steeltoe.Common.Diagnostics.DiagnosticsManager` | Type | Steeltoe.Management.Abstractions | Removed | None | Made internal, moved to Steeltoe.Management.Endpoint package | +| `Steeltoe.Common.Diagnostics.IDiagnosticObserver` | Type | Steeltoe.Management.Abstractions | Removed | None | | +| `Steeltoe.Common.Diagnostics.IDiagnosticsManager` | Type | Steeltoe.Management.Abstractions | Removed | None | | +| `Steeltoe.Common.Diagnostics.IRuntimeDiagnosticSource` | Type | Steeltoe.Management.Abstractions | Removed | None | | +| `Steeltoe.Management.AbstractEndpoint` | Type | Steeltoe.Management.Abstractions | Moved | `IEndpointHandler<,>` in Steeltoe.Management.Endpoint package | | +| `Steeltoe.Management.AbstractEndpoint.Enabled` | Property | Steeltoe.Management.Abstractions | Removed | `EndpointOptions.Enabled` | | +| `Steeltoe.Management.AbstractEndpoint.Id` | Property | Steeltoe.Management.Abstractions | Removed | `EndpointOptions.Id` | | +| `Steeltoe.Management.AbstractEndpoint.Options` | Property | Steeltoe.Management.Abstractions | Removed | `EndpointMiddleware<,>.EndpointOptions` or inject `IOptionsMonitor` | | +| `Steeltoe.Management.AbstractEndpoint.options` | Field | Steeltoe.Management.Abstractions | Removed | `EndpointMiddleware<,>.EndpointOptions` or inject `IOptionsMonitor` | | +| `Steeltoe.Management.AbstractEndpoint.Path` | Property | Steeltoe.Management.Abstractions | Removed | `EndpointOptions.Path` | | +| `Steeltoe.Management.AbstractEndpoint<,>` | Type | Steeltoe.Management.Abstractions | Removed | `IEndpointHandler<,>` in Steeltoe.Management.Endpoint package | | +| `Steeltoe.Management.AbstractEndpoint<,>.Invoke` | Method | Steeltoe.Management.Abstractions | Removed | `IEndpointHandler<,>.InvokeAsync` | | +| `Steeltoe.Management.AbstractEndpoint<>` | Type | Steeltoe.Management.Abstractions | Removed | `IEndpointHandler<,>` in Steeltoe.Management.Endpoint package | | +| `Steeltoe.Management.AbstractEndpoint<>.Invoke` | Method | Steeltoe.Management.Abstractions | Removed | `IEndpointHandler<,>.InvokeAsync` | | +| `Steeltoe.Management.AbstractEndpointOptions` | Type | Steeltoe.Management.Abstractions | Renamed | `Steeltoe.Management.Configuration.EndpointOptions` | | +| `Steeltoe.Management.AbstractEndpointOptions._enabled` | Field | Steeltoe.Management.Abstractions | Removed | `EndpointOptions.Enabled` | | +| `Steeltoe.Management.AbstractEndpointOptions._path` | Field | Steeltoe.Management.Abstractions | Removed | `EndpointOptions.Path` | | +| `Steeltoe.Management.AbstractEndpointOptions._sensitive` | Field | Steeltoe.Management.Abstractions | Removed | None | Was never used | +| `Steeltoe.Management.AbstractEndpointOptions.DefaultEnabled` | Property | Steeltoe.Management.Abstractions | Removed | None, implicitly true | | +| `Steeltoe.Management.AbstractEndpointOptions.ExactMatch` | Property | Steeltoe.Management.Abstractions | Removed | `EndpointOptions.RequiresExactMatch()` | | +| `Steeltoe.Management.AbstractEndpointOptions.Global` | Property | Steeltoe.Management.Abstractions | Removed | Inject `IOptionsMonitor` | | +| `Steeltoe.Management.AbstractEndpointOptions.IsAccessAllowed` | Method | Steeltoe.Management.Abstractions | Removed | `EndpointOptions.RequiredPermissions` | | +| `Steeltoe.Management.CloudFoundry.CloudFoundryActuatorsStartupFilter` | Type | Steeltoe.Management.CloudFoundryCore | Removed | None | | +| `Steeltoe.Management.CloudFoundry.CloudFoundryHostBuilderExtensions.AddCloudFoundryActuators` | Extension method | Steeltoe.Management.CloudFoundryCore | Moved | `builder.Services.AddCloudFoundryActuator()` in Steeltoe.Management.Endpoint package | | +| `Steeltoe.Management.CloudFoundry.CloudFoundryServiceCollectionExtensions.AddCloudFoundryActuators` | Extension method | Steeltoe.Management.CloudFoundryCore | Moved | `builder.Services.AddCloudFoundryActuator()` in Steeltoe.Management.Endpoint package | | +| `Steeltoe.Management.Configuration.EndpointOptions.GetDefaultAllowedVerbs` | Method | Steeltoe.Management.Abstractions | Added | | Override to initialize `AllowedVerbs` default | +| `Steeltoe.Management.Endpoint.ActuatorMediaTypes` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Each actuator uses built-in media type | +| `Steeltoe.Management.Endpoint.ActuatorRouteBuilderExtensions.LookupMiddleware` | Method | Steeltoe.Management.Endpoint [Base/Core] | Removed | Inject `IEnumerable` | | +| `Steeltoe.Management.Endpoint.ActuatorRouteBuilderExtensions.Map` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `MapActuators()` | | +| `Steeltoe.Management.Endpoint.ActuatorRouteBuilderExtensions.MapAllActuators` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `MapActuators()` | | +| `Steeltoe.Management.Endpoint.Actuators.CloudFoundry.ICloudFoundryEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.DbMigrations.IDbMigrationsEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.Environment.IEnvironmentEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.Health.Availability.ApplicationAvailability` | Type | Steeltoe.Management.Endpoint | Added | | Moved from Steeltoe.Common package | +| `Steeltoe.Management.Endpoint.Actuators.Health.Availability.AvailabilityEventArgs` | Type | Steeltoe.Management.Endpoint | Added | | Moved from Steeltoe.Common package | +| `Steeltoe.Management.Endpoint.Actuators.Health.Availability.AvailabilityState` | Type | Steeltoe.Management.Endpoint | Added | | Moved from Steeltoe.Common package | +| `Steeltoe.Management.Endpoint.Actuators.Health.Availability.LivenessState` | Type | Steeltoe.Management.Endpoint | Added | | Moved from Steeltoe.Common package | +| `Steeltoe.Management.Endpoint.Actuators.Health.Availability.LivenessStateContributorOptions.Enabled` | Property | Steeltoe.Management.Endpoint | Added | | Enables to turn off via configuration | +| `Steeltoe.Management.Endpoint.Actuators.Health.Availability.ReadinessState` | Type | Steeltoe.Management.Endpoint | Added | | Moved from Steeltoe.Common package | +| `Steeltoe.Management.Endpoint.Actuators.Health.Availability.ReadinessStateContributorOptions.Enabled` | Property | Steeltoe.Management.Endpoint | Added | | Enables to turn off via configuration | +| `Steeltoe.Management.Endpoint.Actuators.Health.Contributors.DiskSpaceContributorOptions.Enabled` | Property | Steeltoe.Management.Endpoint | Added | | Enables to turn off via configuration | +| `Steeltoe.Management.Endpoint.Actuators.Health.HealthEndpointOptions.ShowComponents` | Property | Steeltoe.Management.Endpoint | Added | | Whether to show/hide contributors in response | +| `Steeltoe.Management.Endpoint.Actuators.Health.HealthEndpointRequest` | Type | Steeltoe.Management.Endpoint | Added | | Data about incoming actuator request | +| `Steeltoe.Management.Endpoint.Actuators.Health.HealthEndpointResponse.Components` | Property | Steeltoe.Management.Endpoint | Added | | List of health contributors in response | +| `Steeltoe.Management.Endpoint.Actuators.Health.HealthEndpointResponse.Exists` | Property | Steeltoe.Management.Endpoint | Added | | Used to indicate the request was invalid | +| `Steeltoe.Management.Endpoint.Actuators.Health.HealthGroupOptions.ShowComponents` | Property | Steeltoe.Management.Endpoint | Added | | Hide/show contributors in the group | +| `Steeltoe.Management.Endpoint.Actuators.Health.HealthGroupOptions.ShowDetails` | Property | Steeltoe.Management.Endpoint | Added | | Hide/show contributor details in the group | +| `Steeltoe.Management.Endpoint.Actuators.Health.IHealthEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.HeapDump.IHeapDumpEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.HttpExchanges.HttpExchangesEndpointOptions.RequestHeaders` | Property | Steeltoe.Management.Endpoint | Added | | Request header names to exclude from redaction | +| `Steeltoe.Management.Endpoint.Actuators.HttpExchanges.HttpExchangesEndpointOptions.ResponseHeaders` | Property | Steeltoe.Management.Endpoint | Added | | Response header names to exclude from redaction | +| `Steeltoe.Management.Endpoint.Actuators.HttpExchanges.HttpExchangesEndpointOptions.Reverse` | Property | Steeltoe.Management.Endpoint | Added | | Return most recent exchanges at the top | +| `Steeltoe.Management.Endpoint.Actuators.HttpExchanges.IHttpExchangesEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.Hypermedia.IHypermediaEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.Info.EndpointServiceCollectionExtensions.AddInfoContributor` | Extension method | Steeltoe.Management.Endpoint | Added | | Adds a contributor to info actuator | +| `Steeltoe.Management.Endpoint.Actuators.Info.IInfoContributor` | Type | Steeltoe.Management.Endpoint | Added | | Moved from Steeltoe.Management.Abstractions package | +| `Steeltoe.Management.Endpoint.Actuators.Info.IInfoEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.Info.InfoBuilder` | Type | Steeltoe.Management.Endpoint | Added | | Moved from Steeltoe.Management.Abstractions package | +| `Steeltoe.Management.Endpoint.Actuators.Loggers.ILoggersEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.Loggers.LoggerGroup` | Type | Steeltoe.Management.Endpoint | Added | | Group in `LoggersResponse` | +| `Steeltoe.Management.Endpoint.Actuators.Loggers.LoggersRequest.Type` | Property | Steeltoe.Management.Endpoint | Added | | Indicates actuator request type (get or change) | +| `Steeltoe.Management.Endpoint.Actuators.Loggers.LoggersRequestType` | Type | Steeltoe.Management.Endpoint | Added | | Indicates actuator request type (get or change) | +| `Steeltoe.Management.Endpoint.Actuators.Loggers.LoggersResponse` | Type | Steeltoe.Management.Endpoint | Added | | Data for outgoing actuator response | +| `Steeltoe.Management.Endpoint.Actuators.Refresh.IRefreshEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.IRouteMappingsEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.ResponseTypes.MediaTypeDescriptor` | Type | Steeltoe.Management.Endpoint | Added | | Used in response structure to mirror Spring | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.ResponseTypes.ParameterDescriptor` | Type | Steeltoe.Management.Endpoint | Added | | Used in response structure to mirror Spring | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.ResponseTypes.RouteConditionsDescriptor.Headers` | Property | Steeltoe.Management.Endpoint | Added | | Used in response structure to mirror Spring | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.ResponseTypes.RouteConditionsDescriptor.Parameters` | Property | Steeltoe.Management.Endpoint | Added | | Used in response structure to mirror Spring | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.ResponseTypes.RouteDetailsDescriptor` | Type | Steeltoe.Management.Endpoint | Added | | Used in response structure to mirror Spring | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.ResponseTypes.RouteDispatcherServlets` | Type | Steeltoe.Management.Endpoint | Added | | Used in response structure to mirror Spring | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.ResponseTypes.RouteHandlerDescriptor` | Type | Steeltoe.Management.Endpoint | Added | | Used in response structure to mirror Spring | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.ResponseTypes.RouteMappingContexts` | Type | Steeltoe.Management.Endpoint | Added | | Used in response structure to mirror Spring | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.ResponseTypes.RouteMappingsContainer` | Type | Steeltoe.Management.Endpoint | Added | | Used in response structure to mirror Spring | +| `Steeltoe.Management.Endpoint.Actuators.RouteMappings.RouteMappingsEndpointOptions.IncludeActuators` | Property | Steeltoe.Management.Endpoint | Added | | Whether actuator endpoints are included in the response | +| `Steeltoe.Management.Endpoint.Actuators.Services` | Namespace | Steeltoe.Management.Endpoint | Added | | Provides services actuator | +| `Steeltoe.Management.Endpoint.Actuators.Services.EndpointServiceCollectionExtensions.AddServicesActuator` | Extension method | Steeltoe.Management.Endpoint | Added | | Activates the services actuator | +| `Steeltoe.Management.Endpoint.Actuators.Services.IServicesEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.Actuators.Services.ServiceRegistration` | Type | Steeltoe.Management.Endpoint | Added | | Describes an entry in the D/I container | +| `Steeltoe.Management.Endpoint.Actuators.Services.ServicesEndpointOptions` | Type | Steeltoe.Management.Endpoint | Added | | Configuration options for services actuator | +| `Steeltoe.Management.Endpoint.Actuators.ThreadDump.IThreadDumpEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Enables custom implementation to execute actuator | +| `Steeltoe.Management.Endpoint.ActuatorServiceCollectionExtensions.AddAllActuators` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.All.EndpointServiceCollectionExtensions.AddAllActuators` | For custom CORS, call `services.ConfigureActuatorsCorsPolicy()` | +| `Steeltoe.Management.Endpoint.ActuatorServiceCollectionExtensions.RegisterEndpointOptions` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.Endpoint.AllActuatorsStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Moved to internal type `ConfigureActuatorsMiddlewareStartupFilter` | +| `Steeltoe.Management.Endpoint.ApplicationBuilderExtensions.UseActuatorsCorsPolicy` | Extension method | Steeltoe.Management.Endpoint | Added | | Only needed when setting up middleware manually | +| `Steeltoe.Management.Endpoint.ApplicationBuilderExtensions.UseManagementPort` | Extension method | Steeltoe.Management.Endpoint | Added | | Only needed when setting up middleware manually | +| `Steeltoe.Management.Endpoint.CloudFoundry` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.CloudFoundry` | | +| `Steeltoe.Management.Endpoint.CloudFoundry.CloudFoundryActuatorStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddCloudFoundryActuator()` | Redundant | +| `Steeltoe.Management.Endpoint.CloudFoundry.CloudFoundryEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `ICloudFoundryEndpointHandler` | Moved to internal type `CloudFoundryEndpointHandler` | +| `Steeltoe.Management.Endpoint.CloudFoundry.CloudFoundryEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddCloudFoundryActuator()` | Made internal | +| `Steeltoe.Management.Endpoint.CloudFoundry.CloudFoundryEndpointOptions.CloudFoundryApi` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `Api` | | +| `Steeltoe.Management.Endpoint.CloudFoundry.CloudFoundryManagementOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `CloudFoundryEndpointOptions`, `ManagementOptions` | | +| `Steeltoe.Management.Endpoint.CloudFoundry.CloudFoundrySecurityMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `EndpointApplicationBuilderExtensions.UseCloudFoundrySecurity()` | Made internal | +| `Steeltoe.Management.Endpoint.CloudFoundry.CloudFoundrySecurityStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `EndpointApplicationBuilderExtensions.UseCloudFoundrySecurity()` | | +| `Steeltoe.Management.Endpoint.CloudFoundry.ICloudFoundryEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `ICloudFoundryEndpointHandler` | | +| `Steeltoe.Management.Endpoint.CloudFoundry.ICloudFoundryOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `CloudFoundryEndpointOptions` | | +| `Steeltoe.Management.Endpoint.CloudFoundry.SecurityBase` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Moved to internal type `PermissionsProvider` | +| `Steeltoe.Management.Endpoint.CloudFoundry.SecurityResult` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.Configuration.ConfigureEndpointOptions` | Type | Steeltoe.Management.Endpoint | Added | | Derive when implementing custom actuator | +| `Steeltoe.Management.Endpoint.Configuration.IConfigureOptionsWithKey` | Type | Steeltoe.Management.Endpoint | Added | | Contract for loading options in custom actuator | +| `Steeltoe.Management.Endpoint.Configuration.ManagementOptions.SslEnabled` | Property | Steeltoe.Management.Endpoint | Added | | Whether `options.Port` applies to HTTP or HTTPS | +| `Steeltoe.Management.Endpoint.ContentNegotiation.ContentNegotiationExtensions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.Endpoint.CoreActuatorServiceCollectionExtensions` | Type | Steeltoe.Management.Endpoint | Added | | Building block to implement custom actuator | +| `Steeltoe.Management.Endpoint.DbMigrations` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.DbMigrations` | | +| `Steeltoe.Management.Endpoint.DbMigrations.DbMigrationsEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IDbMigrationsEndpointHandler` | Moved to internal type `DbMigrationsEndpointHandler` | +| `Steeltoe.Management.Endpoint.DbMigrations.DbMigrationsEndpoint.DbMigrationsEndpointHelper` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.Endpoint.DbMigrations.DbMigrationsEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddDbMigrationsActuator()` | Made internal | +| `Steeltoe.Management.Endpoint.DbMigrations.DbMigrationsEndpointOptions.KeysToSanitize` | Property | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Was never used | +| `Steeltoe.Management.Endpoint.DbMigrations.DbMigrationsStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddDbMigrationsActuator()` | | +| `Steeltoe.Management.Endpoint.DbMigrations.IDbMigrationsEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IDbMigrationsEndpointHandler` | | +| `Steeltoe.Management.Endpoint.DbMigrations.IDbMigrationsOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `DbMigrationsEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Diagnostics.DiagnosticServices` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Moved to internal type `...HttpExchanges.Diagnostics.DiagnosticsService` | +| `Steeltoe.Management.Endpoint.EndpointCollectionConventionBuilder` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.ConfigureActuatorEndpoints()` | | +| `Steeltoe.Management.Endpoint.EndPointExtensions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Moved to internal type `EndpointOptionsExtensions` | +| `Steeltoe.Management.Endpoint.Env` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.Environment` | | +| `Steeltoe.Management.Endpoint.Env.EndpointServiceCollectionExtensions.AddEnvActuator` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddEnvironmentActuator()` | | +| `Steeltoe.Management.Endpoint.Env.EnvEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IEnvironmentEndpointHandler` | Moved to internal type `EnvironmentEndpointHandler` | +| `Steeltoe.Management.Endpoint.Env.EnvEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddEnvironmentActuator()` | Made internal | +| `Steeltoe.Management.Endpoint.Env.EnvEndpointOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `EnvironmentEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Env.EnvironmentDescriptor` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `EnvironmentResponse` | | +| `Steeltoe.Management.Endpoint.Env.EnvStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddEnvironmentActuator()` | | +| `Steeltoe.Management.Endpoint.Env.GenericHostingEnvironment` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | No longer needed | +| `Steeltoe.Management.Endpoint.Env.IEnvEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IEnvironmentEndpointHandler` | | +| `Steeltoe.Management.Endpoint.Env.IEnvOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `EnvironmentEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Env.Sanitizer` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | Use `KeysToSanitize` in configuration | Moved to internal type `Sanitizer` | +| `Steeltoe.Management.Endpoint.Exposure` | Type | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Configuration.Exposure` | | +| `Steeltoe.Management.Endpoint.Health` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.Health` | | +| `Steeltoe.Management.Endpoint.Health.Contributor` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.Health.Contributors` | | +| `Steeltoe.Management.Endpoint.Health.Contributor.DiskSpaceContributor` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.Health.Contributor.PingHealthContributor` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.Health.DefaultHealthAggregator` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Moved to internal type `HealthAggregator` in Steeltoe.Common package | +| `Steeltoe.Management.Endpoint.Health.EndpointServiceCollectionExtensions.AddHealthActuator` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddHealthActuator()` | | +| `Steeltoe.Management.Endpoint.Health.EndpointServiceCollectionExtensions.AddHealthContributors` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Moved | `builder.Services.AddHealthContributor()` | | +| `Steeltoe.Management.Endpoint.Health.HealthCheckExtensions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Moved to internal type `HealthAggregator` in Steeltoe.Common package | +| `Steeltoe.Management.Endpoint.Health.HealthConverter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | No longer needed | +| `Steeltoe.Management.Endpoint.Health.HealthConverterV3` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | No longer needed | +| `Steeltoe.Management.Endpoint.Health.HealthEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IHealthEndpointHandler` | Moved to internal type `HealthEndpointHandler` | +| `Steeltoe.Management.Endpoint.Health.HealthEndpointCore` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IHealthEndpointHandler` | Moved to internal type `HealthEndpointHandler` | +| `Steeltoe.Management.Endpoint.Health.HealthEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddHealthActuator()` | Made internal | +| `Steeltoe.Management.Endpoint.Health.HealthRegistrationsAggregator` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | Inject `IHealthAggregator` | Moved to internal type `HealthAggregator` in Steeltoe.Common package | +| `Steeltoe.Management.Endpoint.Health.HealthStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddHealthActuator()` | | +| `Steeltoe.Management.Endpoint.Health.IHealthEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IHealthEndpointHandler` | | +| `Steeltoe.Management.Endpoint.Health.IHealthOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `HealthEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Health.IHealthRegistrationsAggregator` | Type | Steeltoe.Management.Endpoint [Base/Core] | Moved | `IHealthAggregator` in Steeltoe.Common package | | +| `Steeltoe.Management.Endpoint.Health.IServiceProviderExtensions.InitializeAvailability` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.Health.ShowDetails` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `Steeltoe.Management.Endpoint.Actuators.Health.ShowValues` | Numbers of constants have changed | +| `Steeltoe.Management.Endpoint.HeapDump` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.HeapDump` | | +| `Steeltoe.Management.Endpoint.HeapDump.HeapDumpEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IHeapDumpEndpointHandler` | Moved to internal type `HeapDumpEndpointHandler` | +| `Steeltoe.Management.Endpoint.HeapDump.HeapDumpEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddHeapDumpActuator()` | Made internal | +| `Steeltoe.Management.Endpoint.HeapDump.HeapDumper` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.HeapDump.HeapDumpStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddHeapDumpActuator()` | | +| `Steeltoe.Management.Endpoint.HeapDump.IHeapDumpEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IHeapDumpEndpointHandler` | | +| `Steeltoe.Management.Endpoint.HeapDump.IHeapDumper` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.HeapDump.IHeapDumpOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `HeapDumpEndpointOptions` | | +| `Steeltoe.Management.Endpoint.HeapDump.LinuxHeapDumper` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.Endpoint.Hypermedia` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.Hypermedia` | | +| `Steeltoe.Management.Endpoint.Hypermedia.ActuatorEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IHypermediaEndpointHandler` | Moved to internal type `HypermediaEndpointHandler` | +| `Steeltoe.Management.Endpoint.Hypermedia.ActuatorHypermediaEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddHypermediaActuator()` | Moved to internal type `HypermediaEndpointMiddlewar` | +| `Steeltoe.Management.Endpoint.Hypermedia.ActuatorManagementOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | Configure at key `Management:Endpoints:Actuator:Exposure` | | +| `Steeltoe.Management.Endpoint.Hypermedia.EndpointServiceCollectionExtensions.AddActuatorManagementOptions` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.Endpoint.Hypermedia.HypermediaService` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.Hypermedia.HypermediaStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddHypermediaActuator()` | | +| `Steeltoe.Management.Endpoint.Hypermedia.IActuatorEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IHypermediaEndpointHandler` | | +| `Steeltoe.Management.Endpoint.Hypermedia.IActuatorHypermediaOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `HypermediaEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Hypermedia.Links._links` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `Entries` | | +| `Steeltoe.Management.Endpoint.IEndpointHandler` | Type | Steeltoe.Management.Endpoint | Added | | Implement for custom actuator | +| `Steeltoe.Management.Endpoint.Info` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.Info` | | +| `Steeltoe.Management.Endpoint.Info.Contributor.AppSettingsInfoContributor` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.Info.Contributor.BuildInfoContributor` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.Info.Contributor.GitInfoContributor` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.Info.IInfoEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IInfoEndpointHandler` | | +| `Steeltoe.Management.Endpoint.Info.IInfoOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `InfoEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Info.InfoEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IInfoEndpointHandler` | Moved to internal type `InfoEndpointHandler` | +| `Steeltoe.Management.Endpoint.Info.InfoEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddInfoActuator()` | Made internal | +| `Steeltoe.Management.Endpoint.Info.InfoStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddInfoActuator()` | | +| `Steeltoe.Management.Endpoint.Loggers` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.Loggers` | | +| `Steeltoe.Management.Endpoint.Loggers.ILoggersEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `ILoggersEndpointHandler` | | +| `Steeltoe.Management.Endpoint.Loggers.ILoggersOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `LoggersEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Loggers.LoggerLevels.MapLogLevel` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.Loggers.LoggersChangeRequest` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `LoggersRequest` | | +| `Steeltoe.Management.Endpoint.Loggers.LoggersEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `ILoggersEndpointHandler` | Moved to internal type `LoggersEndpointHandler` | +| `Steeltoe.Management.Endpoint.Loggers.LoggersEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddLoggersActuator()` | Made internal | +| `Steeltoe.Management.Endpoint.Loggers.LoggersStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddLoggersActuator()` | | +| `Steeltoe.Management.Endpoint.ManagementEndpointOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Configuration.ManagementOptions` | | +| `Steeltoe.Management.Endpoint.ManagementEndpointOptions.EndpointOptions` | Property | Steeltoe.Management.Endpoint [Base/Core] | Removed | `EndpointMiddleware<,>.EndpointOptions` or inject `IOptionsMonitor` | | +| `Steeltoe.Management.Endpoint.ManagementEndpointOptions.Sensitive` | Property | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Was never used | +| `Steeltoe.Management.Endpoint.ManagementHostBuilderExtensions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | Use extension methods on `IServiceCollection` | Redundant | +| `Steeltoe.Management.Endpoint.ManagementPort.ManagementPortMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Made internal | +| `Steeltoe.Management.Endpoint.ManagementWebApplicationBuilderExtensions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | Use extension methods on `IServiceCollection` | Redundant | +| `Steeltoe.Management.Endpoint.ManagementWebHostBuilderExtensions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | Use extension methods on `IServiceCollection` | Redundant | +| `Steeltoe.Management.Endpoint.Mappings` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.RouteMappings` | | +| `Steeltoe.Management.Endpoint.Mappings.ApplicationMappings` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `RouteMappingsResponse` | | +| `Steeltoe.Management.Endpoint.Mappings.AspNetCoreRouteDetails` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `RouteConditionsDescriptor` | | +| `Steeltoe.Management.Endpoint.Mappings.AspNetCoreRouteDetails.HttpMethods` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `RouteConditionsDescriptor.Methods` | | +| `Steeltoe.Management.Endpoint.Mappings.AspNetCoreRouteDetails.RouteTemplate` | Property | Steeltoe.Management.Endpoint [Base/Core] | Removed | `RouteConditionsDescriptor.Patterns` | | +| `Steeltoe.Management.Endpoint.Mappings.ContextMappings` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `RouteMappingContext` | | +| `Steeltoe.Management.Endpoint.Mappings.EndpointServiceCollectionExtensions.AddMappingsActuator` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `AddRouteMappingsActuator` | | +| `Steeltoe.Management.Endpoint.Mappings.IMappingsOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `RouteMappingsEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Mappings.IRouteDetails` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `RouteConditionsDescriptor` | Redundant | +| `Steeltoe.Management.Endpoint.Mappings.IRouteMappings` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Conventional routes are no longer shown in mappings actuator | +| `Steeltoe.Management.Endpoint.Mappings.MappingDescription` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `RouteDescriptor` | | +| `Steeltoe.Management.Endpoint.Mappings.MappingsEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IRouteMappingsEndpointHandler` | Moved to internal type `RouteMappingsEndpointHandler` | +| `Steeltoe.Management.Endpoint.Mappings.MappingsEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddRouteMappingsActuator()` | Moved to internal type `RouteMappingsEndpointMiddleware` | +| `Steeltoe.Management.Endpoint.Mappings.MappingsEndpointOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `RouteMappingsEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Mappings.MappingsStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddRouteMappingsActuator()` | | +| `Steeltoe.Management.Endpoint.Mappings.RouteBuilderExtensions.AddRoutesToMappingsActuator` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Conventional routes are no longer shown in mappings actuator | +| `Steeltoe.Management.Endpoint.Mappings.RouteMappings` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Conventional routes are no longer shown in mappings actuator | +| `Steeltoe.Management.Endpoint.MediaTypeVersion` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Each actuator uses built-in media type | +| `Steeltoe.Management.Endpoint.Metrics` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Metrics actuator has been removed | +| `Steeltoe.Management.Endpoint.Metrics.IPrometheusEndpointOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `PrometheusEndpointOptions` in Steeltoe.Management.Prometheus package | | +| `Steeltoe.Management.Endpoint.Metrics.PrometheusEndpointOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Moved | `PrometheusEndpointOptions` in Steeltoe.Management.Prometheus package | | +| `Steeltoe.Management.Endpoint.Metrics.PrometheusEndpointOptions.ScrapeResponseCacheDurationMilliseconds` | Property | Steeltoe.Management.Endpoint [Base/Core] | Removed | | Was never used | +| `Steeltoe.Management.Endpoint.Middleware.ActuatorMetadataProvider` | Type | Steeltoe.Management.Endpoint | Added | | Default implementation to provide metadata for route mappings actuator | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware.CanInvoke` | Method | Steeltoe.Management.Endpoint | Added | | Verifies enabled/exposed based on request path | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware.GetMetadataProvider` | Method | Steeltoe.Management.Endpoint | Added | | Provides metadata for route mappings actuator | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware.InvokeAsync` | Method | Steeltoe.Management.Endpoint | Added | | `IMiddleware` interface implementation | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware.ParseRequestAsync` | Method | Steeltoe.Management.Endpoint | Added | | Creates `TRequest` instance from `HttpContext` | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Changed | `EndpointMiddleware` | Type parameter order reversed | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `EndpointMiddleware` | Pass `object?`/`null` for unused `TRequest` | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware._endpoint` | Field | Steeltoe.Management.Endpoint [Base/Core] | Removed | `EndpointMiddleware.EndpointHandler` | | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware._logger` | Field | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware._mgmtOptions` | Field | Steeltoe.Management.Endpoint [Base/Core] | Removed | `EndpointMiddleware.ManagementOptionsMonitor` | | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware.Endpoint` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `EndpointMiddleware.EndpointHandler` | | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware.HandleRequest` | Method | Steeltoe.Management.Endpoint [Base/Core] | Removed | `EndpointMiddleware.InvokeEndpointHandlerAsync` | | +| `Steeltoe.Management.Endpoint.Middleware.EndpointMiddleware.Serialize` | Method | Steeltoe.Management.Endpoint [Base/Core] | Removed | `EndpointMiddleware.WriteResponseAsync` | | +| `Steeltoe.Management.Endpoint.Middleware.IEndpointMiddleware` | Type | Steeltoe.Management.Endpoint | Added | | Implement for custom actuator | +| `Steeltoe.Management.Endpoint.Refresh` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.Refresh` | | +| `Steeltoe.Management.Endpoint.Refresh.IRefreshEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IRefreshEndpointHandler` | | +| `Steeltoe.Management.Endpoint.Refresh.IRefreshOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `RefreshEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Refresh.RefreshEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IRefreshEndpointHandler` | Moved to internal type `RefreshEndpointHandler` | +| `Steeltoe.Management.Endpoint.Refresh.RefreshEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddRefreshActuator()` | Made internal | +| `Steeltoe.Management.Endpoint.Refresh.RefreshStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddRefreshActuator()` | | +| `Steeltoe.Management.Endpoint.Security.EndpointClaim` | Type | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.Health.EndpointClaim` | | +| `Steeltoe.Management.Endpoint.Security.ISecurityContext` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.Endpoint.SpringBootAdminClient.SpringBootAdminApplicationBuilderExtensions.RegisterWithSpringBootAdmin` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddSpringBootAdminClient()` | | +| `Steeltoe.Management.Endpoint.SpringBootAdminClient.SpringBootAdminClientOptions.ConnectionTimeoutMS` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `SpringBootAdminClientOptions.ConnectionTimeoutMs` | | +| `Steeltoe.Management.Endpoint.ThreadDump` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.ThreadDump` | | +| `Steeltoe.Management.Endpoint.ThreadDump.IThreadDumpEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IThreadDumpEndpointHandler` | | +| `Steeltoe.Management.Endpoint.ThreadDump.IThreadDumpEndpointV2` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IThreadDumpEndpointHandler` | Redundant | +| `Steeltoe.Management.Endpoint.ThreadDump.IThreadDumper` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.Endpoint.ThreadDump.IThreadDumpOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `ThreadDumpEndpointOptions` | | +| `Steeltoe.Management.Endpoint.ThreadDump.LockInfo` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Was never used | +| `Steeltoe.Management.Endpoint.ThreadDump.MetaDataImportProvider` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Was never used | +| `Steeltoe.Management.Endpoint.ThreadDump.MonitorInfo` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Was never used | +| `Steeltoe.Management.Endpoint.ThreadDump.ThreadDumpEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IThreadDumpEndpointHandler` | Moved to internal type `ThreadDumpEndpointHandler` | +| `Steeltoe.Management.Endpoint.ThreadDump.ThreadDumpEndpoint_v2` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IThreadDumpEndpointHandler` | Redundant | +| `Steeltoe.Management.Endpoint.ThreadDump.ThreadDumpEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddThreadDumpActuator()` | Made internal | +| `Steeltoe.Management.Endpoint.ThreadDump.ThreadDumpEndpointMiddleware_v2` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddThreadDumpActuator()` | Redundant | +| `Steeltoe.Management.Endpoint.ThreadDump.ThreadDumperEP` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Renamed to internal type `EventPipeThreadDumper` | +| `Steeltoe.Management.Endpoint.ThreadDump.ThreadDumpResult` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.Endpoint.ThreadDump.ThreadDumpStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddThreadDumpActuator()` | | +| `Steeltoe.Management.Endpoint.ThreadDump.TState` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `State` | | +| `Steeltoe.Management.Endpoint.Trace` | Namespace | Steeltoe.Management.Endpoint [Base/Core] | Moved | `Steeltoe.Management.Endpoint.Actuators.HttpExchanges` | | +| `Steeltoe.Management.Endpoint.Trace.EndpointServiceCollectionExtensions.AddTraceActuator` | Extension method | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `AddHttpExchangesActuator` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTrace` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchange` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceDiagnosticObserver` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Moved to internal type `HttpExchangesDiagnosticObserver` | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IHttpExchangesEndpointHandler` | Moved to internal type `HttpExchangesEndpointHandler` | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddHttpExchangesActuator()` | Moved to internal type `HttpExchangesEndpointMiddleware` | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddAuthType` | Property | Steeltoe.Management.Endpoint [Base/Core] | Removed | `HttpExchangesEndpointOptions.IncludeRequestHeaders` | Was effectively ignored | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddParameters` | Property | Steeltoe.Management.Endpoint [Base/Core] | Removed | `HttpExchangesEndpointOptions.IncludeQueryString` | Form data is no longer included | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddPathInfo` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesEndpointOptions.IncludePathInfo` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddQueryString` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesEndpointOptions.IncludeQueryString` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddRemoteAddress` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesEndpointOptions.IncludeRemoteAddress` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddRequestHeaders` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesEndpointOptions.IncludeRequestHeaders` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddResponseHeaders` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesEndpointOptions.IncludeResponseHeaders` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddSessionId` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesEndpointOptions.IncludeSessionId` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddTimeTaken` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesEndpointOptions.IncludeTimeTaken` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceEndpointOptions.AddUserPrincipal` | Property | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesEndpointOptions.IncludeUserPrincipal` | | +| `Steeltoe.Management.Endpoint.Trace.HttpTraceResult` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesResult` | | +| `Steeltoe.Management.Endpoint.Trace.IHttpTraceEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IHttpExchangesEndpointHandler` | | +| `Steeltoe.Management.Endpoint.Trace.IHttpTraceRepository` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IHttpExchangesRepository` | | +| `Steeltoe.Management.Endpoint.Trace.IHttpTraceRepository.GetTraces` | Method | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IHttpExchangesRepository.GetHttpExchanges` | | +| `Steeltoe.Management.Endpoint.Trace.ITraceEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IHttpExchangesEndpointHandler` | | +| `Steeltoe.Management.Endpoint.Trace.ITraceOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `HttpExchangesEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Trace.ITraceRepository` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IHttpExchangesRepository` | | +| `Steeltoe.Management.Endpoint.Trace.ITraceRepository.GetTraces` | Method | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `IHttpExchangesRepository.GetHttpExchanges` | | +| `Steeltoe.Management.Endpoint.Trace.Principal` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangePrincipal` | | +| `Steeltoe.Management.Endpoint.Trace.Request` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangeRequest` | | +| `Steeltoe.Management.Endpoint.Trace.Response` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangeResponse` | | +| `Steeltoe.Management.Endpoint.Trace.Session` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangeSession` | | +| `Steeltoe.Management.Endpoint.Trace.TraceDiagnosticObserver` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Moved to internal type `HttpExchangesDiagnosticObserver` | +| `Steeltoe.Management.Endpoint.Trace.TraceEndpoint` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `IHttpExchangesEndpointHandler` | Moved to internal type `HttpExchangesEndpointHandler` | +| `Steeltoe.Management.Endpoint.Trace.TraceEndpointMiddleware` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddHttpExchangesActuator()` | Moved to internal type `HttpExchangesEndpointMiddleware` | +| `Steeltoe.Management.Endpoint.Trace.TraceEndpointOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Renamed | `HttpExchangesEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Trace.TraceEndpointOptions` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `HttpExchangesEndpointOptions` | | +| `Steeltoe.Management.Endpoint.Trace.TraceResult` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `HttpExchange` | | +| `Steeltoe.Management.Endpoint.Trace.TraceStartupFilter` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | `builder.Services.AddHttpExchangesActuator()` | | +| `Steeltoe.Management.Endpoint.Utils` | Type | Steeltoe.Management.Endpoint [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.IEndpoint` | Type | Steeltoe.Management.Abstractions | Removed | `IEndpointHandler<,>` in Steeltoe.Management.Endpoint package | | +| `Steeltoe.Management.IEndpointOptions` | Type | Steeltoe.Management.Abstractions | Removed | `Steeltoe.Management.Configuration.EndpointOptions` | | +| `Steeltoe.Management.IManagementOptions` | Type | Steeltoe.Management.Abstractions | Removed | `ManagementOptions` in Steeltoe.Management.Endpoint package | | +| `Steeltoe.Management.Info.AbstractConfigurationContributor` | Type | Steeltoe.Management.Abstractions | Removed | None | Moved to internal type `ConfigurationContributor` | +| `Steeltoe.Management.Info.IInfoBuilder` | Type | Steeltoe.Management.Abstractions | Removed | `InfoBuilder` in Steeltoe.Management.Endpoint package | Redundant | +| `Steeltoe.Management.Info.IInfoContributor` | Type | Steeltoe.Management.Abstractions | Moved | `IInfoContributor` in Steeltoe.Management.Endpoint package | | +| `Steeltoe.Management.Info.IInfoContributor.Contribute` | Method | Steeltoe.Management.Abstractions | Moved | `ContributeAsync()` | | +| `Steeltoe.Management.Info.InfoBuilder` | Type | Steeltoe.Management.Abstractions | Moved | `InfoBuilder` in Steeltoe.Management.Endpoint package | | +| `Steeltoe.Management.Kubernetes` | Namespace | Steeltoe.Management.KubernetesCore | Removed | None | | +| `Steeltoe.Management.OpenTelemetry` | Namespace | Steeltoe.Management.OpenTelemetryBase | Removed | `builder.Services.AddPrometheusActuator()` from Steeltoe.Management.Prometheus package | WaveFront exporter was removed | +| `Steeltoe.Management.Permissions` | Type | Steeltoe.Management.Abstractions | Renamed | `EndpointPermissions` | | +| `Steeltoe.Management.Permissions.UNDEFINED` | Field | Steeltoe.Management.Abstractions | Removed | None | Default in options changed to Restricted | +| `Steeltoe.Management.Prometheus.PrometheusEndpointOptions` | Type | Steeltoe.Management.Prometheus | Added | | Configuration for Prometheus actuator | +| `Steeltoe.Management.Prometheus.PrometheusExtensions.AddPrometheusActuator` | Extension method | Steeltoe.Management.Prometheus | Added | | Add Prometheus actuator to service collection | +| `Steeltoe.Management.Prometheus.PrometheusExtensions.UsePrometheusActuator` | Extension method | Steeltoe.Management.Prometheus | Added | | Activate Prometheus actuator middleware | +| `Steeltoe.Management.TaskCore` | Namespace | Steeltoe.Management.TaskCore | Moved | `Steeltoe.Management.Tasks` | | +| `Steeltoe.Management.TaskCore.DelegatingTask` | Type | Steeltoe.Management.TaskCore | Removed | `builder.Services.AddTask()` | Made internal | +| `Steeltoe.Management.TaskCore.TaskWebHostExtensions.RunWithTasks` | Extension method | Steeltoe.Management.TaskCore | Renamed | `RunWithTasksAsync` | | +| `Steeltoe.Management.Tasks.TaskHostExtensions.HasApplicationTask` | Extension method | Steeltoe.Management.Tasks | Added | | Check whether a task will run | +| `Steeltoe.Management.Tracing.TracingBaseHostBuilderExtensions.AddDistributedTracing` | Extension method | Steeltoe.Management.Tracing [Base/Core] | Removed | Use OpenTelemetry packages directly | | +| `Steeltoe.Management.Tracing.TracingBaseServiceCollectionExtensions.AddDistributedTracing` | Extension method | Steeltoe.Management.Tracing [Base/Core] | Removed | Use OpenTelemetry packages directly | | +| `Steeltoe.Management.Tracing.TracingCoreServiceCollectionExtensions.AddDistributedTracingAspNetCore` | Extension method | Steeltoe.Management.Tracing [Base/Core] | Removed | Use OpenTelemetry packages directly | | +| `Steeltoe.Management.Tracing.TracingHostBuilderExtensions.AddDistributedTracincAspNetCore` | Extension method | Steeltoe.Management.Tracing [Base/Core] | Removed | Use OpenTelemetry packages directly | | +| `Steeltoe.Management.Tracing.TracingLogProcessor.GetCurrentSpan` | Method | Steeltoe.Management.Tracing [Base/Core] | Removed | None | Redundant | +| `Steeltoe.Management.Tracing.TracingOptions` | Type | Steeltoe.Management.Tracing [Base/Core] | Removed | Use OpenTelemetry packages directly | | +| `Steeltoe.Management.Tracing.TracingServiceCollectionExtensions.AddTracingLogProcessor` | Extension method | Steeltoe.Management.Tracing | Added | | Add trace info from `Activity.Current` to logs | + +### Notable PRs + +- https://github.com/SteeltoeOSS/Steeltoe/pull/1474 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1457 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1454 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1451 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1444 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1443 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1438 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1424 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1422 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1421 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1417 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1416 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1413 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1402 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1401 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1398 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1396 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1393 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1392 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1390 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1389 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1386 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1385 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1382 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1380 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1378 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1364 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1357 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1356 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1353 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1331 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1278 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1247 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1224 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1198 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1187 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1185 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1184 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1177 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1165 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1155 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1130 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1120 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1114 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1101 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1065 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1050 + +### Documentation + +For more information, see the updated [Management documentation](../management/index.md) and +[Management samples](https://github.com/SteeltoeOSS/Samples/tree/main/Management). + +## Security + +### Behavior changes + +- Drastically simplified implementation, leveraging the built-in ASP.NET option types +- Dropped OAuth support in favor of OpenID Connect +- Removed CredHub client, use [CredHub Service Broker](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/credhub-service-broker/services/credhub-sb/index.html) + +### NuGet Package changes + +| Source | Change | Replacement | Notes | +| ------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| Steeltoe.Security.Authentication.CloudFoundryBase | Removed | Steeltoe.Security.Authentication.JwtBearer, Steeltoe.Security.Authentication.OpenIdConnect, Steeltoe.Security.Authorization.Certificate | Replacement packages are split per auth method | +| Steeltoe.Security.Authentication.CloudFoundryCore | Removed | Steeltoe.Security.Authentication.JwtBearer, Steeltoe.Security.Authentication.OpenIdConnect, Steeltoe.Security.Authorization.Certificate | Replacement packages are split per auth method | +| Steeltoe.Security.Authentication.JwtBearer | Added | | JSON Web Tokens (JWT) for Cloud Foundry | +| Steeltoe.Security.Authentication.MtlsCore | Renamed | Steeltoe.Security.Authorization.Certificate | Client certificate auth for Cloud Foundry | +| Steeltoe.Security.Authentication.OpenIdConnect | Added | | OpenID Connect (OIDC) for Cloud Foundry | +| Steeltoe.Security.DataProtection.CredHubBase | Removed | None | Use CredHub Service Broker | +| Steeltoe.Security.DataProtection.CredHubCore | Removed | None | Use CredHub Service Broker | +| Steeltoe.Security.DataProtection.RedisCore | Renamed | Steeltoe.Security.DataProtection.Redis | | + +### API changes + +| Source | Kind | Package | Change | Replacement | Notes | +| ----------------------------------------------------------------------------------------------------------------------------------- | ---------------- | --------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| `Steeltoe.Security.Authentication.CloudFoundry.ApplicationBuilderExtensions.UseCloudFoundryCertificateAuth` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `app.UseCertificateAuthorization()` | | +| `Steeltoe.Security.Authentication.CloudFoundry.ApplicationBuilderExtensions.UseCloudFoundryContainerIdentity` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `app.UseCertificateAuthorization()` | | +| `Steeltoe.Security.Authentication.CloudFoundry.ApplicationClaimTypes` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Moved to internal type `ApplicationClaimTypes` | +| `Steeltoe.Security.Authentication.CloudFoundry.AuthenticationBuilderExtensions.AddCloudFoundryIdentityCertificate` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `builder.Configuration.AddAppInstanceIdentityCertificate(); builder.Services.AddAuthentication().AddCertificate();` | | +| `Steeltoe.Security.Authentication.CloudFoundry.AuthenticationBuilderExtensions.AddCloudFoundryJwtBearer` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `builder.Services.AddAuthentication().AddJwtBearer().ConfigureJwtBearerForCloudFoundry()` | | +| `Steeltoe.Security.Authentication.CloudFoundry.AuthenticationBuilderExtensions.AddCloudFoundryOAuth` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | Use OpenID Connect or JWT instead | OAuth support has been removed | +| `Steeltoe.Security.Authentication.CloudFoundry.AuthenticationBuilderExtensions.AddCloudFoundryOpenIdConnect` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `builder.Services.AddAuthentication().AddOpenIdConnect().ConfigureOpenIdConnectForCloudFoundry()` | | +| `Steeltoe.Security.Authentication.CloudFoundry.AuthorizationPolicyBuilderExtensions.SameOrg` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Moved | `AuthorizationPolicyBuilder.RequireSameOrg()` in Steeltoe.Security.Authorization.Certificate package | | +| `Steeltoe.Security.Authentication.CloudFoundry.AuthorizationPolicyBuilderExtensions.SameSpace` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Moved | `AuthorizationPolicyBuilder.RequireSameSpace()` in Steeltoe.Security.Authorization.Certificate package | | +| `Steeltoe.Security.Authentication.CloudFoundry.AuthServerOptions` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `JwtBearerOptions`, `OpenIdConnectOptions` | Now uses built-in ASP.NET option types | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryCertificateIdentityAuthorizationHandler` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored to internal type `CertificateAuthorizationHandler` | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryClaimActionExtensions` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored, no longer needed | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryDefaults` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Contained constants that are no longer needed | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryHelper` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored, no longer needed | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryJwtBearerConfigurer` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored to internal type `PostConfigureJwtBearerOptions` | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryJwtBearerOptions` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions` | Refactored, no longer needed | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryOAuthConfigurer` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored to internal type `PostConfigureOpenIdConnectOptions` | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryOAuthHandler` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored to internal type `TokenKeyResolver` | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryOAuthOptions` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions` | Refactored, no longer needed | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryOpenIdConnectOptions` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions` | Refactored, no longer needed | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryScopeClaimAction` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored, no longer needed | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryTokenKeyResolver` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored to internal type `TokenKeyResolver` | +| `Steeltoe.Security.Authentication.CloudFoundry.CloudFoundryTokenValidator` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored, no longer needed | +| `Steeltoe.Security.Authentication.CloudFoundry.ConfigurationBuilderExtensions.AddCloudFoundryContainerIdentity` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Moved | `builder.Configuration.AddAppInstanceIdentityCertificate()` in Steeltoe.Security.Authorization.Certificate package | | +| `Steeltoe.Security.Authentication.CloudFoundry.MutualTlsAuthenticationOptionsPostConfigurer` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored to internal type `PostConfigureCertificateAuthenticationOptions` | +| `Steeltoe.Security.Authentication.CloudFoundry.OpenIdTokenResponse` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored, no longer needed | +| `Steeltoe.Security.Authentication.CloudFoundry.SameOrgRequirement` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Moved | `SameOrgRequirement` in Steeltoe.Security.Authorization.Certificate package | | +| `Steeltoe.Security.Authentication.CloudFoundry.SameSpaceRequirement` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Moved | `SameSpaceRequirement` in Steeltoe.Security.Authorization.Certificate package | | +| `Steeltoe.Security.Authentication.CloudFoundry.ServiceCollectionExtensions.AddCloudFoundryContainerIdentity` | Extension method | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | `builder.Services.AddAuthorizationBuilder().AddOrgAndSpacePolicies()` in Steeltoe.Security.Authorization.Certificate package | | +| `Steeltoe.Security.Authentication.CloudFoundry.TokenExchanger` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Refactored, no longer needed | +| `Steeltoe.Security.Authentication.JwtBearer.JwtBearerAuthenticationBuilderExtensions.ConfigureJwtBearerForCloudFoundry` | Extension method | Steeltoe.Security.Authentication.JwtBearer | Added | | Configure JWT for UAA-based systems like Cloud Foundry | +| `Steeltoe.Security.Authentication.Mtls.CertificateApplicationBuilderExtensions.UseCertificateRotation` | Extension method | Steeltoe.Security.Authentication.MtlsCore | Removed | None | Rotating certificates in OS-level certificate store proved to be unreliable | +| `Steeltoe.Security.Authentication.Mtls.CertificateAuthenticationBuilderExtensions.AddMutualTls` | Extension method | Steeltoe.Security.Authentication.MtlsCore | Removed | `app.UseCertificateAuthorization()` | | +| `Steeltoe.Security.Authentication.Mtls.CertificateRotationHostedService` | Type | Steeltoe.Security.Authentication.MtlsCore | Removed | None | Rotating certificates in OS-level certificate store proved to be unreliable | +| `Steeltoe.Security.Authentication.Mtls.CloudFoundryInstanceCertificate` | Type | Steeltoe.Security.Authentication.CloudFoundry [Base/Core] | Removed | None | Moved to internal type `ApplicationInstanceCertificate` | +| `Steeltoe.Security.Authentication.Mtls.MutualTlsAuthenticationOptions` | Type | Steeltoe.Security.Authentication.MtlsCore | Removed | `Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationOptions` | | +| `Steeltoe.Security.Authentication.Mtls.MutualTlsAuthenticationOptions.IssuerChain` | Property | Steeltoe.Security.Authentication.MtlsCore | Removed | `CertificateOptions.IssuerChain` in Steeltoe.Common.Certificates package | | +| `Steeltoe.Security.Authentication.OpenIdConnect.OpenIdConnectAuthenticationBuilderExtensions.ConfigureOpenIdConnectForCloudFoundry` | Extension method | Steeltoe.Security.Authentication.OpenIdConnect | Added | | Configure OIDC for UAA-based systems like Cloud Foundry | +| `Steeltoe.Security.Authorization.Certificate.CertificateApplicationBuilderExtensions.UseCertificateAuthorization` | Extension method | Steeltoe.Security.Authorization.Certificate | Added | | Activates cert/header forwarding in ASP.NET Core auth middleware | +| `Steeltoe.Security.Authorization.Certificate.CertificateAuthorizationBuilderExtensions.AddOrgAndSpacePolicies` | Extension method | Steeltoe.Security.Authorization.Certificate | Added | | Verify space/org in the incoming client certificate | +| `Steeltoe.Security.Authorization.Certificate.CertificateAuthorizationPolicies.SameOrganization` | Property | Steeltoe.Security.Authorization.Certificate | Added | | Constant for same-org policy | +| `Steeltoe.Security.Authorization.Certificate.CertificateAuthorizationPolicies.SameSpace` | Property | Steeltoe.Security.Authorization.Certificate | Added | | Constant for same-space policy | +| `Steeltoe.Security.Authorization.Certificate.CertificateAuthorizationPolicyBuilderExtensions.RequireSameOrg` | Extension method | Steeltoe.Security.Authorization.Certificate | Added | | Require client certificate to originate from same organization | +| `Steeltoe.Security.Authorization.Certificate.CertificateAuthorizationPolicyBuilderExtensions.RequireSameSpace` | Extension method | Steeltoe.Security.Authorization.Certificate | Added | | Require client certificate to originate from same space | +| `Steeltoe.Security.Authorization.Certificate.CertificateHttpClientBuilderExtensions.AddAppInstanceIdentityCertificate` | Extension method | Steeltoe.Security.Authorization.Certificate | Added | | Send app-identify certificate with outgoing HTTP requests | +| `Steeltoe.Security.Authorization.Certificate.CertificateHttpClientBuilderExtensions.AddClientCertificate` | Extension method | Steeltoe.Security.Authorization.Certificate | Added | | Send custom certificate with outgoing HTTP requests | +| `Steeltoe.Security.Authorization.Certificate.SameOrgRequirement` | Type | Steeltoe.Security.Authorization.Certificate | Added | | Authorization requirement for same-org | +| `Steeltoe.Security.Authorization.Certificate.SameSpaceRequirement` | Type | Steeltoe.Security.Authorization.Certificate | Added | | Authorization requirement for same-space | +| `Steeltoe.Security.DataProtection.Redis.CloudFoundryRedisXmlRepository` | Type | Steeltoe.Security.DataProtection.RedisCore | Removed | | No longer needed | +| `Steeltoe.Security.DataProtection.Redis.RedisDataProtectionBuilderExtensions.PersistKeysToRedis` | Extension method | Steeltoe.Security.DataProtection.Redis | Added | | Takes an optional service binding name | +| `Steeltoe.Security.DataProtection.RedisDataProtectionBuilderExtensions.PersistKeysToRedis` | Extension method | Steeltoe.Security.DataProtection.RedisCore | Moved | `PersistKeysToRedis()` in Steeltoe.Security.DataProtection.Redis package | | + +### Notable PRs + +- https://github.com/SteeltoeOSS/Steeltoe/pull/1452 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1349 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1336 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1311 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1306 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1232 +- https://github.com/SteeltoeOSS/Steeltoe/pull/1098 + +### Documentation + +For more information, see the updated [Security documentation](../security/index.md) and +[Discovery samples](https://github.com/SteeltoeOSS/Samples/tree/main/Security). + +## Release Notes + +Release notes for all releases can be found on the [Steeltoe releases](https://github.com/SteeltoeOSS/Steeltoe/releases) section on GitHub. diff --git a/articles/create-dotnet-microservice-projects-automatically-with-steeltoe-initializr.md b/articles/create-dotnet-microservice-projects-automatically-with-steeltoe-initializr.md index 3df61ece..2a4fd160 100644 --- a/articles/create-dotnet-microservice-projects-automatically-with-steeltoe-initializr.md +++ b/articles/create-dotnet-microservice-projects-automatically-with-steeltoe-initializr.md @@ -79,7 +79,7 @@ Through either the web UI or the rest endpoints, Initializr will get your micros Initializr's API offers a few very helpful endpoints. It's how the web UI is able to create such a great experience and how the community could extend its capabilities into Visual Studio or other developer related tools. -Below is a brief explanation of Initializr's top level endpoints. But the conversation doesn't stop there. Each of these endpoints offer all kinds of deeper sub-url's that drill down to specifics of Initializr's config. Read more about [them here](https://docs.steeltoe.io/api/v3/initializr). +Below is a brief explanation of Initializr's top level endpoints. But the conversation doesn't stop there. Each of these endpoints offer all kinds of deeper sub-url's that drill down to specifics of Initializr's config. Read more about [them here](../api/v3/initializr/index.md). **Endpoint Home** @@ -97,7 +97,7 @@ Below is a brief explanation of Initializr's top level endpoints. But the conver ## About dependencies -Initializr's special sauce is the collection of dependencies. It's the reason the tool is so powerful. It's also worthy of an entire discussion - there's quite a few moving parts. We're not going to get too deep in Initializr's inner workings at this time. So, if you would like to get deeper the [project's documentation](https://docs.steeltoe.io/api/v3/initializr) is waiting just for you. +Initializr's special sauce is the collection of dependencies. It's the reason the tool is so powerful. It's also worthy of an entire discussion - there's quite a few moving parts. We're not going to get too deep in Initializr's inner workings at this time. So, if you would like to get deeper the [project's documentation](../api/v3/initializr/index.md) is waiting just for you. When Initializr generates a new project that has added dependencies, the templating is used to “fill in the blanks”. Let see an example of this in action. diff --git a/articles/releases/steeltoe-2-1-boosts-your-net-microservices-with-actuator-endpoints-distributed-tracing-and-deeper-support-for-the-frameworks-that-matter.md b/articles/releases/steeltoe-2-1-boosts-your-net-microservices-with-actuator-endpoints-distributed-tracing-and-deeper-support-for-the-frameworks-that-matter.md index 15049885..c553ba07 100644 --- a/articles/releases/steeltoe-2-1-boosts-your-net-microservices-with-actuator-endpoints-distributed-tracing-and-deeper-support-for-the-frameworks-that-matter.md +++ b/articles/releases/steeltoe-2-1-boosts-your-net-microservices-with-actuator-endpoints-distributed-tracing-and-deeper-support-for-the-frameworks-that-matter.md @@ -16,7 +16,7 @@ author.name: Dave Tillman # Steeltoe 2.1 Boosts Your .NET Microservices with Actuator Endpoints, Distributed Tracing, and Deeper Support for the Frameworks that Matter -With the release of Steeltoe 2.1, Pivotal continues to deliver useful tools to help developers build enterprise-quality, cloud-native .NET apps on [Cloud Foundry](https://www.cloudfoundry.org/). +With the release of Steeltoe 2.1, Pivotal continues to deliver useful tools to help developers build enterprise-quality, cloud-native .NET apps on [Cloud Foundry](https://www.cloudfoundry.org/). Modernizing with a “lift-and-shift” approach? Or are you “re-engineering and rebuilding”? Either way, Steeltoe 2.1 offers several options to make your journey easier. diff --git a/articles/releases/steeltoe-2-2-gives-your--microservices-a-boost.md b/articles/releases/steeltoe-2-2-gives-your--microservices-a-boost.md index c11a99da..3dae4895 100644 --- a/articles/releases/steeltoe-2-2-gives-your--microservices-a-boost.md +++ b/articles/releases/steeltoe-2-2-gives-your--microservices-a-boost.md @@ -18,11 +18,11 @@ author.twitter: dierufdavid # Steeltoe 2.2 Gives Your .NET Microservices a Boost -My wife and I have an agreement. She doesn't question my fashion sense and I don't ask her to review release notes with me. "But Steeltoe 2.2 is coming out soon, honey." "Your pants look like mom jeans" she fires back. Clearly I am not going to win that exchange. +My wife and I have an agreement. She doesn't question my fashion sense and I don't ask her to review release notes with me. "But Steeltoe 2.2 is coming out soon, honey." "Your pants look like mom jeans" she fires back. Clearly I am not going to win that exchange. While my better half may not be excited about the new Steeltoe, over 2.4 million NuGet downloads and a very active community suggest that lots of .NET developers are eager to dive in. Each Steeltoe release is always jam-packed with useful new capabilities. [Steeltoe 2.2](http://steeltoe.io/reference/reference-release-notes/), now GA, delivers! Let’s take a spin through the highlights... | [Read More](https://tanzu.vmware.com/content/blog/steeltoe-2-2-gives-your-net-microservices-a-boost) | -|:---:| \ No newline at end of file +|:---:| diff --git a/articles/releases/steeltoe-2-4-boosts-dotnet-microservices-development.md b/articles/releases/steeltoe-2-4-boosts-dotnet-microservices-development.md index e6718aa6..df5a28d7 100644 --- a/articles/releases/steeltoe-2-4-boosts-dotnet-microservices-development.md +++ b/articles/releases/steeltoe-2-4-boosts-dotnet-microservices-development.md @@ -23,4 +23,4 @@ The Steeltoe framework helps .NET developers create cloud-native applications. A To this end, we’ve cooked up some nifty things to help you do more with Steeltoe... | [Read More](https://tanzu.vmware.com/content/blog/steeltoe-2-4-boosts-dotnet-microservices-development) | -|:---:| \ No newline at end of file +|:---:| diff --git a/articles/releases/steeltoe-3-0-packs-a-mighty-punch-with-many-new-features.md b/articles/releases/steeltoe-3-0-packs-a-mighty-punch-with-many-new-features.md index c66a6507..07797a37 100644 --- a/articles/releases/steeltoe-3-0-packs-a-mighty-punch-with-many-new-features.md +++ b/articles/releases/steeltoe-3-0-packs-a-mighty-punch-with-many-new-features.md @@ -19,7 +19,7 @@ author.twitter: dierufdavid As you make your way through cloud computing and (inevitably) microservices, there will be a never ending list of configuration choices and technical debt. Containerizing legacy code, best practices in new code, developing locally, debugging production apps. That's just a hint of the kinds of questions to be answered. -Fortunately, you’re not the first to embark on this journey. Others have gone ahead and discovered realistic ways to do things. And don’t worry you’re also not the last, so don’t feel like you're playing catch up. +Fortunately, you’re not the first to embark on this journey. Others have gone ahead and discovered realistic ways to do things. And don’t worry you’re also not the last, so don’t feel like you're playing catch up. Running in the cloud means different things to different folks but at its heart, it’s containerization. You may run a container on your desktop, on an enterprise network, or on a public cloud. For Steeltoe, they are all the same. @@ -31,9 +31,7 @@ Steeltoe makes things like production ready database connections a single line o Steeltoe 3.0 is a product of years of learning. Small businesses and large enterprises have all been benefiting and contributing to this new release. It’s a fresh take on cloud opinions that seemingly never get answered. It’s the next evolution for your microservices to go to cloud ninja status. ---- -##### If you’re moving from Steeltoe 2.x and would like a quick comparision with version 3.0, refer to [this page](https://steeltoe.io/docs/3/welcome/whats-new). ---- +> If you’re moving from Steeltoe 2.x and would like a quick comparison with version 3.0, refer to [this page](../../api/v3/welcome/whats-new.md). Let's take a look at the new things included in Steeltoe 3.0. If you’re still wondering how the project fits in your new or existing .NET applications, [learn how here](https://steeltoe.io). @@ -43,7 +41,7 @@ You might know it as a few different things - eventing, event architecture, even To help developers use message based systems but not have to manage all the debt that typically comes along with such a thing, Steeltoe 3 introduces the new Messaging component. This component does all the work of resiliency, portability, and fault-tolerance. To implement it you provide the location of the message server and start reading & writing messages. Want to include a custom object in the message? Steeltoe Messaging will take care of converting the bytes. Should the queue be "ensured" when the application is starting up? Configure Steeltoe Messaging to create it, if nothing is present. Do you have potentially many instances of an application that all share the same queue? Steeltoe Messaging will handle everything appropriately for you. -To get started using Messaging ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/master/Messaging)), provide the server address in `appsettings.json`: +To get started using Messaging ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/3.x/Messaging)), provide the server address in `appsettings.json`: ```json "Spring": { @@ -55,13 +53,17 @@ To get started using Messaging ([here is a full example](https://github.com/Stee } } ``` + Then using dependency injection, send a message to the queue: + ```csharp public MyService(RabbitTemplate amqpTemplate, MyCustomObject myObj) { amqpTemplate.ConvertAndSend("myqueue", myObj); } ``` + Receive messages in a registered callback, managed by Steeltoe and the Rabbit broker: + ```csharp [RabbitListener("myqueue")] public void Listen(MyCustomObject myObj){ @@ -69,7 +71,7 @@ public void Listen(MyCustomObject myObj){ } ``` -Once you’ve got the basics down, it’s time to extend and make the design better with things like custom factories. Steeltoe Messaging will take care of the conversion of a message into a structured type but sometimes you want to intercept that conversion and make decisions. You can create your own `DirectRabbitListenerContainer` and customize to your heart's content. Learn more about custom listener container factories [in the docs](https://dev.steeltoe.io/docs/3/messaging/rabbitmq-intro#basics). +Once you’ve got the basics down, it’s time to extend and make the design better with things like custom factories. Steeltoe Messaging will take care of the conversion of a message into a structured type but sometimes you want to intercept that conversion and make decisions. You can create your own `DirectRabbitListenerContainer` and customize to your heart's content. Learn more about custom listener container factories [in the docs](../../api/v3/messaging/rabbitmq-intro.md#receiving-a-message). ## Legacy and Modern together in the cloud @@ -87,7 +89,7 @@ The Steeltoe team has begun the journey of supporting K8s specific things with t Adding to the list of supported service registries, Steeltoe now offers developers the option of using native Kubernetes. The really amazing design of this is, there are no additional dependencies to be deployed. Registration and discovery can happen with the resources already provided in every cluster. -In Kubernetes, when you want an application registered as discoverable, no work is required. To discover services, simply include the `Steeltoe.Discovery.ClientCore` and `Steeltoe.Discovery.Kubernetes` packages along with implementing the discovery client in the `HostBuilder` ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/master/Discovery/src)). +In Kubernetes, when you want an application registered as discoverable, no work is required. To discover services, simply include the `Steeltoe.Discovery.ClientCore` and `Steeltoe.Discovery.Kubernetes` packages along with implementing the discovery client in the `HostBuilder` ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/3.x/Discovery/src)). ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => @@ -108,7 +110,7 @@ public void ConfigureServices(IServiceCollection services) { }) .AddServiceDiscovery() .AddTypedClient(); - + ... } ``` @@ -117,7 +119,7 @@ Now when an new request is created using the http client `var result = await _ht Kubernetes also has powerful built in features when it comes to getting configuration settings into an application. Combine that with the power of .NET Core’s configuration provider hierarchy and you have one heck of a cloud-native application. -Let's say we have the following ConfigMap ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/master/Configuration/src/Kubernetes)): +Let's say we have the following ConfigMap ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/3.x/Configuration/src/Kubernetes)): ```yaml apiVersion: v1 @@ -139,14 +141,16 @@ public static IHostBuilder CreateHostBuilder(string[] args) => }) .AddKubernetesConfiguration(); ``` + And then retrieve the configuration value through IConfiguration dependency injection: + ```csharp public HomeController(IConfiguration config) { string myKey = config["someKey"]; } ``` -If you'd like to see more visit the [samples repo](https://github.com/SteeltoeOSS/Samples), or have a look in the [docs](https://steeltoe.io/docs). +If you'd like to see more visit the [samples repo](https://github.com/SteeltoeOSS/Samples/tree/3.x), or have a look in the [docs](../../api/v3/welcome/index.md). ## Generate production ready projects and get going fast @@ -156,9 +160,7 @@ The Initializr project aims to solve a very common challenge in every organizati Not only does this save the developer from writing code to manage config server connections or health endpoints or any other essential of microservices, it also keeps their projects on the latest patched libraries. ---- -##### Learn more about Initializr [now](https://steeltoe.io/initializr) ---- +> Learn more about Initializr [now](https://steeltoe.io/initializr) When you review the available dependencies in Steeltoe’s hosted version of Initializr you are probably going to have the need to add your own custom dependencies or want to bring the whole tool in-house. That is one of Initializr’s super powers! @@ -170,20 +172,20 @@ One of the most shocking things to a developer that is new to working with conta Observability is typically a sum of logs, traces, and metrics. Sometimes you have them all and sometimes not. Sometimes the data is all on one dashboard and (most of the time) it’s distributed between 2 or more dashboards. Regardless of where the data is being observed, a developer should not have to bring in all kinds of custom dependencies to conform to each dashboard used. They should offer the information in a simple, neutral way with little time spent getting it all wired up. -Steeltoe 3.0 continues the management endpoints found in 2.x but takes things to a deeper place. Along with the following examples, you can also get started using Tanzu Observability with Wavefront or create a Grafana dashboard in our [observability guides](https://dev.steeltoe.io/observability). +Steeltoe 3.0 continues the management endpoints found in 2.x but takes things to a deeper place. Along with the following examples, you can also get started using Tanzu Observability with Wavefront or create a Grafana dashboard in our [observability guides](../../guides/observability/grafana.md). * Originally OpenCensus was used for creating standard trace data and metrics. That has been superseded by the OpenTelemetry telemetric standard. -* Creating tracing spans has been simplified to a single line in `startup.cs` ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/master/Management/src/Tracing)) +* Creating tracing spans has been simplified to a single line in `startup.cs` ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src/Tracing)) ```csharp public void ConfigureServices(IServiceCollection services) { - + services.AddDistributedTracing(Configuration, builder => builder.UseZipkinWithTraceOptions(services)); ... } ``` -* In addition to the [metrics endpoint](https://dev.steeltoe.io/docs/3/management/metrics-observers), there is a new prometheus endpoint that offers a simple way for metrics to be scraped. Below is an example prometheus.yml configuration ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/master/Management/src)): +* In addition to the [metrics endpoint](../../api/v3/management/metrics.md), there is a new Prometheus endpoint that offers a simple way for metrics to be scraped. Below is an example prometheus.yml configuration ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src)): ```yaml scrape_configs: @@ -192,9 +194,9 @@ Steeltoe 3.0 continues the management endpoints found in 2.x but takes things to scrape_interval: 5s ``` -* [Dynamic logging](https://dev.steeltoe.io/docs/3/logging) can be implemented with a single statement in the `HostBuilder` +* [Dynamic logging](../../api/v3/logging/index.md) can be implemented with a single statement in the `HostBuilder` - ```csharp + ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { @@ -203,7 +205,7 @@ Steeltoe 3.0 continues the management endpoints found in 2.x but takes things to .AddDynamicLogging(); ``` -* To use Spring Boot Admin as your management dashboard add the following to `appsettings.json` ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/master/Management/src/SpringBootAdmin)): +* To use Spring Boot Admin as your management dashboard add the following to `appsettings.json` ([here is a full example](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src/SpringBootAdmin)): ```json "spring": { @@ -216,7 +218,9 @@ Steeltoe 3.0 continues the management endpoints found in 2.x but takes things to } } ``` + And implement the client in Startup.cs + ```csharp public void Configure(IApplicationBuilder app) { ... @@ -235,41 +239,44 @@ Steeltoe still has much love for Cloud Foundry but you’re going to see a lot m Here are a few examples of new ways to implement things in the `HostBuilder`: * Initialize only the health and dynamic logging + ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => { - webBuilder.UseStartup(); - }) - .AddHealthActuator(); + .ConfigureWebHostDefaults(webBuilder => { + webBuilder.UseStartup(); + }) + .AddHealthActuator(); } ``` * Initialize all actuators and optionally secure them behind an authorization policy + ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => { - webBuilder.UseStartup(); - }) - .AddAllActuators(/*endpoints => endpoints.RequireAuthorization("actuators.read")*/); + .ConfigureWebHostDefaults(webBuilder => { + webBuilder.UseStartup(); + }) + .AddAllActuators(/*endpoints => endpoints.RequireAuthorization("actuators.read")*/); } ``` * To instantly enable the enhanced features of app manager in Tanzu Application Services + ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => { - webBuilder.UseStartup(); - }) - .UseCloudHosting(5000) - .AddCloudFoundryActuators(); + .ConfigureWebHostDefaults(webBuilder => { + webBuilder.UseStartup(); + }) + .UseCloudHosting(5000) + .AddCloudFoundryActuators(); } ``` ## Learn more and get started today -To get started with any Steeltoe projects, head over to the [getting started guides](https://steeltoe.io/get-started). Combine this with the samples in the [Steeltoe GitHub repo](https://github.com/SteeltoeOSS/Samples), and you’ll have .NET microservices up and running before you know it! +To get started with any Steeltoe projects, head over to the [getting started guides](https://steeltoe.io/get-started). Combine this with the samples in the [Steeltoe GitHub repo](https://github.com/SteeltoeOSS/Samples/tree/3.x), and you’ll have .NET microservices up and running before you know it! Want to get deeper into creating cloud-native .NET apps? Attend the VMware Pivotal Labs’s [4 -day .NET developer course](https://pivotal.io/platform-acceleration-lab/pal-for-developers-net). You’ll get hands-on cloud-native .NET training learn best practices when creating microservices and become a Steeltoe ninja! diff --git a/articles/releases/steeltoe-3-1-minor-release-major-deal.md b/articles/releases/steeltoe-3-1-minor-release-major-deal.md index 410ae4ac..ad2649ef 100644 --- a/articles/releases/steeltoe-3-1-minor-release-major-deal.md +++ b/articles/releases/steeltoe-3-1-minor-release-major-deal.md @@ -33,7 +33,7 @@ Let’s look at all the new features of Steeltoe 3.1 and how it’s going to get ## Steeltoe Messaging with RabbitMQ -[Steeltoe Messaging](https://docs.steeltoe.io/api/v3/messaging/) (which was introduced in 3.0) brought three main features to simplify developing event-driven microservices: +[Steeltoe Messaging](../../api/v3/messaging/index.md) (which was introduced in 3.0) brought three main features to simplify developing event-driven microservices: * Listener container - a high-level abstraction for asynchronous processing of inbound messages * RabbitTemplate - an abstraction for sending and receiving messages @@ -49,12 +49,12 @@ Very few developers enjoy locking their applications into one vendor. To keep po The goal of Steeltoe Messaging is to make interactions with a specific broker very easy. Steeltoe Streams builds on that, to abstract broker specifics and make them more pluggable. Streams offer features like: -* Binder abstraction - a flexible programming model to dynamically choose message destinations at runtime +* Binder abstraction - a flexible programming model to dynamically choose message destinations at runtime * Persistent pub/sub semantics - makes sharing a topic easy for both producer and consumers * Consumer groups - scaling up consumer microservices while maintaining the integrity of the stream processing operation * Partitioning support - partition between multiple instances for stateful processing (even when the broker does not natively support it) -All of these concepts are covered in depth in [the documentation](https://docs.steeltoe.io/api/v3/stream/) where you can get in-depth with each concept. The goal is to take the burden of learning message semantics away and help you focus on writing your microservice. Have a look at our [quick start guide](https://docs.steeltoe.io/guides/stream/quick-start.html) and get going with message streaming in a flash! +All of these concepts are covered in depth in [the documentation](../../api/v3/stream/index.md) where you can get in-depth with each concept. The goal is to take the burden of learning message semantics away and help you focus on writing your microservice. Have a look at our [quick start guide](../../guides/stream/quick-start.md) and get going with message streaming in a flash! ## Support for Spring Cloud Data Flow @@ -74,11 +74,11 @@ SCDF introduces the concept of sources, processors, and sinks. A source is how t That’s really just the beginning of SCDF. With data pipelines, you can have multiple sources, processors, or sinks. You can scale each microservice independently. And with the introduction of Steeltoe support, you can mix both Java and .NET services together in one pipeline! -These microservices are a little more "micro" than your typical service. They could be a single .cs that does a small job. They have special attributes that take care of all the message bus management as well as the incoming and outgoing data. To learn more have a look at the [Steeltoe stream docs for SCDF](https://docs.steeltoe.io/api/v3/stream/data-flow-stream.html). +These microservices are a little more "micro" than your typical service. They could be a single .cs that does a small job. They have special attributes that take care of all the message bus management as well as the incoming and outgoing data. To learn more have a look at the [Steeltoe stream docs for SCDF](../../api/v3/stream/data-flow-stream.md). ## Steeltoe Bootstrap -Remember the days when you had multiple `using` statements and a variety of extension methods to bring in all those Steeltoe libraries? Well, we have good news: those days are now behind you. Community member Andrew Stakhov contributed an idea to the incubator called bootstrap and we think it's pretty darn cool. He created a HostBuilder extension that looks for select Steeltoe packages your project references and automatically initializes them in the project. What 'select' packages are included, you might be asking? There is a [full table](https://docs.steeltoe.io/api/v3/bootstrap/index.html#supported-steeltoe-packages) in our documentation. Simply add a reference to any (or all) of those packages and then call `AddSteeltoe()` on the HostBuilder and your microservice will get the best of cloud-native practices. Here is an example of using the bootstrapper: +Remember the days when you had multiple `using` statements and a variety of extension methods to bring in all those Steeltoe libraries? Well, we have good news: those days are now behind you. Community member Andrew Stakhov contributed an idea to the incubator called bootstrap and we think it's pretty darn cool. He created a HostBuilder extension that looks for select Steeltoe packages your project references and automatically initializes them in the project. What 'select' packages are included, you might be asking? There is a [full table](../../api/v3/bootstrap/index.md#supported-steeltoe-packages) in our documentation. Simply add a reference to any (or all) of those packages and then call `AddSteeltoe()` on the HostBuilder and your microservice will get the best of cloud-native practices. Here is an example of using the bootstrapper: ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => @@ -92,4 +92,4 @@ public static IHostBuilder CreateHostBuilder(string[] args) => ## Get Started Today -To get started with any Steeltoe projects, head over to the [getting started guides](https://docs.steeltoe.io/guides/). Combine this with the samples in the [Steeltoe GitHub repo](https://github.com/SteeltoeOSS/Samples), and you’ll have .NET microservices up and running before you know it! +To get started with any Steeltoe projects, head over to the [getting started guides](../../guides/index.md). Combine this with the samples in the [Steeltoe GitHub repo](https://github.com/SteeltoeOSS/Samples/tree/3.x), and you’ll have .NET microservices up and running before you know it! diff --git a/articles/steeltoe-3-2-2-adds-kube-service-bindings.md b/articles/steeltoe-3-2-2-adds-kube-service-bindings.md index 3a32b297..09f89b6b 100644 --- a/articles/steeltoe-3-2-2-adds-kube-service-bindings.md +++ b/articles/steeltoe-3-2-2-adds-kube-service-bindings.md @@ -15,15 +15,15 @@ author.name: David Tillman # Announcing Steeltoe 3.2.2 with Experimental Kubernetes Service Bindings -We are delighted to announce the release of Steeltoe 3.2.2. In this release, the Steeltoe team has included experimental support for the [Kubernetes Service Binding](https://github.com/servicebinding/spec) specification. -The specification details a standard way in which Kubernetes platforms can expose secrets that enable application workloads to connect to external services. +We are delighted to announce the release of Steeltoe 3.2.2. In this release, the Steeltoe team has included experimental support for the [Kubernetes Service Binding](https://github.com/servicebinding/spec) specification. +The specification details a standard way in which Kubernetes platforms can expose secrets that enable application workloads to connect to external services. You can review [version 1.0.0](https://servicebinding.io/spec/core/1.0.0/) of the specification to learn more. The experimental implementation can be found in the [Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding](https://www.nuget.org/packages/Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding) package on [nuget.org](https://www.nuget.org/). -Please keep in mind that this is an experimental version and is likely to go through several rounds of changes over the coming months. +Please keep in mind that this is an experimental version and is likely to go through several rounds of changes over the coming months. The implementation consists of a standard .NET configuration provider. The service provider reads the Kubernetes service bindings and translates the information into a set of key value pairs which it then adds to the applications configuration. -Each of configuration keys is prefixed with `k8s:bindings:` where `` is the name associated with the Kubernetes service binding. The rest of the key represents the values associated with the binding. +Each of configuration keys is prefixed with `k8s:bindings:` where `` is the name associated with the Kubernetes service binding. The rest of the key represents the values associated with the binding. Below is an example of the configuration keys associated with a PostgreSql service binding that are created by the Steeltoe configuration provider. @@ -91,7 +91,7 @@ namespace PostgreSql Running your application on a Kubernetes platform which supports the [Kubernetes Service Binding](https://github.com/servicebinding/spec) specification you should see configuration key/values appear in your applications configuration. -As an added feature, the Steeltoe team has added integration with the [Steeltoe Connectors](https://github.com/SteeltoeOSS/Steeltoe/tree/main/src/Connectors) library. This integration enables the Steeltoe Connectors library to pick up and use the configuration data built by the Kubernetes provider. +As an added feature, the Steeltoe team has added integration with the [Steeltoe Connectors](https://github.com/SteeltoeOSS/Steeltoe/tree/release/3.2/src/Connectors) library. This integration enables the Steeltoe Connectors library to pick up and use the configuration data built by the Kubernetes provider. This feature is not enabled by default. To enable it you must edit your `appsettings.json` file and add the following configuration. @@ -107,7 +107,7 @@ As an added feature, the Steeltoe team has added integration with the [Steeltoe } ``` -Take a look at the Steeltoe [PostgreSql Connector sample](https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/PostgreSql) for more details. +Take a look at the Steeltoe [PostgreSql Connector sample](https://github.com/SteeltoeOSS/Samples/tree/3.x/Connectors/src/PostgreSql) for more details. The Steeltoe team is excited to hear your thoughts and opinions on this latest release. Remember you can join us on the Steeltoe Community call or reach out to the team directly on the [Steeltoe Slack](https://steeltoeteam.slack.com//). diff --git a/articles/steeltoe-application-configuration-with-spring-cloud-config.md b/articles/steeltoe-application-configuration-with-spring-cloud-config.md index 75ea2f7d..43ddc021 100644 --- a/articles/steeltoe-application-configuration-with-spring-cloud-config.md +++ b/articles/steeltoe-application-configuration-with-spring-cloud-config.md @@ -19,4 +19,4 @@ author.twitter: dierufdavid Join Steeltoe community member David Dieruf in learning about application configuration using the Spring Cloud Config provider. -> [!Video https://www.youtube.com/embed/hxRjk66s51Q] \ No newline at end of file +> [!Video https://www.youtube.com/embed/hxRjk66s51Q] diff --git a/articles/steeltoe-basics-in-7-minutes.md b/articles/steeltoe-basics-in-7-minutes.md index f1443c1b..723341ae 100644 --- a/articles/steeltoe-basics-in-7-minutes.md +++ b/articles/steeltoe-basics-in-7-minutes.md @@ -20,4 +20,4 @@ author.twitter: dierufdavid Join Steeltoe community member David Dieruf in learning about the basic of Steeltoe in Visual Studio. -> [!Video https://www.youtube.com/embed/qftu_ku8jmM] \ No newline at end of file +> [!Video https://www.youtube.com/embed/qftu_ku8jmM] diff --git a/articles/tech-tutorial-use-kubernetes-for-modern-net-apps-steeltoe-and-project-tye-are-your-path-to-productivity.md b/articles/tech-tutorial-use-kubernetes-for-modern-net-apps-steeltoe-and-project-tye-are-your-path-to-productivity.md index 21af1cac..beeba1b4 100644 --- a/articles/tech-tutorial-use-kubernetes-for-modern-net-apps-steeltoe-and-project-tye-are-your-path-to-productivity.md +++ b/articles/tech-tutorial-use-kubernetes-for-modern-net-apps-steeltoe-and-project-tye-are-your-path-to-productivity.md @@ -44,7 +44,7 @@ Further, configuration values come from different sources in different environme .NET Core introduced [configuration providers](https://docs.microsoft.com/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#configuration-providers) and a hierarchy to them. So it's natural that a Kubernetes configmap (which is just another key/value store) should be a config source in a .NET microservice. -[Steeltoe offers a Kubernetes provider](https://steeltoe.io/docs/3/configuration/kubernetes-providers) to do just this! To add the client all you need to do is let the HostBuilder know about it. +[Steeltoe offers a Kubernetes provider](../api/v3/configuration/kubernetes-providers.md) to do just this! To add the client all you need to do is let the HostBuilder know about it. ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) @@ -67,7 +67,7 @@ public WeatherForecastController(IConfiguration config){ Also included is the option to automatically refresh values. When enabled, your application will poll (or maintain an open connection) with the Kubernetes API server. Whenever a value in the ConfigMap is changed, your app’s values will also change -- no restart needed. Whenever a value is added or removed from the ConfigMap (or Secret) your app will automatically see those changes -- also no restart required. That's some cloud-native ninja action! -Getting the value(s) of Kubernetes secrets to the application follows the same pattern as ConfigMaps. Additionally you can pick and choose which source should be made available to the application. [Learn more in the docs](https://steeltoe.io/docs/3/configuration/kubernetes-providers). +Getting the value(s) of Kubernetes secrets to the application follows the same pattern as ConfigMaps. Additionally you can pick and choose which source should be made available to the application. [Learn more in the docs](../api/v3/configuration/kubernetes-providers.md). ## If all the services are in the same cluster... @@ -80,12 +80,13 @@ To implement the Steeltoe discovery client, add the `Steeltoe.Discovery.Kubernet ```csharp using Steeltoe.Discovery.Client; //-- -public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => { - webBuilder.UseStartup(); - }) - .AddDiscoveryClient() -``` +public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => { + webBuilder.UseStartup(); + }) + .AddDiscoveryClient() + ``` The combination of adding a specific discovery client’s package and generally implementing the discovery client tells Steeltoe exactly what the app wants to do. Under the covers Steeltoe will manage all the interactions with the Kubernetes API. @@ -116,7 +117,7 @@ public FortuneService(HttpClient httpClient, ILoggerFactory logFactory){ } ``` -[Customizable load-balancing](https://steeltoe.io/docs/3/discovery/load-balancing) between multiple application instances of the same service? Done. Automatic service registration? Done. Steeltoe and Kubernetes are like peanut butter and jelly. They were made for one another. +[Customizable load-balancing](../api/v3/discovery/load-balancing.md) between multiple application instances of the same service? Done. Automatic service registration? Done. Steeltoe and Kubernetes are like peanut butter and jelly. They were made for one another. ## Teach Kubernetes what a healthy application is @@ -124,13 +125,13 @@ Any proper platform running containers is going to have a concept of health repo In Kubernetes, there are two deeper probes offered named `readiness` and `liveness`. Readiness is about ensuring the application is ready to start receiving traffic. While liveness is about making sure the application is still healthy over time. -Fortunately, Steeltoe is here to help set up both of these probes. Using new IHealthContributors and support for grouping, Steeltoe’s [health actuator endpoint](https://steeltoe.io/docs/3/management/health) builds several different views of the app’s dependencies. +Fortunately, Steeltoe is here to help set up both of these probes. Using new IHealthContributors and support for grouping, Steeltoe’s [health actuator endpoint](../api/v3/management/health.md) builds several different views of the app’s dependencies. A view is a collection of decisions that reflect the current state of the application. For example if an application depends on a service and it (for some reason) goes offline, then the view should return a negative state. When the service is back up, then the view’s state should update to positive. The current state of the views are a part of the response body in the health actuator endpoint. Kubernetes uses this to know how the app is doing. -Learn more about Steeltoe’s health endpoint with documentation and code snippets, [here](https://steeltoe.io/docs/3/management/health). +Learn more about Steeltoe’s health endpoint with documentation and code snippets, [here](../api/v3/management/health.md). ## Develop locally, as if you’re already in production @@ -146,10 +147,10 @@ The local development needs are: Say hello to [Project Tye](https://github.com/dotnet/tye). With Tye the environment is software defined as a manifest. Port assignment and container networking are done for you. You can run the application and all it’s services in individual containers. Or you could run the application from its IDE and just have Tye run the backing services. Most notably you can have Tye target Kubernetes as the intended platform. In fact you could switch between a local cluster and a hosted cluster with no change to the application! -Project Tye solves a cloud-native developer’s biggest challenge, environment parity. It’s super friendly to all your existing .NET habits and doesn’t have much bias about an IDE. All you need is the [tool installed in the dotnet cli](https://github.com/dotnet/tye/blob/master/docs/getting_started.md) and Docker running… and maybe a little yaml skill. +Project Tye solves a cloud-native developer’s biggest challenge, environment parity. It’s super friendly to all your existing .NET habits and doesn’t have much bias about an IDE. All you need is the [tool installed in the dotnet cli](https://github.com/dotnet/tye/blob/main/docs/getting_started.md) and Docker running… and maybe a little yaml skill. ## Learn more and get started today -To get started with any Steeltoe projects, head over to the [getting started guides](https://steeltoe.io/get-started). Combine this with the samples in the [Steeltoe GitHub repo](https://github.com/SteeltoeOSS/Samples), and you’ll have .NET microservices up and running before you know it! +To get started with any Steeltoe projects, head over to the [getting started guides](../guides/index.md). Combine this with the samples in the [Steeltoe GitHub repo](https://github.com/SteeltoeOSS/Samples/tree/3.x), and you’ll have .NET microservices up and running before you know it! Want to get deeper into creating cloud-native .NET apps? Attend the VMware Pivotal Labs’s [4 -day .NET developer course](https://pivotal.io/platform-acceleration-lab/pal-for-developers-net). You’ll get hands-on cloud-native .NET training learn best practices when creating microservices and become a Steeltoe ninja! diff --git a/articles/writing-event-based-microservices-using-steeltoe.md b/articles/writing-event-based-microservices-using-steeltoe.md index 3e64cd94..47ac9ea9 100644 --- a/articles/writing-event-based-microservices-using-steeltoe.md +++ b/articles/writing-event-based-microservices-using-steeltoe.md @@ -18,4 +18,4 @@ author.name: Dave Tillman Join Steeltoe founder Dave Tillman in learning about the all new messaging component in Steeltoe v3. -> [!Video https://www.youtube.com/embed/Lk2TrvE5w8s] \ No newline at end of file +> [!Video https://www.youtube.com/embed/Lk2TrvE5w8s] diff --git a/build-metadata.sh b/build-metadata.sh old mode 100644 new mode 100755 index 8282f774..385456a5 --- a/build-metadata.sh +++ b/build-metadata.sh @@ -9,6 +9,7 @@ cd $base_dir git_sources_url=https://github.com/SteeltoeOSS/Steeltoe v2_sources=$(cat metadata.conf | grep '^2:' | cut -d: -f2) v3_sources=$(cat metadata.conf | grep '^3:' | cut -d: -f2) +v4_sources=$(cat metadata.conf | grep '^4:' | cut -d: -f2) build_dir=build get_sources() { @@ -20,12 +21,17 @@ get_sources() { } get_sources sources/v2 $v2_sources +get_sources sources/v3 $v3_sources +get_sources sources/v4 $v4_sources + echo "building v2 metadata" docfx metadata api-v2.json -get_sources sources/v3 $v3_sources echo "building v3 metadata" docfx metadata api-v3.json +echo "building v4 metadata" +docfx metadata api-v4.json + echo "building all metadata" docfx metadata api-all.json diff --git a/docfx.json b/docfx.json index 5208d150..83fbe9d5 100644 --- a/docfx.json +++ b/docfx.json @@ -6,6 +6,7 @@ "api/**.md", "api/v2/**/toc.yml", "api/v3/**/toc.yml", + "api/v4/**/toc.yml", "articles/**.md", "articles/**/toc.yml", @@ -19,6 +20,7 @@ "exclude": [ "**/amqp.md", "**/rabbitmq-binder.md", + "api/browser/v4/all/index.md", "api/browser/v3/all/index.md", "api/browser/v2/all/index.md" ] @@ -41,6 +43,15 @@ ], "version": "3.x" }, + { + "files": [ + "api/browser/v4/**.yml" + ], + "exclude": [ + "api/browser/v4/all/**.yml" + ], + "version": "4.x" + }, { "files": [ "api/browser/v2/all/index.md", @@ -54,6 +65,13 @@ "api/browser/v3/all/**.yml" ], "version": "3.all" + }, + { + "files": [ + "api/browser/v4/all/index.md", + "api/browser/v4/all/**.yml" + ], + "version": "4.all" } ], "resource": [ diff --git a/example-program.cs b/example-program.cs index 113cb135..2528af9a 100644 --- a/example-program.cs +++ b/example-program.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Steeltoe.Extensions.Configuration.ConfigServer; +using Steeltoe.Configuration.ConfigServer; namespace Simple { @@ -19,4 +19,4 @@ public static IWebHost BuildWebHost(string[] args) => #some other thing #endregion } -} \ No newline at end of file +} diff --git a/guides/application-configuration/cloud-foundry.md b/guides/application-configuration/cloud-foundry.md index 49586d77..b43732da 100644 --- a/guides/application-configuration/cloud-foundry.md +++ b/guides/application-configuration/cloud-foundry.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## App Configuration with Cloud Foundry This tutorial takes you through setting up a .NET Core application that retrieves environment variable values from Cloud Foundry. > [!NOTE] -> For more detailed examples, please refer to the [SimpleCloundFoundry](https://github.com/SteeltoeOSS/Samples/tree/main/Configuration/src/SimpleCloudFoundry) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [SimpleCloundFoundry](https://github.com/SteeltoeOSS/Samples/tree/3.x/Configuration/src/SimpleCloudFoundry) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **create a .NET Core WebAPI** that retrieves (configuration) environment variables from Cloud Foundry. diff --git a/guides/application-configuration/placeholder.md b/guides/application-configuration/placeholder.md index 999affdf..e96431c7 100644 --- a/guides/application-configuration/placeholder.md +++ b/guides/application-configuration/placeholder.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Application Configuration Placeholders This tutorial takes you through setting up a .NET Core application that uses placeholders for config values. > [!NOTE] -> For more detailed examples, please refer to the [Placeholder](https://github.com/SteeltoeOSS/Samples/tree/main/Configuration/src/Placeholder) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Placeholder](https://github.com/SteeltoeOSS/Samples/tree/3.x/Configuration/src/Placeholder) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **create a .NET Core WebAPI** that has a placeholder implemented diff --git a/guides/application-configuration/random-value.md b/guides/application-configuration/random-value.md index 5f78d479..e7c50a90 100644 --- a/guides/application-configuration/random-value.md +++ b/guides/application-configuration/random-value.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Application Configuration Random Values This tutorial takes you through setting up a .NET Core application that gets a random value for a config setting. > [!NOTE] -> For more detailed examples, please refer to the [RandomValue](https://github.com/SteeltoeOSS/Samples/tree/main/Configuration/src/RandomValue) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [RandomValue](https://github.com/SteeltoeOSS/Samples/tree/3.x/Configuration/src/RandomValue) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **create a .NET Core WebAPI** that has a placeholder implemented. diff --git a/guides/application-configuration/spring-config.md b/guides/application-configuration/spring-config.md index 18b25a18..592b467f 100644 --- a/guides/application-configuration/spring-config.md +++ b/guides/application-configuration/spring-config.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## App Configuration with a Spring Config Server This tutorial takes you through setting up a .NET Core application that gets configuration values from a Spring Config Server. > [!NOTE] -> For more detailed examples, please refer to the [Simple (Config Server)](https://github.com/SteeltoeOSS/Samples/tree/main/Configuration/src/Simple) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Simple (Config Server)](https://github.com/SteeltoeOSS/Samples/tree/3.x/Configuration/src/Simple) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **create a GitHub repository** to hold config values. diff --git a/guides/circuit-breaker/circuit-breaker.md b/guides/circuit-breaker/circuit-breaker.md index 4257d2bb..adf510e3 100644 --- a/guides/circuit-breaker/circuit-breaker.md +++ b/guides/circuit-breaker/circuit-breaker.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + ## Implementing Circuit Breakers This tutorial takes you through setting up a .NET Core application that implements a circuit breaker pattern. > [!NOTE] -> For more detailed examples, please refer to the [FortuneTeller (Circuit Breaker)](https://github.com/SteeltoeOSS/Samples/tree/main/CircuitBreaker/src/FortuneTeller) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [FortuneTeller (Circuit Breaker)](https://github.com/SteeltoeOSS/Samples/tree/3.x/CircuitBreaker/src/FortuneTeller) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). ### Start a instance of the Hystrix dashboard @@ -105,7 +108,7 @@ Navigate to the endpoint [http://localhost:5000/WeatherForecast](http://localhos 1. Navigate to the dashboard at [http://localhost:7979/hystrix](http://localhost:7979/hystrix) and enter the application stream url in the stream url text box (ex. [http://localhost:5000/hystrix/hystrix.stream](http://localhost:5000/hystrix/hystrix.stream)) Circuit Breaker Landing - + > NOTE: The stream url `http://localhost:5000/hystrix/hystrix.stream` will only work if the Hystrix dashboard is running on your local host. You will have to use a different URL, one that is accessible from Docker if you are running the dashboard using Docker. 1. Refresh the application in your browser a few times and go back to the dashboard to see it logging live activity. diff --git a/guides/cloud-management/distributed-tracing.md b/guides/cloud-management/distributed-tracing.md index 2bb487c7..3a1b520b 100644 --- a/guides/cloud-management/distributed-tracing.md +++ b/guides/cloud-management/distributed-tracing.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Distributed Tracing for debugging with Zipkin This tutorial takes you through setting up a .NET Core application that sends tracing data to a Zipkin server. > [!NOTE] -> For more detailed examples, please refer to the [Tracing](https://github.com/SteeltoeOSS/Samples/tree/main/Management/src/Tracing) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Tracing](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src/Tracing) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **start a Zipkin instance**. Depending on your hosting platform this is done in several ways. @@ -32,15 +35,6 @@ Next, **create a .NET Core WebAPI** that interacts with Distributed Tracing 1. Click **Generate Project** to download a zip containing the new project 1. Extract the zipped project and open in your IDE of choice 1. Add `Steeltoe.Management.TracingCore` NuGet package to your project - - ```xml - - ... - - ... - - ``` - 1. Add Distributed Tracing to your startup services ```csharp diff --git a/guides/cloud-management/endpoints-framework.md b/guides/cloud-management/endpoints-framework.md index 9e5e658a..5c05adbe 100644 --- a/guides/cloud-management/endpoints-framework.md +++ b/guides/cloud-management/endpoints-framework.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v2. Later Steeltoe versions do not support .NET Framework usage. + > [!TIP] > Looking for a .NET Core example? [Have a look](endpoints-netcore.md). @@ -14,7 +17,7 @@ _hideTocVersionToggle: true This tutorial takes you through setting up a ASP.NET 4.x Framework application with cloud management endpoints and dynamic logging levels enabled. > [!NOTE] -> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/main/Management/src) projects in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src) projects in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). **Create a .NET Framework Web API** project @@ -37,14 +40,14 @@ Next, **install packages** needed 1. Install NuGet distributed packages ```powershell - Install-Package -Id Microsoft.Extensions.Configuration -Version 2.2 - Install-Package -Id Microsoft.Extensions.Logging -Version 2.2 - Install-Package -Id Microsoft.Extensions.Logging.Console -Version 2.2 - Install-Package -Id OpenCensus -IncludePrerelease - Install-Package -Id Steeltoe.Extensions.Logging.DynamicLogger -Version 2.4 - Install-Package -Id Steeltoe.Management.EndpointBase -Version 2.4 - Install-Package -Id Steeltoe.Extensions.Configuration.CloudFoundryBase -Version 2.4 - Install-Package -Id Steeltoe.Management.EndpointWeb -Version 2.4 + Install-Package Microsoft.Extensions.Configuration + Install-Package Microsoft.Extensions.Logging + Install-Package Microsoft.Extensions.Logging.Console + Install-Package OpenCensus -IncludePrerelease + Install-Package Steeltoe.Extensions.Logging.DynamicLogger + Install-Package Steeltoe.Management.EndpointBase + Install-Package Steeltoe.Extensions.Configuration.CloudFoundryBase + Install-Package Steeltoe.Management.EndpointWeb ``` Next, **add actuators** support classes diff --git a/guides/cloud-management/endpoints-netcore.md b/guides/cloud-management/endpoints-netcore.md index 78d8a902..27645b91 100644 --- a/guides/cloud-management/endpoints-netcore.md +++ b/guides/cloud-management/endpoints-netcore.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + > [!TIP] > Looking for a .NET Framework example? [Have a look](endpoints-framework.md). @@ -14,7 +17,7 @@ _hideTocVersionToggle: true This tutorial takes you through setting up a .NET Core application with cloud management endpoints automatically added in. > [!NOTE] -> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/main/Management/src) projects in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src) projects in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). **Create a .NET Core WebAPI** with Actuators enabled diff --git a/guides/get-to-know-steeltoe/exercise1.md b/guides/get-to-know-steeltoe/exercise1.md index 3a87dd64..e6360da2 100644 --- a/guides/get-to-know-steeltoe/exercise1.md +++ b/guides/get-to-know-steeltoe/exercise1.md @@ -8,6 +8,9 @@ _disableNav: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + [exercise-1-link]: exercise1.md [exercise-2-link]: exercise2.md [exercise-3-link]: exercise3.md @@ -126,7 +129,7 @@ Add the distributed tracing feature to the service container: builder.Services.AddDistributedTracingAspNetCore(); ``` -With the addition of the distributed tracing option, under the covers, Steeltoe uses the OpenTelemetry specification to generate and propagate spans and traces throughout the application, as requests are received. No additional configuration is needed, but if you wanted to manipulate how traces and spans are created you could provide settings in "appsettings.json", [read the docs](/api/v3/tracing/index.html#configure-settings) for more information. +With the addition of the distributed tracing option, under the covers, Steeltoe uses the OpenTelemetry specification to generate and propagate spans and traces throughout the application, as requests are received. No additional configuration is needed, but if you wanted to manipulate how traces and spans are created you could provide settings in "appsettings.json", [read the docs](/api/v3/tracing/index.md#configure-settings) for more information. > [!TIP] > Having the combination of the logging actuator and distributed tracing enabled, Steeltoe will automatically append the application name, span Id, and trace Id on log messages when possible. This can be very handy when debugging a specific happening or error in production. @@ -179,7 +182,7 @@ Let's look at the health endpoint. Replace `WeatherForecast` with `actuator/heal ![Health endpoint](../images/health-endpoint.png) -As we discussed above, the fact that the page loaded (status of 200) is the first communication to the application's platform that it is healthy. Secondarily, the application has output information to help certain platforms gain a deeper knowledge of app health. Learn more about the health endpoint [here](/api/v3/management/health.html). +As we discussed above, the fact that the page loaded (status of 200) is the first communication to the application's platform that it is healthy. Secondarily, the application has output information to help certain platforms gain a deeper knowledge of app health. Learn more about the health endpoint [here](../../api/v3/management/health.md). ## Discover the info endpoint @@ -187,7 +190,7 @@ Now navigate to the info endpoint by replacing `health` with `info` in the addre ![Info endpoint](../images/info-endpoint.png) -We have loaded the bare minimum application info for this example. You could build your own `IInfoContributor` and add all kinds of metadata and connection information. Learn more [here](/api/v3/management/info.html). +We have loaded the bare minimum application info for this example. You could build your own `IInfoContributor` and add all kinds of metadata and connection information. Learn more [here](../../api/v3/management/info.md). ## Observe trace and spans appended to logs diff --git a/guides/get-to-know-steeltoe/exercise2.md b/guides/get-to-know-steeltoe/exercise2.md index 0a8775f1..6d2ecd37 100644 --- a/guides/get-to-know-steeltoe/exercise2.md +++ b/guides/get-to-know-steeltoe/exercise2.md @@ -8,6 +8,9 @@ _disableNav: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + [home-page-link]: index.md [exercise-1-link]: exercise1.md [exercise-2-link]: exercise2.md @@ -86,7 +89,7 @@ With the application running and the weather forecast endpoint loaded, your brow Load the base actuator endpoint by replacing `WeatherForecast` with `actuator` in the browser address bar. -What has happened? In the previous exercise, only select endpoints were implemented and we visited each in the browser to see their output. There was no need to expose those endpoints, because Steeltoe doesn't secure them by default ([you should use security in production environments](/api/v3/management/using-endpoints.html#securing-endpoints)). With the addition of all endpoints, most are secured by default. You pick and choose which should be exposed and with what roles. Here's a list of each endpoint that is available and its purpose. While the application is running, visit each one to learn more. +What has happened? In the previous exercise, only select endpoints were implemented and we visited each in the browser to see their output. There was no need to expose those endpoints, because Steeltoe doesn't secure them by default ([you should use security in production environments](../../api/v3/management/using-endpoints.md#securing-endpoints)). With the addition of all endpoints, most are secured by default. You pick and choose which should be exposed and with what roles. Here's a list of each endpoint that is available and its purpose. While the application is running, visit each one to learn more. - `/actuator`: A JSON structured list of all actuator endpoints that have been exposed. - `/actuator/env`: A listing of all environment variables that are available to the app. diff --git a/guides/get-to-know-steeltoe/exercise3.md b/guides/get-to-know-steeltoe/exercise3.md index 455cc405..75e9d0e5 100644 --- a/guides/get-to-know-steeltoe/exercise3.md +++ b/guides/get-to-know-steeltoe/exercise3.md @@ -8,6 +8,9 @@ _disableNav: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + [home-page-link]: index.md [exercise-1-link]: exercise1.md [exercise-2-link]: exercise2.md @@ -258,7 +261,7 @@ Add the below JSON to 'appsettings.json', just after the 'management' section. T ## Review what was done -Before we see everything in action, let's review what has been done. With the Steeltoe EFCore package added, we created a definition of a database context and list item. Then we registered them at startup in the dependency injection container. Instead of bringing in the typical SqlClient packages to help define things, we used `Steeltoe.Connector.SqlServer.EFCore`. This package not only has all the needed sub-packages included, but also introduces another way of configuring server settings. To learn more about what values can be customized, [have a look at the docs](/api/v3/connectors/microsoft-sql-server.html). In our example, we're using the default port of `1433` and a server name of `localhost`. If you wanted the app to connect to a SQL database hosted elsewhere you could provide different values, or rely on built-in support for [service bindings](/api/v3/connectors/usage.md#cloud-foundry). Also, we've provided the required credentials and server name in `appsettings.json`. The database name will be derived from our ToDo database context. The key is to give the Steeltoe connector a valid healthy connection to a SQL instance, it will do the rest. +Before we see everything in action, let's review what has been done. With the Steeltoe EFCore package added, we created a definition of a database context and list item. Then we registered them at startup in the dependency injection container. Instead of bringing in the typical SqlClient packages to help define things, we used `Steeltoe.Connector.SqlServer.EFCore`. This package not only has all the needed sub-packages included, but also introduces another way of configuring server settings. To learn more about what values can be customized, [have a look at the docs](../../api/v3/connectors/microsoft-sql-server.md). In our example, we're using the default port of `1433` and a server name of `localhost`. If you wanted the app to connect to a SQL database hosted elsewhere you could provide different values, or rely on built-in support for [service bindings](../../api/v3/connectors/usage.md#cloud-foundry). Also, we've provided the required credentials and server name in `appsettings.json`. The database name will be derived from our ToDo database context. The key is to give the Steeltoe connector a valid healthy connection to a SQL instance, it will do the rest. ## Run the application diff --git a/guides/get-to-know-steeltoe/exercise4.md b/guides/get-to-know-steeltoe/exercise4.md index 9fec7160..8bbce246 100644 --- a/guides/get-to-know-steeltoe/exercise4.md +++ b/guides/get-to-know-steeltoe/exercise4.md @@ -8,6 +8,9 @@ _disableNav: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + [home-page-link]: index.md [exercise-1-link]: exercise1.md [exercise-2-link]: exercise2.md @@ -181,7 +184,7 @@ Use the key combination "Ctrl+C" on Windows/Linux or "Cmd+C" on Mac. With an existing Spring Config server running that was configured to retrieve values from a YAML file, we added a Spring Config client to our application and output the retrieved values. With this architecture in place, you can now do things like update the YAML file and visit the `/actuator/refresh` management endpoint in the application. This will automatically refresh values within the application, without downtime (or restart). You could store a server's connection name in the YAML and have the application retrieve the value. As the application moves through different environments (dev, test, staging, prod) the connection value can change, but the original tested application stays unchanged. -We've just begun to scratch the surface of what Spring Cloud Config Server can really do and all its many features. Learn more about [using Spring Cloud Config Server with Steeltoe](/api/v3/configuration/config-server-provider.html). +We've just begun to scratch the surface of what Spring Cloud Config Server can really do and all its many features. Learn more about [using Spring Cloud Config Server with Steeltoe](../../api/v3/configuration/config-server-provider.md). | [<< Previous Exercise][exercise-3-link] | [Workshop Summary >>][summary-link] | | :-------------------------------------- | ----------------------------------: | diff --git a/guides/get-to-know-steeltoe/index.md b/guides/get-to-know-steeltoe/index.md index 7109c290..e8b592a0 100644 --- a/guides/get-to-know-steeltoe/index.md +++ b/guides/get-to-know-steeltoe/index.md @@ -10,6 +10,9 @@ tags: ["get-started"] _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + [exercise-1-link]: exercise1.md [exercise-2-link]: exercise2.md [exercise-3-link]: exercise3.md diff --git a/guides/get-to-know-steeltoe/summary.md b/guides/get-to-know-steeltoe/summary.md index 675500a6..fc1346a4 100644 --- a/guides/get-to-know-steeltoe/summary.md +++ b/guides/get-to-know-steeltoe/summary.md @@ -8,6 +8,9 @@ _disableNav: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + [exercise-1-link]: exercise1.md [exercise-2-link]: exercise2.md [exercise-3-link]: exercise3.md diff --git a/guides/index.md b/guides/index.md index 247c5240..390b4cc4 100644 --- a/guides/index.md +++ b/guides/index.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> These guides apply to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + # Get Started with Steeltoe ## The Basics Workshop diff --git a/guides/messaging/Tutorials/Tutorial1/Readme.md b/guides/messaging/Tutorials/Tutorial1/Readme.md index e8d2c94c..6a703264 100644 --- a/guides/messaging/Tutorials/Tutorial1/Readme.md +++ b/guides/messaging/Tutorials/Tutorial1/Readme.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + ## Hello World Tutorial (using Steeltoe) > **Prerequisites** @@ -73,14 +76,14 @@ Messaging library to help simplify the code we write while creating our messagin We have also chosen to use Visual Studio 2022 to edit and build the project; but we could have just as easily chosen VSCode. -The [source code of the tutorials](https://github.com/steeltoeoss/samples/tree/main/messaging/tutorials) +The [source code of the tutorials](https://github.com/SteeltoeOSS/Samples/tree/3.x/messaging/tutorials) is available online. You can either just run the finished tutorials or you can do the tutorials from scratch by following the steps outlined in each of tutorial writeups. If you choose to start from scratch, open Visual Studio and create a new **Console** application using the VS2022 template: ![ConsoleApp](~/guides/images/messaging/VS2022NewConsoleApp.png) -Name the project `Receiver` and select a directory location such as `c:\workspace\Tutorials`. +Name the project `Receiver` and select a directory location such as `c:\workspace\Tutorials`. Choose a solution name of `Tutorial1` and uncheck the `Place solution and project in the same directory` as you will be adding another project to this solution next. @@ -98,13 +101,9 @@ When you are done with the above, add a new class to the `Receiver` project. Name this class `Tut1Receiver`; this will be the class we use to receive messages from the sender. -Next, in the `Sender` project, rename the `Worker.cs` file to `Tut1Sender.cs`. - -Finally, in both of the projects `.csproj` files add the Steeltoe RabbitMQ Messaging package reference. Below is an example of the reference. +Next, in the `Sender` project, rename the `Worker.cs` file to `Tut1Sender.cs`. -```xml - -``` +Finally, in both of the projects `.csproj` files add the `Steeltoe.Messaging.RabbitMQ` NuGet package reference. After these changes your solution should look something like the following: @@ -118,7 +117,7 @@ First, Steeltoe RabbitMQ Messaging applications have the option of using the `Ra Specifically it adds and configures the following Steeltoe services: -- `RabbitTemplate` - used to send (i.e. **producer**) and receive (i.e. **consumer**) messages. +- `RabbitTemplate` - used to send (i.e. **producer**) and receive (i.e. **consumer**) messages. - `RabbitAdmin` - used to administer (i.e. create, delete, update, etc.) RabbitMQ entities (i.e. Queues, Exchanges, Bindings, etc.). At application startup the `RabbitAdmin` looks for any RabbitMQ entities that have been added in the service container and attempts to define them in the broker. - `RabbitListener Attribute processor` - processes all `RabbitListener` attributes and creates `RabbitContainers` (i.e.**consumers**) for each `RabbitListener`. - `Rabbit Container Factory` - a component used to create and manage all the `RabbitContainer`s (i.e.**consumers**) in the application @@ -136,7 +135,7 @@ RabbitMQHost.CreateDefaultBuilder(args) Next use the `.ConfigureServices()` method on the returned builder to further configure the services in the host. -First use the Steeltoe extension method `.AddRabbitQueue(...)` to add a `Queue` in the service container. We do this so that the `RabbitAdmin` will find it and at startup use it to create and configure the queue for us on the broker. +First use the Steeltoe extension method `.AddRabbitQueue(...)` to add a `Queue` in the service container. We do this so that the `RabbitAdmin` will find it and at startup use it to create and configure the queue for us on the broker. ```csharp // Add queue to service container to be declared at startup @@ -259,7 +258,7 @@ namespace Sender } } } -} +} ``` You'll notice that Steeltoe removes the typical boilerplate .NET code needed to send and receive messages diff --git a/guides/messaging/Tutorials/Tutorial2/Readme.md b/guides/messaging/Tutorials/Tutorial2/Readme.md index 719007ba..5fc0916b 100644 --- a/guides/messaging/Tutorials/Tutorial2/Readme.md +++ b/guides/messaging/Tutorials/Tutorial2/Readme.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + ## Work Queues Tutorial (using Steeltoe) > **Prerequisites** @@ -245,7 +248,7 @@ The second change you should see is in how we reference the queue in the `Rabbit [RabbitListener(Queue = "#{@hello}")] ``` -This syntax uses a Steeltoe feature that leverages a built in `expression language` that is executed when the `Rabbit Container` is created. To use the language, you enclose the `expression` inside a `#{...}` as shown above. In this case the expression is `@hello`. The `@` symbol is part of the language; it is used to specify a reference to a service from the service container. What follows the `@` symbol is interpreted as the name of the service in the container you wish to reference. In this case, the service name `hello` is specified, and it is the name of the `Queue` that was added to the service container using the `[DeclareQueue(..)]` attribute we mentioned above. +This syntax uses a Steeltoe feature that leverages a built in `expression language` that is executed when the `Rabbit Container` is created. To use the language, you enclose the `expression` inside a `#{...}` as shown above. In this case the expression is `@hello`. The `@` symbol is part of the language; it is used to specify a reference to a service from the service container. What follows the `@` symbol is interpreted as the name of the service in the container you wish to reference. In this case, the service name `hello` is specified, and it is the name of the `Queue` that was added to the service container using the `[DeclareQueue(..)]` attribute we mentioned above. This is how the `RabbitListener` attribute ties the `Receive(..)` method to the `hello` queue declared above. diff --git a/guides/messaging/Tutorials/Tutorial3/Readme.md b/guides/messaging/Tutorials/Tutorial3/Readme.md index 3e0a329b..7a99bc18 100644 --- a/guides/messaging/Tutorials/Tutorial3/Readme.md +++ b/guides/messaging/Tutorials/Tutorial3/Readme.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + ## Publish/Subscribe Tutorial (using Steeltoe) > **Prerequisites** @@ -88,7 +91,7 @@ namespace Receiver public Tut3Receiver(ILogger logger) { _logger = logger; - } + } .... } } @@ -153,7 +156,7 @@ namespace Sender _logger = logger; _rabbitTemplate = rabbitTemplate; } - + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) @@ -210,7 +213,7 @@ namespace Receiver public Tut3Receiver(ILogger logger) { _logger = logger; - } + } .... } } @@ -248,7 +251,7 @@ namespace Receiver public Tut3Receiver(ILogger logger) { _logger = logger; - } + } .... } } @@ -294,7 +297,7 @@ namespace Sender _logger = logger; _rabbitTemplate = rabbitTemplate; } - + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) diff --git a/guides/messaging/Tutorials/Tutorial4/Readme.md b/guides/messaging/Tutorials/Tutorial4/Readme.md index e4bf7e35..3d514cef 100644 --- a/guides/messaging/Tutorials/Tutorial4/Readme.md +++ b/guides/messaging/Tutorials/Tutorial4/Readme.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + ## Routing Tutorial (using Steeltoe) > **Prerequisites** @@ -44,7 +47,7 @@ Remember, a binding is a relationship between an exchange and a queue. This can be simply read as: the queue is interested in messages from this exchange. -Bindings can take an extra routing key parameter which we didn't use in the previous tutorial. +Bindings can take an extra routing key parameter which we didn't use in the previous tutorial. We can specify the key using the `RoutingKey` property on the `DeclareQueueBinding` attribute as shown below: ```csharp diff --git a/guides/messaging/Tutorials/Tutorial5/Readme.md b/guides/messaging/Tutorials/Tutorial5/Readme.md index 1d3a7267..d6a43f49 100644 --- a/guides/messaging/Tutorials/Tutorial5/Readme.md +++ b/guides/messaging/Tutorials/Tutorial5/Readme.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + ## Topics Tutorial (using Steeltoe) > **Prerequisites** @@ -231,12 +234,12 @@ namespace Sender private int index = 0; private int count = 0; - private readonly string[] keys = new string[] { - "quick.orange.rabbit", - "lazy.orange.elephant", + private readonly string[] keys = new string[] { + "quick.orange.rabbit", + "lazy.orange.elephant", "quick.orange.fox", - "lazy.brown.fox", - "lazy.pink.rabbit", + "lazy.brown.fox", + "lazy.pink.rabbit", "quick.brown.fox"}; public Tut5Sender(ILogger logger, RabbitTemplate rabbitTemplate) diff --git a/guides/messaging/Tutorials/Tutorial6/Readme.md b/guides/messaging/Tutorials/Tutorial6/Readme.md index 0e6a9f5c..cb105e56 100644 --- a/guides/messaging/Tutorials/Tutorial6/Readme.md +++ b/guides/messaging/Tutorials/Tutorial6/Readme.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + ## Remote Procedure Call Tutorial (using Steeltoe) > **Prerequisites** @@ -76,7 +79,7 @@ request. Steeltoe's `RabbitTemplate` handles the callback queue for us when we use the above `ConvertSendAndReceiveAsync()` method. There is no need to do any other setup when using the `RabbitTemplate`. For a thorough explanation please see -[Request/Reply Message](https://docs.steeltoe.io/api/v3/messaging/rabbitmq-reference.html#request-and-reply-messaging). +[Request/Reply Message](../../../../api/v3/messaging/rabbitmq-reference.md#request-and-reply-messaging). > **Message properties** > diff --git a/guides/messaging/Tutorials/Tutorial7/Readme.md b/guides/messaging/Tutorials/Tutorial7/Readme.md index 60a187d4..432e463d 100644 --- a/guides/messaging/Tutorials/Tutorial7/Readme.md +++ b/guides/messaging/Tutorials/Tutorial7/Readme.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + ## Publisher Confirms Tutorial (using Steeltoe) > **Prerequisites** diff --git a/guides/modernize-dotnet/buildpacks.md b/guides/modernize-dotnet/buildpacks.md deleted file mode 100644 index f6ddc421..00000000 --- a/guides/modernize-dotnet/buildpacks.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -uid: guides/modernize-dotnet/buildpacks -_disableContribution: true -_disableToc: true -_disableFooter: true -_homePath: "./" -_disableNav: true ---- - -[exercise-1-link]: exercise1.md -[buildpacks-link]: buildpacks.md -[exercise-2-link]: exercise2.md - -| [<< Prev][exercise-2-link] | | -| :------------------------- | --: | - -# Extra Context: Buildpacks in-depth - -A `buildpack` is an artifact that configures or provides your app's hosting environment. For example, the `HWC_BUILDPACK` provides the Hostable Web Core for IIS app support. - -Buildpacks come in two flavors: - -1. A `supply builpack` helps bootstrap your app's dependencies for startup. -1. A `final buildpack` is responsible for launching your app - - The HWC_BUILDPACK is an example of a `final buildpack`. - -Buildpacks provide a series of scripts for the platform to invoke during the buildpack detection and execution phases. These scripts are referred to as `hooks`. - -#### Lifecycle - -A `buildpack` is run by the platform prior to app instance startup if either of the following conditions are met: - -1. The buildpack's `detect` hook returns true (implicit) - - Drives the app detection that allows us to `cf push` certain app types without specifying a buildpack. -2. The buildpack is specified in the manifest (explicit) - - Most common use-case in a prod environment - -If a buildpack is detected or specified in the manifest, the buildpack's remaining hooks will be invoked: - -1. `supply`: - - Dependency injection, environment setup. - - Must be implemented by each `supply buildpack` -2. `finalize` - - Provide app startup concerns (webserver, etc.) - - Must be implemented by `final buildpack` -3. `release` - - Provide metadata to control app startup - out of scope for today. - -#### Composability - -Multi-buildpack allows us to compose an app startup pipeline where `supply buildpacks` are invoked in the order provided prior to the `final buildpack`, which starts the app. - -- Analogous to Middleware concept in WebAPI - -Multi-buildpack can be specified in yml: - -```yml ---- -applications: - - stack: windows - instances: 1 - buildpacks: - - first_supply_buildpack - - second_supply_buildpack - - final_buildpack -``` - -Or, via command line: - -```CLI -cf push APP-NAME -b FIRST-BUILDPACK -b SECOND-BUILDPACK -b FINAL-BUILDPACK -``` - -#### Redis Buildpack - -If you've ever pushed an app to Cloud Foundry that started successfully, you've already made use of a `final buildpack`. In our sample web app, we've chosen to use the HWC_BUILDPACK as our `final buildpack` because the app we're pushing is a full framework .NET app. And, while the HWC_BUILDPACK has solved our problem of getting our app to run on TAS, it has revealed a new problem regarding our app's design: its use of in-proc session. Thankfully, there's a `supply buildpack` for that, and it's called the Redis for Session Buildpack. - -The Redis for Session Buildpack does a very simple trick: when its `supply` hook is invoked, the buildpack transforms your app's web.config and replaces use of in-proc session with use of a Redis backed session. For the buildpack to be effective, we must do three things to our app: - -1. Add the Redis for Session buildpack to our manifest as a supply buildpack -2. Add the RedisSessionStateProvider nuget package to our app. -3. Bind our app to a Redis service instance. - -When the app is pushed with the buildpack, the Redis buildpack will lookup the details for connecting to Redis; this is only possible because we've bound our app to a Redis service instance. If no Redis instances are found by the buildpack during startup, the web.config will not be modified. - -Assuming Redis is bound to the app, the buildpack will then transform the app's web.config, replacing the in-proc session configuration with a complete and credentialed configuration for using Redis intsead. For this to work, the buildpack must find the RedisSessionStateProvider in your app's bin directory; if the provider is not found, the web.config will not be modified. - -If we've followed the happy path (installed the nuget and added a redis service to our manifest), the next time we push our app, horizontal scale wont' be a concern even with our reliance on session. - -[https://github.com/cloudfoundry-community/redis-session-aspnet-buildpack](https://github.com/cloudfoundry-community/redis-session-aspnet-buildpack) - -##### Some caveats - -The .NET framework requires that objects stored in session state must be serializable; the one exception to this rule is if session is maintained in process. If your app was not designed with externalization of session in mind, you may encounter exceptions for any objects stored in session that cannot be serialized. - -| [<< Prev>][exercise-2-link] | | -| :-------------------------- | --: | diff --git a/guides/modernize-dotnet/exercise1.md b/guides/modernize-dotnet/exercise1.md deleted file mode 100644 index dffbd0ee..00000000 --- a/guides/modernize-dotnet/exercise1.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -uid: guides/modernize-dotnet/exercise1 -_disableContribution: true -_disableToc: true -_disableFooter: true -_homePath: "./" -_disableNav: true ---- - -[exercise-1-link]: exercise1.md -[exercise-2-link]: exercise2.md -[modernize-frontend-newmanifest]: ~/guides/images/modernize-frontend-newmanifest.png "Create a new manifest for the frontend" -[modernize-frontend-publish]: ~/guides/images/modernize-frontend-publish.png "Publish the frontend" -[modernize-frontend-publish2]: ~/guides/images/modernize-frontend-publish2.png "Publish the frontend" -[modernize-frontend-cfapp]: ~/guides/images/modernize-frontend-cfapp.png "Find the URL your application will respond on" -[modernize-service-newmanifest]: ~/guides/images/modernize-service-newmanifest.png "Create a manifest for the backend service" -[modernize-service-result]: ~/guides/images/modernize-service-result.png "Results of the service" -[modernize-frontend-result]: ~/guides/images/modernize-frontend-result.png "Results of the service as consumed by the frontend" - -| | [Next Exercise >>][exercise-2-link] | -| :-- | ----------------------------------: | - -# Exercise 1 - -## Goal - -Simulate an IIS Virtual Directory structure with routes in TAS - -## Expected Results - -1. Web API Service running on /api -1. Web front end running on / - -## Get Started - -### Deploy the frontend application - -Using VS Code, create a manifest file for the web frontend named `manifest.yml` in the `WorkshopFrontEnd` directory. In this case every field can remain the same as the example. - -


-![modernize-frontend-newmanifest] -


- -With the following content - -```yaml ---- -applications: - - instances: 1 - memory: 384M - path: bin/app.publish/ - buildpacks: - - hwc_buildpack -``` - -In Visual Studio publish the application to the Folder profile by right-clicking the `WorkshopFrontEnd` project, selecting `Publish`, and clicking the `Publish` button on the right. - -


-![modernize-frontend-publish] -


-![modernize-frontend-publish2] -


- -In Powershell change directory to `WorkshopFrontEnd` (the directory containing `WorkshopFrontEnd.csproj`). Then Push the web app to cloud foundry. Supply your own value for <front-end-app-name> that would likely be unique amoungst your classmates, like `john-q-smith-1990`. Ensure the Windows stack is targetting by setting the `-s` parameter to `windows`. - -```powershell -cd c:\Users\WorkshopStudent\src\Workshop\WorkshopFrontEnd -cf push -s windows -``` - -Find the url for your application by visitng it's route in a web browser. You can retrieve the route with - -```powershell -cf app -``` - -


-![modernize-frontend-cfapp] -


- -Select `ViewCounter` from the top menu of the web application. See the counter increments with every refresh. Do this 10 times or so to verify. - -### Deploy the API (optional, for more advanced CF users) - -Using VS Code, create a manifest file named `manifest.yml` for the backend in the `WorkshopService` directory. In the begining of the route place the URL used by the frontend application without the protocol i.e. `john-q-smith-1990.cfapps.io`. Ensure the route has `/api` after the domain name. This instructs cloud foundry to send all requests to the `/api` context path to the backend service while all other requests are routed to the front. - -Notes: - -- Your frontend app and api must be named differently -- The frontend's route was set automatically -- We'll set the route for the backend manually -- The api's route should be set to the same as the frontend's with `/api` at the end. - -


-![modernize-service-newmanifest] -


- -``` ---- -applications: -- instances: 1 - memory: 384M - path: bin/app.publish/ - buildpacks: - - hwc_buildpack - routes: - - route: /api -``` - -Publish the application to the Folder profile by right-clicking the `WorkshopService` project, selecting `Publish`, and clicking the `Publish` button on the right. - -In powershell change directory to `WorkshopService` (the directory containing `WorkshopService.csproj`) then push the service to cloud foundry. Since you're sharing a space with your classmates you'll need to ensure the name is unique. Also, ensure the app name is DIFFERENT than front end. Note that outside of the classroom each deployment of the application would likely have a different space. - -```powershell -cd c:\Users\WorkshopStudent\src\Workshop\WorkshopService -cf push -s windows -``` - -Verify the service is working by visiting `https:///api/values` in your web browser. Note that in the absense of special headers you may get an XML response. - -


-![modernize-service-result] -


- -Now validate that the frontend is consuming the API by visiting `https:///Home/ApiClient` in your web browser. If you see `one two three` in the results then everythign is working. You've recreated an IIS virtual directory structure using Cloud Foundry routes! - -


-![modernize-frontend-result] -


- -Note that in practice you can mix and match technologies behind context routes. For instance your `/api` could be a Java/Spring application and your front end at the root could be dotnet core, ASP.NET, or whatever you like. - -| | [Next Exercise >>][exercise-2-link] | -| :-- | ----------------------------------: | diff --git a/guides/modernize-dotnet/exercise2.md b/guides/modernize-dotnet/exercise2.md deleted file mode 100644 index 383122e0..00000000 --- a/guides/modernize-dotnet/exercise2.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -uid: guides/modernize-dotnet/exercise2 -_disableContribution: true -_disableToc: true -_disableFooter: true -_homePath: "./" -_disableNav: true ---- - -[exercise-1-link]: exercise1.md -[exercise-2-link]: exercise2.md -[buildpacks-link]: buildpacks.md -[modernize-redis-servicelist]: ~/guides/images/modernize-redis-servicelist.png "Get a list of services running in your space" -[modernize-frontend-addnuget]: ~/guides/images/modernize-frontend-addnuget.png "Add a nuget reference " -[modernize-frontend-selectnuget]: ~/guides/images/modernize-frontend-selectnuget.png "Select nuget reference for Microsoft.Web.RedisSessionStateProvider" -[modernize-frontend-nugetinstall]: ~/guides/images/modernize-frontend-nugetinstall.png "Install Microsoft.Web.RedisSessionStateProvider" -[modernize-frontend-publish]: ~/guides/images/modernize-frontend-publish.png "Publish the frontend" -[modernize-frontend-publish2]: ~/guides/images/modernize-frontend-publish2.png "Publish the frontend" - -| [<< Previous Exercise][exercise-1-link] | [Next Buildpacks >>][buildpacks-link] | -| :-------------------------------------- | ------------------------------------: | - -# Exercise 2 - -## Goal - -Switch InProc session state to redis-backed with minimal code changes - -## Expected Results - -View counter increments with every request, regardless of how many instances are running - -## Get Started - -### Scale the frontend - -Let's return our attention to the frontend. In powershell scale the application from a single instance to two. - -```powershell -cf scale -i 2 -``` - -Visit the `ViewCounter` in a browser and hit refresh several times. Observe that the counter isn't incrementing on every request. This is because each instance is storing its own session state in memory. Our session-level view counter is broken! - -## Fixing things with Redis - -Now we'll fix the application by externalizing the session to Redis. We'll use a community-maintained buildpack to deal with the discovery and configuration of the Redis service and session provider. We won't have to write any code to make this happen! - -### Verify our Redis service is running - -Under normal conditions you'd have to create an instance of the `rediscloud` service from the Cloud Foundry marketplace. This lab provides you with an instance, however. -You can verify its existance with: - -```powershell -cf services -``` - -and you'd expect to see an output like this: - -


-![modernize-redis-servicelist] -


- -Ensure that you see a service named `session` of type `rediscloud`. In practice, the name isn't important, but `session` is what we'll use for this exercise. For this lab you only have to verify that the service exists. - -### Add a nuget reference to the Redis Session Provider - -Add a nuget reference to `Microsoft.Web.RedisSessionStateProvider` and rebuild the application by right-clicking on the `WorkshopFrontEnd` project and selecting "Manage Nuget Packages". - -


-![modernize-frontend-addnuget] -


- -Then select "Browse" at the top of the screen and search for `Microsoft.Web.RedisSessionStateProvider`. - -


-![modernize-frontend-selectnuget] -


- -Select the entry of the appropriate name (it should be at the top of the search results) and then select `Install`. - -


-![modernize-frontend-nugetinstall] -


- -Accept the license and rebuild the application. - -### Publish - -Now you can re-publish the frontend application to the Folder profile by right-clicking the `WorkshopFrontEnd` project, selecting `Publish`, and clicking the `Publish` button on the right. - -


-![modernize-frontend-publish] -


- -Ensure the `Folder` profile is selected and click `Install`. - -


-![modernize-frontend-publish2] -


- -### Update manifest - -Bind the application to redis by adding a `services` entry to your frontend's manifest that matches the name of the redis service we observed earlier. For this lab we named it "session". - -```yaml ---- -applications: - - instances: 2 - memory: 384M - path: bin/app.publish/ - buildpacks: - - hwc_buildpack - services: - - session -``` - -Add the redis session buildpack by putting the link `https://github.com/cloudfoundry-community/redis-session-aspnet-buildpack/releases/download/v1.0.5/Pivotal.Redis.Aspnet.Session.Buildpack-win-x64-1.0.5.zip` in a list entry of the `buildpacks` element. - -```yaml ---- -applications: - - memory: 384M - instances: 2 - path: bin/app.publish/ - buildpacks: - - https://github.com/cloudfoundry-community/redis-session-aspnet-buildpack/releases/download/v1.0.5/Pivotal.Redis.Aspnet.Session.Buildpack-win-x64-1.0.5.zip - - hwc_buildpack - services: - - session -``` - -### Deploy - -Push the web app to cloud foundry targetting the Windows stack - -```powershell -cd c:\Users\WorkshopStudent\src\Workshop\WorkshopFrontEnd -cf push -s windows -``` - -### See your results - -Now visit the `ViewCounter` in a browser again. Again, the first few requests might be slow while your application is waking up. See that the view counts are incerementing correctly now? - -### Clean up - -Please delete your instances when you're done. Note the `-r` switch. That cleans up your routes. - -```powershell -cf delete -r -cf delete -r -``` - -| [<< Previous Exercise][exercise-1-link] | [Next Buildpacks >>][buildpacks-link] | -| :-------------------------------------- | ------------------------------------: | diff --git a/guides/modernize-dotnet/index.md b/guides/modernize-dotnet/index.md deleted file mode 100644 index 23c308f4..00000000 --- a/guides/modernize-dotnet/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -_disableContribution: true -_disableFooter: true -_homePath: "./" -_disableNav: true -uid: guides/modernize-dotnet ---- - -[strigo-desktop-vs]: ~/guides/images/strigo-desktop-vs.png "Strigo windows placement with Visual Studio" -[exercise-1-link]: exercise1.md -[exercise-2-link]: exercise2.md - -## Spring One Workshops - Modernizing .NET Applications with VMware Tanzu Application Service - -In this workshop we’re going to perform a lightweight modernization of a fictitious full framework ASP.NET MVC application who's front-end consumes a WebAPI backend. The application is presumed to run on IIS today using standard virtual or physical infrastructure and our task is to migrate the application to Cloud Foundry. Our modernization efforts will involve building the necessary artifacts to get the application to run at all in the cloud and to allow the application to scale once it gets there. - -All the while we’ll try to use a lightweight approach and make as few changes to application code as possible. - -## Current State - -Our sample application for this working is a single solution containing two projects. The first project is a WebAPI project exposing a single endpoint. The second project is an ASP.NET MVC front-end that consumes the WebAPI endpoint from JavaScript. - -The application is designed with an IIS topology in mind with both applications sharing a common hostname, the frontend responding to the root, and the backend living in a virtual directory located at the path “/api”. - -The frontend exposes an endpoint that tracks session-level view counts and is configured to use “InProc” session state. - -## Desired State: - -Our goals are - -1. Get this application operational on Cloud Foundry - -1. Ensure the application is scalable - -1. Use solutions that are minimally invasive to the code base - -## Lab Details: - -- $HOME\src contains the solution. -- Your CF CLI is already authenticated - -| [Get started][exercise-1-link] | -| :----------------------------: | diff --git a/guides/observability/grafana.md b/guides/observability/grafana.md index 5aea6467..066ac291 100644 --- a/guides/observability/grafana.md +++ b/guides/observability/grafana.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Grafana for app container metrics, distributed tracing, and observability This tutorial takes you creating a simple Steeltoe app with actuators, logging, and distributed tracing. With that app running you then export the data to an instance of Prometheus and visualize things in a Grafana dashboard. > [!NOTE] -> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/main/Management/src) solution in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src) solution in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **clone to accompanying repo** that contains all the needed assets diff --git a/guides/observability/tanzu.md b/guides/observability/tanzu.md index 3b5b6903..994a5d2b 100644 --- a/guides/observability/tanzu.md +++ b/guides/observability/tanzu.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Tanzu App Manager for app container metrics, distributed tracing, and observability This tutorial takes you creating a simple Steeltoe app with actuators, logging, and distributed tracing. With that app running you then export the data to a Tanzu Application Services foundation. > [!NOTE] -> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/main/Management/src) solution in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src) solution in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). ### Prereq's diff --git a/guides/observability/wavefront.md b/guides/observability/wavefront.md index bba8d415..0d76fc34 100644 --- a/guides/observability/wavefront.md +++ b/guides/observability/wavefront.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + ## Using Wavefront for app container metrics, distributed tracing, and observability This tutorial takes you creating a simple Steeltoe app with actuators, logging, and distributed tracing. With that app running you then export the data to a Wavefront account. > [!NOTE] -> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/main/Management/src) solution in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Management](https://github.com/SteeltoeOSS/Samples/tree/3.x/Management/src) solution in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). ### Prereq's diff --git a/guides/security/jwt.md b/guides/security/jwt.md index 58bbb44f..bd4c6e0b 100644 --- a/guides/security/jwt.md +++ b/guides/security/jwt.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using JWT Bearer Tokens -Please refer to our [sample app on GitHub](https://github.com/SteeltoeOSS/Samples/tree/main/Security/src/CloudFoundryJwtAuthentication) for detailed directions on using JWT and Cloud Foundry. +Please refer to our [sample app on GitHub](https://github.com/SteeltoeOSS/Samples/tree/3.x/Security/src/CloudFoundryJwtAuthentication) for detailed directions on using JWT and Cloud Foundry. diff --git a/guides/security/redisstore.md b/guides/security/redisstore.md index 2097f023..8242723f 100644 --- a/guides/security/redisstore.md +++ b/guides/security/redisstore.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Cloud Security with a Redis Cache for key ring store This tutorial takes you through setting up a .NET Core application that stores its master keys used to protect payloads in an external Redis cache. Learn more about ASP.NET data protection [here](https://docs.microsoft.com/en-us/aspnet/core/security/data-protection). > [!NOTE] -> For more detailed examples, please refer to the [RedisDataProtectionKeyStore](https://github.com/SteeltoeOSS/Samples/tree/main/Security/src/RedisDataProtectionKeyStore) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [RedisDataProtectionKeyStore](https://github.com/SteeltoeOSS/Samples/tree/3.x/Security/src/RedisDataProtectionKeyStore) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **start a Redis instance**. Using the [Steeltoe dockerfile](https://github.com/steeltoeoss/dockerfiles), start a local instance of RedisStore. diff --git a/guides/security/sso-oauth.md b/guides/security/sso-oauth.md index 3165e1dc..2fba4e25 100644 --- a/guides/security/sso-oauth.md +++ b/guides/security/sso-oauth.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Cloud Foundry SSO with OAuth2 provider -Please refer to our [sample app on GitHub](https://github.com/SteeltoeOSS/Samples/tree/main/Security/src/CloudFoundrySingleSignon) for detailed directions on using Single Sign-on with OAuth2 and Cloud Foundry. +Please refer to our [sample app on GitHub](https://github.com/SteeltoeOSS/Samples/tree/3.x/Security/src/CloudFoundrySingleSignon) for detailed directions on using Single Sign-on with OAuth2 and Cloud Foundry. diff --git a/guides/security/sso-openid-framework.md b/guides/security/sso-openid-framework.md index bcef5db4..a207a51b 100644 --- a/guides/security/sso-openid-framework.md +++ b/guides/security/sso-openid-framework.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v2. Later Steeltoe versions do not support .NET Framework usage. + ## Using Cloud Foundry SSO with OAuth2 provider Please refer to our [sample app on GitHub](https://github.com/SteeltoeOSS/Samples/tree/2.x/Security/src/AspDotNet4/CloudFoundrySingleSignon) for detailed directions on using Single Sign-on with OAuth2 and Cloud Foundry in .NET Framework 4. diff --git a/guides/security/sso-openid-netcore.md b/guides/security/sso-openid-netcore.md index d236d9e1..792810a4 100644 --- a/guides/security/sso-openid-netcore.md +++ b/guides/security/sso-openid-netcore.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + > [!TIP] > Looking for a .NET Framework example? Have a [look](./sso-openid-framework.md). @@ -14,7 +17,7 @@ _hideTocVersionToggle: true This is a guide to integrate a .Net Core API with the Cloud Foundry SSO identity provider service. The sample provides authentication to select entry points of an application. It is meant to provide authentication simiar to how IIS would when Windows authentication is enabled. > [!NOTE] -> For more detailed examples, please refer to the [Security](https://github.com/SteeltoeOSS/Samples/tree/main/Security) section in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Security](https://github.com/SteeltoeOSS/Samples/tree/3.x/Security) section in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **establish an identity provider**. Using the [Steeltoe dockerfile](https://github.com/steeltoeoss/dockerfiles), start a local instance of SSO. @@ -34,10 +37,10 @@ Next, **create a .NET Core WebAPI** that interacts with SSO 1. Extract the zipped project and open in your IDE of choice 1. Open the package manager console Visual Studio - Package Manager Console -1. Install NuGet distributed packages +1. Install NuGet packages ```powershell - Install-Package -Id Steeltoe.Security.Authentication.CloudFoundryCore -Version 2.4 + Install-Package Steeltoe.Security.Authentication.CloudFoundryCore ``` 1. Set the instance address in **appsettings.json** diff --git a/guides/service-connectors/mongo.md b/guides/service-connectors/mongo.md index d8994949..7898bfd6 100644 --- a/guides/service-connectors/mongo.md +++ b/guides/service-connectors/mongo.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Service Connectors with Mongo DB This tutorial takes you through setting up a .NET Core application with the Mongo DB service connector. > [!NOTE] -> For more detailed examples, please refer to the [MongoDb](https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/MongoDb) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [MongoDb](https://github.com/SteeltoeOSS/Samples/tree/3.x/Connectors/src/MongoDb) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **start a Mongo DB instance**. Depending on your hosting platform this is done in several ways. diff --git a/guides/service-connectors/mssql.md b/guides/service-connectors/mssql.md index fb682aef..42103ec0 100644 --- a/guides/service-connectors/mssql.md +++ b/guides/service-connectors/mssql.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Service Connectors with Microsoft SQL This tutorial takes you through setting up a .NET Core application with the Microsoft SQL service connector. > [!NOTE] -> For more detailed examples, please refer to the [SqlServerEFCore](https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/SqlServerEFCore) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [SqlServerEFCore](https://github.com/SteeltoeOSS/Samples/tree/3.x/Connectors/src/SqlServerEFCore) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **start an MsSQL instance** using the [Steeltoe dockerfile](https://github.com/steeltoeoss/dockerfiles). diff --git a/guides/service-connectors/mysql.md b/guides/service-connectors/mysql.md index 102a97d0..684cff62 100644 --- a/guides/service-connectors/mysql.md +++ b/guides/service-connectors/mysql.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Service Connectors with MySQL This tutorial takes you through setting up a .NET Core application with the MySQL service connector. > [!NOTE] -> For more detailed examples, please refer to the [MySql](https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/MySql) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [MySql](https://github.com/SteeltoeOSS/Samples/tree/3.x/Connectors/src/MySql) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **start a MySQL instance** using the [Steeltoe dockerfile](https://github.com/steeltoeoss/dockerfiles). diff --git a/guides/service-connectors/oauth.md b/guides/service-connectors/oauth.md index 22d885ce..9cc52300 100644 --- a/guides/service-connectors/oauth.md +++ b/guides/service-connectors/oauth.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Service Connectors with an OAuth2 service -Please refer to our [sample app on GitHub](https://github.com/SteeltoeOSS/Samples/tree/master/Security/src/CloudFoundrySingleSignon) +Please refer to our [sample app on GitHub](https://github.com/SteeltoeOSS/Samples/tree/3.x/Security/src/CloudFoundrySingleSignon) diff --git a/guides/service-connectors/postgresql.md b/guides/service-connectors/postgresql.md index a345d29c..75efd5c7 100644 --- a/guides/service-connectors/postgresql.md +++ b/guides/service-connectors/postgresql.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Service Connectors with PostgreSQL Database This tutorial takes you through setting up a .NET Core application with the PostgreSQL service connector. > [!NOTE] -> For more detailed examples, please refer to the [PostgreSql](https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/PostgreSql) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [PostgreSql](https://github.com/SteeltoeOSS/Samples/tree/3.x/Connectors/src/PostgreSql) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **start a PostgreSQL instance** using the [Steeltoe dockerfile](https://github.com/steeltoeoss/dockerfiles). diff --git a/guides/service-connectors/rabbitmq.md b/guides/service-connectors/rabbitmq.md index 93d5b177..a2099588 100644 --- a/guides/service-connectors/rabbitmq.md +++ b/guides/service-connectors/rabbitmq.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Service Connectors with RabbitMQ This tutorial takes you through setting up a .NET Core application with the RabbitMQ service connector. > [!NOTE] -> For more detailed examples, please refer to the [RabbitMQ](https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/RabbitMQ) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [RabbitMQ](https://github.com/SteeltoeOSS/Samples/tree/3.x/Connectors/src/RabbitMQ) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **start a RabbitMQ instance** using the [Steeltoe dockerfile](https://github.com/steeltoeoss/dockerfiles). diff --git a/guides/service-connectors/redis.md b/guides/service-connectors/redis.md index 74d4e6f5..0142e54b 100644 --- a/guides/service-connectors/redis.md +++ b/guides/service-connectors/redis.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Service Connectors with Redis Cache This tutorial takes you through setting up a .NET Core application with the Redis service connector. > [!NOTE] -> For more detailed examples, please refer to the [Redis](https://github.com/SteeltoeOSS/Samples/tree/main/Connectors/src/Redis) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [Redis](https://github.com/SteeltoeOSS/Samples/tree/3.x/Connectors/src/Redis) project in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **start a Redis instance** using the [Steeltoe dockerfile](https://github.com/steeltoeoss/dockerfiles). diff --git a/guides/service-discovery/consul.md b/guides/service-discovery/consul.md index 1a93fe98..d8fbf8ea 100644 --- a/guides/service-discovery/consul.md +++ b/guides/service-discovery/consul.md @@ -6,6 +6,9 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Service Discovery with HashiCorp Consul server This tutorial takes you through setting up two .NET Core applications using services discovery. The first will register it's endpoints for discovery, and the second will discover the first's services. @@ -201,7 +204,7 @@ public class WeatherForecastController : ControllerBase Some notes about the above code: * Steeltoe configures [`HttpClientFactory`](https://docs.microsoft.com/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests) to provide named `HttpClient`s that are configured with Random or RoundRobin load balancers. - * There are several other ways to [discover services](/api/v3/discovery/discovering-services.html) + * There are several other ways to [discover services](../../api/v3/discovery/discovering-services.md) * Inside the outbound HTTP request pipeline, Steeltoe replaces "http://Consul-Register-Example/" in the request Uri with a scheme + host + port returned from Consul Run the app to see discovery in action: diff --git a/guides/service-discovery/eureka.md b/guides/service-discovery/eureka.md index 8d1c4efb..6a79ca1a 100644 --- a/guides/service-discovery/eureka.md +++ b/guides/service-discovery/eureka.md @@ -6,12 +6,15 @@ _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. Please [open an issue](https://github.com/SteeltoeOSS/Documentation/issues/new/choose) if you'd like to help update the content for Steeltoe v4. + ## Using Service Discovery with Eureka Server This tutorial takes you through setting up two .NET Core applications using services discovery. The first will register it's endpoints for discovery, and the second will discover the first's services. > [!NOTE] -> For more detailed examples, please refer to the [FortuneTeller (Discovery)](https://github.com/SteeltoeOSS/Samples/tree/main/Discovery/src) solution in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples). +> For more detailed examples, please refer to the [FortuneTeller (Discovery)](https://github.com/SteeltoeOSS/Samples/tree/3.x/Discovery/src) solution in the [Steeltoe Samples Repository](https://github.com/SteeltoeOSS/Samples/tree/3.x). First, **start a Eureka Server** using the [Steeltoe dockerfile](https://github.com/steeltoeoss/dockerfiles), start a local instance of Eureka. diff --git a/guides/stream/quick-start.md b/guides/stream/quick-start.md index 9647520f..c6bc2911 100644 --- a/guides/stream/quick-start.md +++ b/guides/stream/quick-start.md @@ -1,11 +1,14 @@ --- uid: guides/stream/quick-start -title: Quick Start w/ RabbitMQ +title: Quick Start w/ RabbitMQ tags: [] _disableFooter: true _hideTocVersionToggle: true --- +> [!NOTE] +> This guide applies to Steeltoe v3. [This component has been removed from v4](https://github.com/SteeltoeOSS/Steeltoe/issues/1244). + # Quick Start w/ RabbitMQ This guide will show you how to create a Steeltoe Stream service that receives messages coming from messaging middleware of your choice and logs the received message to the console. @@ -30,15 +33,15 @@ First, **start a rabbitmq server** locally using Docker: To get started, visit the [Steeltoe Initializr](https://start.steeltoe.io). From there, you can generate our `LoggingConsumer` application. To do so: - 1. In the *Name* field, type 'LoggingConsumer'. - - @@ -125,7 +128,7 @@ We are using the StreamHost implementation that configures services required to ```csharp var builder = WebApplication.CreateBuilder(args); builder.Host.AddStreamServices(); -builder.Build().Run(); +builder.Build().Run(); ``` You now have a fully functional Steeltoe Stream application that listens for messages. diff --git a/guides/toc.yml b/guides/toc.yml index c539e4d4..f4565dd6 100644 --- a/guides/toc.yml +++ b/guides/toc.yml @@ -47,7 +47,7 @@ - topicUid: guides/service-discovery/eureka - topicUid: guides/service-discovery/consul - name: Stream - items: + items: - topicUid: guides/stream/quick-start - name: Steeltoe Workshop items: diff --git a/main-site.localhost.json b/main-site.localhost.json index e4f387bd..1c8ad668 100644 --- a/main-site.localhost.json +++ b/main-site.localhost.json @@ -1,3 +1,3 @@ { - "_rootHost": "http://localhost:8080" + "_rootHost": "https://localhost:8080" } diff --git a/metadata.conf b/metadata.conf index 6779eab7..ed368109 100644 --- a/metadata.conf +++ b/metadata.conf @@ -1,2 +1,3 @@ 2:2.5.5 3:3.2.6 +4:main diff --git a/metadata.json b/metadata.json index 73fae8ff..4fdbdb22 100644 --- a/metadata.json +++ b/metadata.json @@ -30,4 +30,4 @@ "_enableNewTab": true, "_gitUrlPattern": "github" -} \ No newline at end of file +} diff --git a/nginx.conf b/nginx.conf index bee31140..9f732303 100644 --- a/nginx.conf +++ b/nginx.conf @@ -11,16 +11,19 @@ server { index index.html index.htm; } - location = / { - return 302 /api/v3/welcome; + location = / { + return 302 /api/v4/welcome; } - location = /api/ { - return 302 /api/v3/welcome; + location = /api/ { + return 302 /api/v4/welcome; + } + location = /api/v4/ { + return 302 /api/v4/welcome; } - location = /api/v3/ { + location = /api/v3/ { return 302 /api/v3/welcome; } - location = /api/v2/ { + location = /api/v2/ { return 302 /api/v2/welcome; } @@ -55,4 +58,4 @@ server { #location ~ /\.ht { # deny all; #} -} \ No newline at end of file +} diff --git a/template/steeltoe/partials/blog-specs.tmpl.partial b/template/steeltoe/partials/blog-specs.tmpl.partial index 2e560243..df9cb942 100644 --- a/template/steeltoe/partials/blog-specs.tmpl.partial +++ b/template/steeltoe/partials/blog-specs.tmpl.partial @@ -4,4 +4,4 @@ {{#author.github}}{{/author.github}} {{#author.twitter}}{{/author.twitter}} {{/author.name}} - \ No newline at end of file + diff --git a/template/steeltoe/partials/footer.tmpl.partial b/template/steeltoe/partials/footer.tmpl.partial index 5eafb670..8b03af47 100644 --- a/template/steeltoe/partials/footer.tmpl.partial +++ b/template/steeltoe/partials/footer.tmpl.partial @@ -1,5 +1,5 @@
-
+
@@ -31,4 +31,4 @@
-
\ No newline at end of file + diff --git a/template/steeltoe/partials/navbar.tmpl.partial b/template/steeltoe/partials/navbar.tmpl.partial index acdb6b02..9a002cdc 100644 --- a/template/steeltoe/partials/navbar.tmpl.partial +++ b/template/steeltoe/partials/navbar.tmpl.partial @@ -1,70 +1,67 @@ diff --git a/template/steeltoe/partials/toc.tmpl.partial b/template/steeltoe/partials/toc.tmpl.partial index d79df19a..5c82ccaf 100644 --- a/template/steeltoe/partials/toc.tmpl.partial +++ b/template/steeltoe/partials/toc.tmpl.partial @@ -10,12 +10,18 @@ X
+ + @@ -25,6 +31,17 @@
+