diff --git a/.gitignore b/.gitignore index b4855007af..c70ca92e0a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Python virtual environments +.venv + docs/_build/ .idea/ *.swp diff --git a/docfx.json b/docfx.json index a824cea8f7..b583af4fba 100644 --- a/docfx.json +++ b/docfx.json @@ -149,10 +149,12 @@ "Docker", "Dockerfile", "EF Core", + "Elasticsearch", "Entity Framework Core", "Git", "GitHub", "JSON", + "Keycloak", "Kubernetes", "Linux", "localhost", diff --git a/docs/app-host/withdockerfile.md b/docs/app-host/withdockerfile.md new file mode 100644 index 0000000000..6f67a0f7a5 --- /dev/null +++ b/docs/app-host/withdockerfile.md @@ -0,0 +1,115 @@ +--- +title: Add Dockerfiles to your .NET app model +description: Learn how to add Dockerfiles to your .NET app model. +ms.date: 07/23/2024 +--- + +# Add Dockerfiles to your .NET app model + +With .NET Aspire it's possible to specify a _Dockerfile_ to build when the [app host](../fundamentals/app-host-overview.md) is started using either the or extension methods. + +## Add a Dockerfile to the app model + +In the following example the extension method is used to specify a container by referencing the context path for the container build. + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var container = builder.AddDockerfile( + "mycontainer", "relative/context/path"); +``` + +Unless the context path argument is a rooted path the context path is interpreted as being relative to the app host projects directory (where the AppHost `*.csproj` folder is located). + +By default the name of the _Dockerfile_ which is used is `Dockerfile` and is expected to be within the context path directory. It's possible to explicitly specify the _Dockerfile_ name either as an absolute path or a relative path to the context path. + +This is useful if you wish to modify the specific _Dockerfile_ being used when running locally or when the app host is deploying. + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var container = builder.ExecutionContext.IsRunMode + ? builder.AddDockerfile( + "mycontainer", "relative/context/path", "Dockerfile.debug") + : builder.AddDockerfile( + "mycontainer", "relative/context/path", "Dockerfile.release"); +``` + +## Customize existing container resources + +When using the return value is an `IResourceBuilder`. .NET Aspire includes many custom resource types that are derived from . + +Using the extension method it's possible to continue using these strongly typed resource types and customize the underlying container that is used. + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var pgsql = builder.AddPostgres("pgsql") + .WithDockerfile("path/to/context") + .WithPgAdmin(); +``` + +## Pass build arguments + +The method can be used to pass arguments into the container image build. + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var container = builder.AddDockerfile("mygoapp", "relative/context/path") + .WithBuildArg("GO_VERSION", "1.22"); +``` + +The value parameter on the method can be a literal value (`boolean`, `string`, `int`) or it can be a resource builder for a [parameter resource](../fundamentals/external-parameters.md). The following code replaces the `GO_VERSION` with a parameter value that can be specified at deployment time. + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var goVersion = builder.AddParameter("goversion"); + +var container = builder.AddDockerfile("mygoapp", "relative/context/path") + .WithBuildArg("GO_VERSION", goVersion); +``` + +Build arguments correspond to the [`ARG` command](https://docs.docker.com/build/guide/build-args/) in _Dockerfiles_. Expanding the preceding example, this is a multi-stage _Dockerfile_ which specifies specific container image version to use as a parameter. + +```dockerfile +# Stage 1: Build the Go program +ARG GO_VERSION=1.22 +FROM golang:${GO_VERSION} AS builder +WORKDIR /build +COPY . . +RUN go build mygoapp.go + +# Stage 2: Run the Go program +FROM mcr.microsoft.com/cbl-mariner/base/core:2.0 +WORKDIR /app +COPY --from=builder /build/mygoapp . +CMD ["./mygoapp"] +``` + +> [!NOTE] +> Instead of hardcoding values into the container image, it's recommended to use environment variables for values that frequently change. This avoids the need to rebuild the container image whenever a change is required. + +## Pass build secrets + +In addition to build arguments it's possible to specify build secrets using which are made selectively available to individual commands in the _Dockerfile_ using the `--mount=type=secret` syntax on `RUN` commands. + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var accessToken = builder.AddParameter("accesstoken", secret: true); + +var container = builder.AddDockerfile("myapp", "relative/context/path") + .WithBuildSecret("ACCESS_TOKEN", accessToken); +``` + +For example, consider the `RUN` command in a _Dockerfile_ which exposes the specified secret to the specific command: + +```dockerfile +# The helloworld command can read the secret from /run/secrets/ACCESS_TOKEN +RUN --mount=type=secret,id=ACCESS_TOKEN helloworld +``` + +> [!CAUTION] +> Caution should be exercised when passing secrets in build environments. This is often done when using a token to retrieve dependencies from private repositories or feeds before a build. It is important to ensure that the injected secrets are not copied into the final or intermediate images. diff --git a/docs/authentication/keycloak-component.md b/docs/authentication/keycloak-component.md new file mode 100644 index 0000000000..5e0fa9e581 --- /dev/null +++ b/docs/authentication/keycloak-component.md @@ -0,0 +1,134 @@ +--- +title: .NET Aspire Keycloak component +description: This article describes the .NET Aspire Keycloak component. +ms.topic: how-to +ms.date: 07/23/2024 +--- + +# .NET Aspire Keycloak component + +In this article, you learn how to use the .NET Aspire Keycloak component. The `Aspire.Keycloak.Authentication` library registers JwtBearer and OpenId Connect authentication handlers in the DI container for connecting to a Keycloak server. + +## Prerequisites + +- A Keycloak server instance. +- A Keycloak realm. +- For JwtBearer authentication, a configured audience in the Keycloak realm. +- For OpenId Connect authentication, the ID of a client configured in the Keycloak realm. + +## Get started + +To get started with the .NET Aspire Keycloak component, install the [Aspire.Keycloak.Authentication](https://www.nuget.org/packages/Aspire.Keycloak.Authentication) NuGet package in the consuming client project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Keycloak.Authentication +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). + +## Jwt bearer authentication usage example + +In the _Program.cs_ file of your ASP.NET Core API project, call the `AddKeycloakJwtBearer` extension method to add JwtBearer authentication, using a connection name, realm and any required JWT Bearer options: + +```csharp +builder.Services.AddAuthentication() + .AddKeycloakJwtBearer("keycloak", realm: "WeatherShop", options => + { + options.Audience = "weather.api"; + }); +``` + +You can set many other options via the `Action configureOptions` delegate. + +## OpenId Connect authentication usage example + +In the _Program.cs_ file of your Blazor project, call the `AddKeycloakOpenIdConnect` extension method to add OpenId Connect authentication, using a connection name, realm and any required OpenId Connect options: + +```csharp +builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) + .AddKeycloakOpenIdConnect( + "keycloak", + realm: "WeatherShop", + options => + { + options.ClientId = "WeatherWeb"; + options.ResponseType = OpenIdConnectResponseType.Code; + options.Scope.Add("weather:all"); + }); +``` + +You can set many other options via the `Action? configureOptions` delegate. + +## App host usage + +To model the Keycloak resource in the app host, install the [Aspire.Hosting.Keycloak](https://www.nuget.org/packages/Aspire.Hosting.Keycloak) NuGet package in the [app host](xref:aspire/app-host) project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Hosting.Keycloak +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +Then, in the _Program.cs_ file of `AppHost`, register a Keycloak server and consume the connection using the following methods: + +```csharp +var keycloak = builder.AddKeycloak("keycloak", 8080); + +var apiService = builder.AddProject("apiservice") + .WithReference(keycloak); + +builder.AddProject("webfrontend") + .WithExternalHttpEndpoints() + .WithReference(keycloak) + .WithReference(apiService); +``` + +> [!TIP] +> For local development use a stable port for the Keycloak resource (8080 in the example above). It can be any port, but it should be stable to avoid issues with browser cookies that will persist OIDC tokens (which include the authority URL, with port) beyond the lifetime of the _app host_. + +The `WithReference` method configures a connection in the `Keycloak.ApiService` and `Keycloak.Web` projects named `keycloak`. + +In the _Program.cs_ file of `Keycloak.ApiService`, the Keycloak connection can be consumed using: + +```csharp +builder.Services.AddAuthentication() + .AddKeycloakJwtBearer("keycloak", realm: "WeatherShop"); +``` + +In the _Program.cs_ file of `Keycloak.Web`, the Keycloak connection can be consumed using: + +```csharp +var oidcScheme = OpenIdConnectDefaults.AuthenticationScheme; + +builder.Services.AddAuthentication(oidcScheme) + .AddKeycloakOpenIdConnect( + "keycloak", + realm: "WeatherShop", + oidcScheme); +``` + +## See also + +- [Keycloak](https://www.keycloak.org/) +- [.NET Aspire components](../fundamentals/components-overview.md) +- [.NET Aspire GitHub repo](https://github.com/dotnet/aspire) diff --git a/docs/caching/includes/garnet-app-host.md b/docs/caching/includes/garnet-app-host.md new file mode 100644 index 0000000000..30cada3c66 --- /dev/null +++ b/docs/caching/includes/garnet-app-host.md @@ -0,0 +1,33 @@ +To model the Garnet resource (`GarnetResource`) in the app host, install the [Aspire.Hosting.Garnet](https://www.nuget.org/packages/Aspire.Hosting.Garnet) NuGet package in the [app host](xref:aspire/app-host) project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Hosting.Garnet +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +In your app host project, register .NET Aspire Garnet as a `GarnetResource` using the `AddGarnet` method and consume the service using the following methods: + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var cache = builder.AddGarnet("cache"); + +builder.AddProject() + .WithReference(cache) +``` + +The method configures a connection in the `ExampleProject` project named `cache`. In the _:::no-loc text="Program.cs":::_ file of `ExampleProject`, the Garnet connection can be consumed using: + +```csharp +builder.AddGarnet("cache"); +``` diff --git a/docs/caching/includes/redis-app-host.md b/docs/caching/includes/redis-app-host.md index a6c5929774..6dbe7074a4 100644 --- a/docs/caching/includes/redis-app-host.md +++ b/docs/caching/includes/redis-app-host.md @@ -1,4 +1,4 @@ -To model the Redis resource in the app host, install the [Aspire.Hosting.Redis](https://www.nuget.org/packages/Aspire.Hosting.Redis) NuGet package in the [app host](xref:aspire/app-host) project. +To model the Redis resource (`RedisResource`) in the app host, install the [Aspire.Hosting.Redis](https://www.nuget.org/packages/Aspire.Hosting.Redis) NuGet package in the [app host](xref:aspire/app-host) project. ### [.NET CLI](#tab/dotnet-cli) @@ -16,3 +16,18 @@ dotnet add package Aspire.Hosting.Redis --- In your app host project, register the .NET Aspire Stack Exchange Redis as a resource using the method and consume the service using the following methods: + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var cache = builder.AddRedis("cache"); + +builder.AddProject() + .WithReference(cache) +``` + +The method configures a connection in the `ExampleProject` project named `cache`. In the _:::no-loc text="Program.cs":::_ file of `ExampleProject`, the Redis connection can be consumed using: + +```csharp +builder.AddRedis("cache"); +``` diff --git a/docs/caching/includes/valkey-app-host.md b/docs/caching/includes/valkey-app-host.md new file mode 100644 index 0000000000..ca44e5b488 --- /dev/null +++ b/docs/caching/includes/valkey-app-host.md @@ -0,0 +1,33 @@ +To model the Valkey resource (`ValkeyResource`) in the app host, install the [Aspire.Hosting.Valkey](https://www.nuget.org/packages/Aspire.Hosting.Valkey) NuGet package in the [app host](xref:aspire/app-host) project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Hosting.Valkey +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +In your app host project, register the .NET Aspire Valkey as a resource using the `AddValkey` method and consume the service using the following methods: + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var cache = builder.AddValkey("cache"); + +builder.AddProject() + .WithReference(cache) +``` + +The method configures a connection in the `ExampleProject` project named `cache`. In the _:::no-loc text="Program.cs":::_ file of `ExampleProject`, the Valkey connection can be consumed using: + +```csharp +builder.AddValkey("cache"); +``` diff --git a/docs/caching/stackexchange-redis-caching-overview.md b/docs/caching/stackexchange-redis-caching-overview.md index 242a464570..11b859bb59 100644 --- a/docs/caching/stackexchange-redis-caching-overview.md +++ b/docs/caching/stackexchange-redis-caching-overview.md @@ -1,7 +1,7 @@ --- title: Stack Exchange Redis caching overview description: Learn about Stack Exchange Redis caching and how to use it in your applications. -ms.date: 06/11/2024 +ms.date: 07/23/2024 --- # Stack Exchange Redis caching overview @@ -10,6 +10,17 @@ With .NET Aspire, there are several ways to use caching in your applications. On To use multiple Redis caching components in your application, see [Tutorial: Implement caching with .NET Aspire components](caching-components.md). If you're interested in using the Redis Cache for Azure, see [Tutorial: Deploy a .NET Aspire project with a Redis Cache to Azure](caching-components-deployment.md). +## Redis serialization protocol (RESP) + +The Redis serialization protocol (RESP) is a binary-safe protocol that Redis uses to communicate with clients. RESP is a simple, text-based protocol that is easy to implement and efficient to parse. RESP is used to send commands to Redis and receive responses from Redis. RESP is designed to be fast and efficient, making it well-suited for use in high-performance applications. For more information, see [Redis serialization protocol specification](https://redis.io/docs/latest/develop/reference/protocol-spec/). + +In addition to Redis itself, there are two well-maintained implementations of RESP for .NET: + +- [Garnet](https://github.com/microsoft/Garnet): Garnet is a remote cache-store from Microsoft Research that offers strong performance (throughput and latency), scalability, storage, recovery, cluster sharding, key migration, and replication features. Garnet can work with existing Redis clients. +- [Valkey](https://github.com/valkey-io/valkey): A flexible distributed key-value datastore that supports both caching and beyond caching workloads. + +.NET Aspire lets you easily model either the Redis, Garnet, or Valkey RESP protocol in your applications and you can choose which one to use based on your requirements. All of the .NET Aspire Redis components can be used with either the Redis, Garnet, or Valkey RESP protocol. + ## Caching Caching is a technique used to store frequently accessed data in memory. This helps to reduce the time it takes to retrieve the data from the original source, such as a database or a web service. Caching can significantly improve the performance of an application by reducing the number of requests made to the original source. To access the Redis `IConnectionMultiplexer` object, you use the `Aspire.StackExchange.Redis` NuGet package: @@ -17,6 +28,12 @@ Caching is a technique used to store frequently accessed data in memory. This he > [!div class="nextstepaction"] > [.NET Aspire Stack Exchange Redis component](stackexchange-redis-component.md) +> [!div class="nextstepaction"] +> [.NET Aspire Stack Exchange Redis component (Garnet)](stackexchange-redis-component.md?pivots=garnet) + +> [!div class="nextstepaction"] +> [.NET Aspire Stack Exchange Redis component (Valkey)](stackexchange-redis-component.md?pivots=valkey) + ## Distributed caching Distributed caching is a type of caching that stores data across multiple servers. This allows the data to be shared between multiple instances of an application, which can help to improve scalability and performance. Distributed caching can be used to store a wide variety of data, such as session state, user profiles, and frequently accessed data. To use Redis distributed caching in your application (the `IDistributedCache` interface), use the `Aspire.StackExchange.Redis.DistributedCaching` NuGet package: @@ -24,6 +41,12 @@ Distributed caching is a type of caching that stores data across multiple server > [!div class="nextstepaction"] > [.NET Aspire Stack Exchange Redis distributed caching component](stackexchange-redis-distributed-caching-component.md) +> [!div class="nextstepaction"] +> [.NET Aspire Stack Exchange Redis distributed caching component (Garnet)](stackexchange-redis-distributed-caching-component.md?pivots=garnet) + +> [!div class="nextstepaction"] +> [.NET Aspire Stack Exchange Redis distributed caching component (Valkey)](stackexchange-redis-distributed-caching-component.md?pivots=valkey) + ## Output caching Output caching is a type of caching that stores the output of a web page or API response. This allows the response to be served directly from the cache, rather than generating it from scratch each time. Output caching can help to improve the performance of a web application by reducing the time it takes to generate a response. To use declarative Redis output caching with either the `OutputCache` attribute or the `CacheOutput` method in your application, use the `Aspire.StackExchange.Redis.OutputCaching` NuGet package: @@ -31,6 +54,12 @@ Output caching is a type of caching that stores the output of a web page or API > [!div class="nextstepaction"] > [.NET Aspire Stack Exchange Redis output caching component](stackexchange-redis-output-caching-component.md) +> [!div class="nextstepaction"] +> [.NET Aspire Stack Exchange Redis output caching component (Garnet)](stackexchange-redis-output-caching-component.md?pivots=garnet) + +> [!div class="nextstepaction"] +> [.NET Aspire Stack Exchange Redis output caching component (Valkey)](stackexchange-redis-output-caching-component.md?pivots=valkey) + ## See also - [Caching in .NET](/dotnet/core/extensions/caching) diff --git a/docs/caching/stackexchange-redis-component.md b/docs/caching/stackexchange-redis-component.md index 9af494eadf..cd95bb8e6a 100644 --- a/docs/caching/stackexchange-redis-component.md +++ b/docs/caching/stackexchange-redis-component.md @@ -2,7 +2,8 @@ title: .NET Aspire Stack Exchange Redis component description: This article describes the .NET Aspire Stack Exchange Redis component features and capabilities ms.topic: how-to -ms.date: 07/17/2024 +ms.date: 07/23/2024 +zone_pivot_groups: resp-host --- # .NET Aspire Stack Exchange Redis component @@ -49,22 +50,21 @@ public class ExampleService(IConnectionMultiplexer connectionMultiplexer) ## App host usage +:::zone pivot="redis" + [!INCLUDE [redis-app-host](includes/redis-app-host.md)] -```csharp -var builder = DistributedApplication.CreateBuilder(args); +:::zone-end +:::zone pivot="garnet" -var redis = builder.AddRedis("redis"); +[!INCLUDE [garnet-app-host](includes/garnet-app-host.md)] -builder.AddProject() - .WithReference(redis) -``` +:::zone-end +:::zone pivot="valkey" -The method configures a connection in the `ExampleProject` project named `redis`. In the _:::no-loc text="Program.cs":::_ file of `ExampleProject`, the Redis connection can be consumed using: +[!INCLUDE [valkey-app-host](includes/valkey-app-host.md)] -```csharp -builder.AddRedis("cache"); -``` +:::zone-end ## Configuration @@ -72,18 +72,42 @@ The .NET Aspire Stack Exchange Redis component provides multiple options to conf ### Use a connection string +:::zone pivot="redis" + When using a connection string from the `ConnectionStrings` configuration section, you can provide the name of the connection string when calling `builder.AddRedis`: ```csharp -builder.AddRedis("RedisConnection"); +builder.AddRedis("cache"); +``` + +:::zone-end +:::zone pivot="garnet" + +When using a connection string from the `ConnectionStrings` configuration section, you can provide the name of the connection string when calling `builder.AddGarnet`: + +```csharp +builder.AddGarnet("cache"); ``` +:::zone-end +:::zone pivot="valkey" + +[!INCLUDE [valkey-app-host](includes/valkey-app-host.md)] + +When using a connection string from the `ConnectionStrings` configuration section, you can provide the name of the connection string when calling `builder.AddValkey`: + +```csharp +builder.AddValkey("cache"); +``` + +:::zone-end + And then the connection string will be retrieved from the `ConnectionStrings` configuration section: ```json { "ConnectionStrings": { - "RedisConnection": "localhost:6379" + "cache": "localhost:6379" } } ``` @@ -115,12 +139,36 @@ The .NET Aspire Stack Exchange Redis component supports ` delegate to set up some or all the options inline, for example to configure `DisableTracing`: +:::zone pivot="redis" + ```csharp builder.AddRedis( "cache", settings => settings.DisableTracing = true); ``` +:::zone-end +:::zone pivot="garnet" + +```csharp +builder.AddGarnet( + "cache", + settings => settings.DisableTracing = true); +``` + +:::zone-end +:::zone pivot="valkey" + +[!INCLUDE [valkey-app-host](includes/valkey-app-host.md)] + +```csharp +builder.AddValkey( + "cache", + settings => settings.DisableTracing = true); +``` + +:::zone-end + [!INCLUDE [component-health-checks](../includes/component-health-checks.md)] The .NET Aspire Stack Exchange Redis component handles the following: diff --git a/docs/caching/stackexchange-redis-distributed-caching-component.md b/docs/caching/stackexchange-redis-distributed-caching-component.md index 42df645d52..37536bb4bd 100644 --- a/docs/caching/stackexchange-redis-distributed-caching-component.md +++ b/docs/caching/stackexchange-redis-distributed-caching-component.md @@ -2,7 +2,8 @@ title: .NET Aspire Stack Exchange Redis distributed caching component description: This article describes the .NET Aspire Stack Exchange Redis distributed caching component features and capabilities ms.topic: how-to -ms.date: 07/17/2024 +ms.date: 07/23/2024 +zone_pivot_groups: resp-host --- # .NET Aspire Stack Exchange Redis distributed caching component @@ -49,22 +50,21 @@ public class ExampleService(IDistributedCache cache) ## App host usage +:::zone pivot="redis" + [!INCLUDE [redis-app-host](includes/redis-app-host.md)] -```csharp -var builder = DistributedApplication.CreateBuilder(args); +:::zone-end +:::zone pivot="garnet" -var redis = builder.AddRedis("cache"); +[!INCLUDE [garnet-app-host](includes/garnet-app-host.md)] -builder.AddProject() - .WithReference(redis) -``` +:::zone-end +:::zone pivot="valkey" -The method configures a connection in the `ExampleProject` project named `cache`. In the _:::no-loc text="Program.cs":::_ file of `ExampleProject`, the Redis connection can be consumed using: +[!INCLUDE [valkey-app-host](includes/valkey-app-host.md)] -```csharp -builder.AddRedisDistributedCache("cache"); -``` +:::zone-end ## Configuration diff --git a/docs/caching/stackexchange-redis-output-caching-component.md b/docs/caching/stackexchange-redis-output-caching-component.md index c7c24d9915..9fd3e6fe24 100644 --- a/docs/caching/stackexchange-redis-output-caching-component.md +++ b/docs/caching/stackexchange-redis-output-caching-component.md @@ -2,12 +2,13 @@ title: .NET Aspire Stack Exchange Redis output caching Component description: This article describes the .NET Aspire Stack Exchange Redis output caching component features and capabilities ms.topic: how-to -ms.date: 07/17/2024 +ms.date: 07/23/2024 +zone_pivot_groups: resp-host --- # .NET Aspire Stack Exchange Redis output caching component -In this article, you learn how to use the .NET Aspire Stack Exchange Redis output caching component. The `Aspire.StackExchange.Redis.OutputCaching` library is used to register an [ASP.NET Core Output Caching](/aspnet/core/performance/caching/output) provider backed by a [Redis](https://redis.io/) server. It enables corresponding health check, logging, and telemetry. +In this article, you learn how to use the .NET Aspire Stack Exchange Redis output caching component. The `Aspire.StackExchange.Redis.OutputCaching` library is used to register an [ASP.NET Core Output Caching](/aspnet/core/performance/caching/output) provider backed by a [Redis](https://redis.io/) server. It enables corresponding health check, logging, and telemetry.. ## Get started @@ -56,22 +57,21 @@ For apps with controllers, apply the `[OutputCache]` attribute to the action met ## App host usage +:::zone pivot="redis" + [!INCLUDE [redis-app-host](includes/redis-app-host.md)] -```csharp -var builder = DistributedApplication.CreateBuilder(args); +:::zone-end +:::zone pivot="garnet" -var redis = builder.AddRedis("redis"); +[!INCLUDE [garnet-app-host](includes/garnet-app-host.md)] -var basket = builder.AddProject() - .WithReference(redis) -``` +:::zone-end +:::zone pivot="valkey" -The method configures a connection in the `ExampleProject` project named `redis`. In the _:::no-loc text="Program.cs":::_ file of `ExampleProject`, the Redis connection can be consumed using: +[!INCLUDE [valkey-app-host](includes/valkey-app-host.md)] -```csharp -builder.AddRedisOutputCache("messaging"); -``` +:::zone-end ## Configuration diff --git a/docs/database/milvus-component.md b/docs/database/milvus-component.md new file mode 100644 index 0000000000..1bcb83b4b2 --- /dev/null +++ b/docs/database/milvus-component.md @@ -0,0 +1,162 @@ +--- +title: .NET Aspire Milvus database component +description: This article describes the .NET Aspire Milvus database component. +ms.topic: how-to +ms.date: 07/23/2024 +--- + +# .NET Aspire Milvus database component + +In this article, you learn how to use the .NET Aspire Milvus database component. The `Aspire.Milvus.Client` library registers a [MilvusClient](https://github.com/milvus-io/milvus-sdk-csharp) in the DI container for connecting to a Milvus server. + +## Prerequisites + +- Milvus server and connection string for accessing the server API endpoint. + +## Get started + +To get started with the .NET Aspire Milvus database component, install the [Aspire.Milvus.Client](https://www.nuget.org/packages/Aspire.Milvus.Client) NuGet package in the consuming client project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Milvus.Client +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). + +## Example usage + +In the _Program.cs_ file of your project, call the `AddMilvusClient` extension method to register a `MilvusClient` for use via the dependency injection container. The method takes a connection name parameter. + +```csharp +builder.AddMilvusClient("milvus"); +``` + +## App host usage + +To model the Milvus resource in the app host, install the [Aspire.Hosting.Milvus](https://www.nuget.org/packages/Aspire.Hosting.Milvus) NuGet package in the [app host](xref:aspire/app-host) project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Hosting.Milvus +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +In the _Program.cs_ file of `AppHost`, register a Milvus server and consume the connection using the following methods: + +```csharp +var milvus = builder.AddMilvus("milvus"); + +var myService = builder.AddProject() + .WithReference(milvus); +``` + +The `WithReference` method configures a connection in the `MyService` project named `milvus`. In the _Program.cs_ file of `MyService`, the Milvus connection can be consumed using: + +```csharp +builder.AddMilvusClient("milvus"); +``` + +## Configuration + +The .NET Aspire Milvus Client component provides multiple options to configure the server connection based on the requirements and conventions of your project. + +> [!TIP] +> The default use is `root` and the default password is `Milvus`. Currently, Milvus doesn't support changing the superuser password at startup. It needs to be manually changed with the client. + +### Use a connection string + +When using a connection string from the `ConnectionStrings` configuration section, you can provide the name of the connection string when calling `builder.AddMilvusClient()`: + +```csharp +builder.AddMilvusClient("milvus"); +``` + +And then the connection string will be retrieved from the `ConnectionStrings` configuration section: + +```json +{ + "ConnectionStrings": { + "milvus": "Endpoint=http://localhost:19530/;Key=root:123456!@#$%" + } +} +``` + +By default the `MilvusClient` uses the gRPC API endpoint. + +### Use configuration providers + +The .NET Aspire Milvus Client component supports [Microsoft.Extensions.Configuration](/dotnet/api/microsoft.extensions.configuration). It loads the `MilvusSettings` from configuration by using the `Aspire:Milvus:Client` key. Consider the following example _appsettings.json_ that configures some of the options: + +```json +{ + "Aspire": { + "Milvus": { + "Client": { + "Key": "root:123456!@#$%" + } + } + } +} +``` + +### Use inline delegates + +Also you can pass the `Action configureSettings` delegate to set up some or all the options inline, for example to set the API key from code: + +```csharp +builder.AddMilvusClient( + "milvus", + settings => settings.Key = "root:12345!@#$%"); +``` + +[!INCLUDE [component-health-checks](../includes/component-health-checks.md)] + +The .NET Aspire Milvus database component uses the configured client to perform a `HealthAsync`. If the result _is healthy_, the health check is considered healthy, otherwise it's unhealthy. Likewise, if there's an exception, the health check is considered unhealthy with the error propagating through the health check failure. + +[!INCLUDE [component-observability-and-telemetry](../includes/component-observability-and-telemetry.md)] + +### Logging + +The .NET Aspire Milvus database component uses standard .NET logging, and you'll see log entries from the following category: + +- `Milvus.Client` + +## See also + +- [Milvus .NET SDK](https://github.com/milvus-io/milvus-sdk-csharp) +- [.NET Aspire components](../fundamentals/components-overview.md) +- [.NET Aspire GitHub repo](https://github.com/dotnet/aspire) + + \ No newline at end of file diff --git a/docs/database/snippets/cosmos-db/AspireApp.ApiService/AspireApp.ApiService.csproj b/docs/database/snippets/cosmos-db/AspireApp.ApiService/AspireApp.ApiService.csproj index e9bed540ab..b39697686c 100644 --- a/docs/database/snippets/cosmos-db/AspireApp.ApiService/AspireApp.ApiService.csproj +++ b/docs/database/snippets/cosmos-db/AspireApp.ApiService/AspireApp.ApiService.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/database/snippets/cosmos-db/AspireApp.AppHost/AspireApp.AppHost.csproj b/docs/database/snippets/cosmos-db/AspireApp.AppHost/AspireApp.AppHost.csproj index 16fb05970d..d8e52cccdc 100644 --- a/docs/database/snippets/cosmos-db/AspireApp.AppHost/AspireApp.AppHost.csproj +++ b/docs/database/snippets/cosmos-db/AspireApp.AppHost/AspireApp.AppHost.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/docs/database/snippets/cosmos-db/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj b/docs/database/snippets/cosmos-db/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/database/snippets/cosmos-db/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj +++ b/docs/database/snippets/cosmos-db/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/database/snippets/tutorial/aspiresqldeployazure/AspireSql.AppHost/AspireSql.AppHost.csproj b/docs/database/snippets/tutorial/aspiresqldeployazure/AspireSql.AppHost/AspireSql.AppHost.csproj index c6e85315d4..ff35507796 100644 --- a/docs/database/snippets/tutorial/aspiresqldeployazure/AspireSql.AppHost/AspireSql.AppHost.csproj +++ b/docs/database/snippets/tutorial/aspiresqldeployazure/AspireSql.AppHost/AspireSql.AppHost.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/docs/database/snippets/tutorial/aspiresqldeployazure/AspireSql.ServiceDefaults/AspireSql.ServiceDefaults.csproj b/docs/database/snippets/tutorial/aspiresqldeployazure/AspireSql.ServiceDefaults/AspireSql.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/database/snippets/tutorial/aspiresqldeployazure/AspireSql.ServiceDefaults/AspireSql.ServiceDefaults.csproj +++ b/docs/database/snippets/tutorial/aspiresqldeployazure/AspireSql.ServiceDefaults/AspireSql.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/database/snippets/tutorial/aspiresqldeploycontainer/AspireSql.AppHost/AspireSql.AppHost.csproj b/docs/database/snippets/tutorial/aspiresqldeploycontainer/AspireSql.AppHost/AspireSql.AppHost.csproj index ab28716e81..008a649bdc 100644 --- a/docs/database/snippets/tutorial/aspiresqldeploycontainer/AspireSql.AppHost/AspireSql.AppHost.csproj +++ b/docs/database/snippets/tutorial/aspiresqldeploycontainer/AspireSql.AppHost/AspireSql.AppHost.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/docs/database/snippets/tutorial/aspiresqldeploycontainer/AspireSql.ServiceDefaults/AspireSql.ServiceDefaults.csproj b/docs/database/snippets/tutorial/aspiresqldeploycontainer/AspireSql.ServiceDefaults/AspireSql.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/database/snippets/tutorial/aspiresqldeploycontainer/AspireSql.ServiceDefaults/AspireSql.ServiceDefaults.csproj +++ b/docs/database/snippets/tutorial/aspiresqldeploycontainer/AspireSql.ServiceDefaults/AspireSql.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore.AppHost/AspireSQLEFCore.AppHost.csproj b/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore.AppHost/AspireSQLEFCore.AppHost.csproj index 2a3433bf1a..0568378087 100644 --- a/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore.AppHost/AspireSQLEFCore.AppHost.csproj +++ b/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore.AppHost/AspireSQLEFCore.AppHost.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore.ServiceDefaults/AspireSQLEFCore.ServiceDefaults.csproj b/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore.ServiceDefaults/AspireSQLEFCore.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore.ServiceDefaults/AspireSQLEFCore.ServiceDefaults.csproj +++ b/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore.ServiceDefaults/AspireSQLEFCore.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore/AspireSQLEFCore.csproj b/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore/AspireSQLEFCore.csproj index cd6d54683e..b1e8d92531 100644 --- a/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore/AspireSQLEFCore.csproj +++ b/docs/database/snippets/tutorial/aspiresqlefcore/AspireSQLEFCore/AspireSQLEFCore.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/deployment/azure/snippets/AppHost.Bicep/AppHost.Bicep.csproj b/docs/deployment/azure/snippets/AppHost.Bicep/AppHost.Bicep.csproj index c9dee9a8d1..3ec3d0b836 100644 --- a/docs/deployment/azure/snippets/AppHost.Bicep/AppHost.Bicep.csproj +++ b/docs/deployment/azure/snippets/AppHost.Bicep/AppHost.Bicep.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/docs/extensibility/snippets/MailDevResource/MailDev.Hosting/MailDev.Hosting.csproj b/docs/extensibility/snippets/MailDevResource/MailDev.Hosting/MailDev.Hosting.csproj index fc602e5bc4..1230adeafe 100644 --- a/docs/extensibility/snippets/MailDevResource/MailDev.Hosting/MailDev.Hosting.csproj +++ b/docs/extensibility/snippets/MailDevResource/MailDev.Hosting/MailDev.Hosting.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResource/MailDevResource.AppHost/MailDevResource.AppHost.csproj b/docs/extensibility/snippets/MailDevResource/MailDevResource.AppHost/MailDevResource.AppHost.csproj index 4e177d9495..10ac6c5b34 100644 --- a/docs/extensibility/snippets/MailDevResource/MailDevResource.AppHost/MailDevResource.AppHost.csproj +++ b/docs/extensibility/snippets/MailDevResource/MailDevResource.AppHost/MailDevResource.AppHost.csproj @@ -10,7 +10,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResource/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj b/docs/extensibility/snippets/MailDevResource/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/extensibility/snippets/MailDevResource/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj +++ b/docs/extensibility/snippets/MailDevResource/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResourceAndComponent/MailDev.Hosting/MailDev.Hosting.csproj b/docs/extensibility/snippets/MailDevResourceAndComponent/MailDev.Hosting/MailDev.Hosting.csproj index fc602e5bc4..1230adeafe 100644 --- a/docs/extensibility/snippets/MailDevResourceAndComponent/MailDev.Hosting/MailDev.Hosting.csproj +++ b/docs/extensibility/snippets/MailDevResourceAndComponent/MailDev.Hosting/MailDev.Hosting.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResourceAndComponent/MailDevResource.AppHost/MailDevResource.AppHost.csproj b/docs/extensibility/snippets/MailDevResourceAndComponent/MailDevResource.AppHost/MailDevResource.AppHost.csproj index 4e177d9495..10ac6c5b34 100644 --- a/docs/extensibility/snippets/MailDevResourceAndComponent/MailDevResource.AppHost/MailDevResource.AppHost.csproj +++ b/docs/extensibility/snippets/MailDevResourceAndComponent/MailDevResource.AppHost/MailDevResource.AppHost.csproj @@ -10,7 +10,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResourceAndComponent/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj b/docs/extensibility/snippets/MailDevResourceAndComponent/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/extensibility/snippets/MailDevResourceAndComponent/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj +++ b/docs/extensibility/snippets/MailDevResourceAndComponent/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResourceAndComponent/MailKit.Client/MailKit.Client.csproj b/docs/extensibility/snippets/MailDevResourceAndComponent/MailKit.Client/MailKit.Client.csproj index c543c8dbe9..f4b0cfa7a5 100644 --- a/docs/extensibility/snippets/MailDevResourceAndComponent/MailKit.Client/MailKit.Client.csproj +++ b/docs/extensibility/snippets/MailDevResourceAndComponent/MailKit.Client/MailKit.Client.csproj @@ -8,7 +8,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDev.Hosting/MailDev.Hosting.csproj b/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDev.Hosting/MailDev.Hosting.csproj index fc602e5bc4..1230adeafe 100644 --- a/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDev.Hosting/MailDev.Hosting.csproj +++ b/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDev.Hosting/MailDev.Hosting.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDevResource.AppHost/MailDevResource.AppHost.csproj b/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDevResource.AppHost/MailDevResource.AppHost.csproj index 4e177d9495..10ac6c5b34 100644 --- a/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDevResource.AppHost/MailDevResource.AppHost.csproj +++ b/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDevResource.AppHost/MailDevResource.AppHost.csproj @@ -10,7 +10,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj b/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj +++ b/docs/extensibility/snippets/MailDevResourceWithCredentials/MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/extensibility/snippets/MailDevResourceWithCredentials/MailKit.Client/MailKit.Client.csproj b/docs/extensibility/snippets/MailDevResourceWithCredentials/MailKit.Client/MailKit.Client.csproj index c543c8dbe9..f4b0cfa7a5 100644 --- a/docs/extensibility/snippets/MailDevResourceWithCredentials/MailKit.Client/MailKit.Client.csproj +++ b/docs/extensibility/snippets/MailDevResourceWithCredentials/MailKit.Client/MailKit.Client.csproj @@ -8,7 +8,7 @@ - + diff --git a/docs/frameworks/snippets/Dapr/Dapr.AppHost/Dapr.AppHost.csproj b/docs/frameworks/snippets/Dapr/Dapr.AppHost/Dapr.AppHost.csproj index 33a49c0a85..b29cd0e949 100644 --- a/docs/frameworks/snippets/Dapr/Dapr.AppHost/Dapr.AppHost.csproj +++ b/docs/frameworks/snippets/Dapr/Dapr.AppHost/Dapr.AppHost.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/docs/frameworks/snippets/Dapr/Dapr.ServiceDefaults/Dapr.ServiceDefaults.csproj b/docs/frameworks/snippets/Dapr/Dapr.ServiceDefaults/Dapr.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/frameworks/snippets/Dapr/Dapr.ServiceDefaults/Dapr.ServiceDefaults.csproj +++ b/docs/frameworks/snippets/Dapr/Dapr.ServiceDefaults/Dapr.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/frameworks/snippets/Orleans/OrleansAppHost/OrleansAppHost.csproj b/docs/frameworks/snippets/Orleans/OrleansAppHost/OrleansAppHost.csproj index f12ff38d42..c4f4e52fbc 100644 --- a/docs/frameworks/snippets/Orleans/OrleansAppHost/OrleansAppHost.csproj +++ b/docs/frameworks/snippets/Orleans/OrleansAppHost/OrleansAppHost.csproj @@ -10,10 +10,10 @@ - - - - + + + + diff --git a/docs/frameworks/snippets/Orleans/OrleansServiceDefaults/OrleansServiceDefaults.csproj b/docs/frameworks/snippets/Orleans/OrleansServiceDefaults/OrleansServiceDefaults.csproj index 3e0d94a75e..d39dbd4c83 100644 --- a/docs/frameworks/snippets/Orleans/OrleansServiceDefaults/OrleansServiceDefaults.csproj +++ b/docs/frameworks/snippets/Orleans/OrleansServiceDefaults/OrleansServiceDefaults.csproj @@ -15,7 +15,7 @@ - + diff --git a/docs/fundamentals/components-overview.md b/docs/fundamentals/components-overview.md index d3fa4be6af..f28b9fdba1 100644 --- a/docs/fundamentals/components-overview.md +++ b/docs/fundamentals/components-overview.md @@ -1,7 +1,7 @@ --- title: .NET Aspire components overview description: Explore the fundamental concepts of .NET Aspire components and learn how to integrate them into your apps. -ms.date: 05/23/2024 +ms.date: 07/23/2024 ms.topic: conceptual --- @@ -23,20 +23,24 @@ The following table lists the .NET Aspire components currently available for use |--|--|--| | [Apache Kafka](../messaging/kafka-component.md)
.NET Aspire logo. | [Aspire.Confluent.Kafka](https://www.nuget.org/packages/Aspire.Confluent.Kafka) | A library for producing and consuming messages from an [Apache Kafka](https://kafka.apache.org/) broker. | | [Azure AI OpenAI](../azureai/azureai-openai-component.md)
Azire OpenAI logo. | [Aspire.Azure.AI.OpenAI](https://www.nuget.org/packages/Aspire.Azure.AI.OpenAI) | A library for accessing [Azure AI OpenAI](/azure/ai-services/openai/overview) or OpenAI functionality. | -| [Azure Search Documents](../azureai/azureai-search-document-component.md)
Azure Search Documents logo. | [Aspire.Azure.Search.Documents](https://www.nuget.org/packages/Aspire.Azure.Search.Documents) | A library for accessing [Azure AI Search](/azure/search/search-what-is-azure-search). | | [Azure Blob Storage](../storage/azure-storage-blobs-component.md)
Azure Blog Storage logo. | [Aspire.Azure.Storage.Blobs](https://www.nuget.org/packages/Aspire.Azure.Storage.Blobs) | A library for accessing [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction). | | [Azure Cosmos DB Entity Framework Core](../database/azure-cosmos-db-entity-framework-component.md)
Azure Cosmos DB EF logo. | [Aspire.Microsoft.EntityFrameworkCore.Cosmos](https://www.nuget.org/packages/Aspire.Microsoft.EntityFrameworkCore.Cosmos) | A library for accessing Azure Cosmos DB databases with [Entity Framework Core](/ef/core/providers/cosmos/). | | [Azure Cosmos DB](../database/azure-cosmos-db-component.md)
Azure Cosmos DB logo. | [Aspire.Microsoft.Azure.Cosmos](https://www.nuget.org/packages/Aspire.Microsoft.Azure.Cosmos) | A library for accessing [Azure Cosmos DB](/azure/cosmos-db/introduction) databases. | | [Azure Event Hubs](../messaging/azure-event-hubs-component.md)
Azure Event Hubs logo. | [Aspire.Azure.Messaging.EventHubs](https://www.nuget.org/packages/Aspire.Azure.Messaging.EventHubs) | A library for accessing [Azure Event Hubs](/azure/event-hubs/event-hubs-about). | | [Azure Key Vault](../security/azure-security-key-vault-component.md)
Azure Key Vault logo. | [Aspire.Azure.Security.KeyVault](https://www.nuget.org/packages/Aspire.Azure.Security.KeyVault) | A library for accessing [Azure Key Vault](/azure/key-vault/general/overview). | +| [Azure Search Documents](../azureai/azureai-search-document-component.md)
Azure Search Documents logo. | [Aspire.Azure.Search.Documents](https://www.nuget.org/packages/Aspire.Azure.Search.Documents) | A library for accessing [Azure AI Search](/azure/search/search-what-is-azure-search). | | [Azure Service Bus](../messaging/azure-service-bus-component.md)
Azure Service Bus logo. | [Aspire.Azure.Messaging.ServiceBus](https://www.nuget.org/packages/Aspire.Azure.Messaging.ServiceBus) | A library for accessing [Azure Service Bus](/azure/service-bus-messaging/service-bus-messaging-overview). | | [Azure Storage Queues](../storage/azure-storage-queues-component.md)
Azure Storage Queues logo. | [Aspire.Azure.Storage.Queues](https://www.nuget.org/packages/Aspire.Azure.Storage.Queues) | A library for accessing [Azure Storage Queues](/azure/storage/queues/storage-queues-introduction). | | [Azure Table Storage](../storage/azure-storage-tables-component.md)
Azure Table Storage logo. | [Aspire.Azure.Data.Tables](https://www.nuget.org/packages/Aspire.Azure.Data.Tables) | A library for accessing the [Azure Table](/azure/storage/tables/table-storage-overview) service. | +| [Azure Web PubSub](../messaging/azure-web-pubsub-component.md)
Azure Web PubSub logo. | [Aspire.Azure.Messaging.WebPubSub](https://www.nuget.org/packages/Aspire.Azure.Messaging.WebPubSub) | A library for accessing the [Azure Web PubSub](/azure/azure-web-pubsub/) service. | +| [Elasticsearch](../search/elasticsearch-component.md)
Elasticsearch logo. | [Aspire.Elasticsearch.Client](https://www.nuget.org/packages/Aspire.Elasticsearch.Client) | A library for accessing [Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/client/index.html) databases. | +| [Keycloak](../authentication/keycloak-component.md)
.NET Aspire logo. | [Aspire.Keycloak.Authentication](https://www.nuget.org/packages/Aspire.Keycloak.Authentication) | A library for accessing [Keycloak](https://www.keycloak.org/docs/latest/server_admin/index.html) authentication. | +| [Milvus](../database/milvus-component.md)
Milvus logo. | [Aspire.Milvus.Client](https://www.nuget.org/packages/Aspire.Milvus.Client) | A library for accessing [Milvus](https://milvus.io/) databases. | | [MongoDB Driver](../database/mongodb-component.md)
MongoDB logo. | [Aspire.MongoDB.Driver](https://www.nuget.org/packages/Aspire.MongoDB.Driver) | A library for accessing [MongoDB](https://www.mongodb.com/docs) databases. | | [MySqlConnector](../database/mysql-component.md)
MySqlConnector logo. | [Aspire.MySqlConnector](https://www.nuget.org/packages/Aspire.MySqlConnector) | A library for accessing [MySqlConnector](https://mysqlconnector.net/) databases. | | [NATS](../messaging/nats-component.md)
NATS logo. | [Aspire.NATS.Net](https://www.nuget.org/packages/Aspire.NATS.Net) | A library for accessing [NATS](https://nats.io/) messaging. | -| [Pomelo MySQL Entity Framework Core](../database/mysql-entity-framework-component.md)
.NET Aspire logo. | [Aspire.Pomelo.EntityFrameworkCore.MySql](https://www.nuget.org/packages/Aspire.Pomelo.EntityFrameworkCore.MySql) | A library for accessing MySql databases with [Entity Framework Core](/ef/core). | | [Oracle Entity Framework Core](../database/oracle-entity-framework-component.md)
.NET Aspire logo. | [Aspire.Oracle.EntityFrameworkCore](https://www.nuget.org/packages/Aspire.Oracle.EntityFrameworkCore) | A library for accessing Oracle databases with [Entity Framework Core](/ef/core). | +| [Pomelo MySQL Entity Framework Core](../database/mysql-entity-framework-component.md)
.NET Aspire logo. | [Aspire.Pomelo.EntityFrameworkCore.MySql](https://www.nuget.org/packages/Aspire.Pomelo.EntityFrameworkCore.MySql) | A library for accessing MySql databases with [Entity Framework Core](/ef/core). | | [PostgreSQL Entity Framework Core](../database/postgresql-entity-framework-component.md)
PostgreSQL logo. | [Aspire.Npgsql.EntityFrameworkCore.PostgreSQL](https://www.nuget.org/packages/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL) | A library for accessing PostgreSQL databases using [Entity Framework Core](https://www.npgsql.org/efcore/index.html). | | [PostgreSQL](../database/postgresql-component.md)
PostgreSQL logo. | [Aspire.Npgsql](https://www.nuget.org/packages/Aspire.Npgsql) | A library for accessing [PostgreSQL](https://www.npgsql.org/doc/index.html) databases. | | [Qdrant](../database/qdrant-component.md)
Qdrant logo. | [Aspire.Qdrant.Client](https://www.nuget.org/packages/Aspire.Qdrant.Client) | A library for accessing [Qdrant](https://qdrant.tech/) databases. | diff --git a/docs/fundamentals/media/icons/AzureWebPubSub_256x.png b/docs/fundamentals/media/icons/AzureWebPubSub_256x.png new file mode 100644 index 0000000000..5625427aa4 Binary files /dev/null and b/docs/fundamentals/media/icons/AzureWebPubSub_256x.png differ diff --git a/docs/fundamentals/media/icons/Elastic_logo_256x.png b/docs/fundamentals/media/icons/Elastic_logo_256x.png new file mode 100644 index 0000000000..699ef0e036 Binary files /dev/null and b/docs/fundamentals/media/icons/Elastic_logo_256x.png differ diff --git a/docs/fundamentals/media/icons/Milvus_256x.png b/docs/fundamentals/media/icons/Milvus_256x.png new file mode 100644 index 0000000000..09004fcff5 Binary files /dev/null and b/docs/fundamentals/media/icons/Milvus_256x.png differ diff --git a/docs/fundamentals/snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj b/docs/fundamentals/snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj index 4c183dc273..a9228e7213 100644 --- a/docs/fundamentals/snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj +++ b/docs/fundamentals/snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/docs/fundamentals/snippets/components/AspireApp/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj b/docs/fundamentals/snippets/components/AspireApp/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/fundamentals/snippets/components/AspireApp/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj +++ b/docs/fundamentals/snippets/components/AspireApp/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/fundamentals/snippets/healthz/Healthz.ServiceDefaults/Healthz.ServiceDefaults.csproj b/docs/fundamentals/snippets/healthz/Healthz.ServiceDefaults/Healthz.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/fundamentals/snippets/healthz/Healthz.ServiceDefaults/Healthz.ServiceDefaults.csproj +++ b/docs/fundamentals/snippets/healthz/Healthz.ServiceDefaults/Healthz.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/fundamentals/snippets/networking/Networking.AppHost/Networking.AppHost.csproj b/docs/fundamentals/snippets/networking/Networking.AppHost/Networking.AppHost.csproj index 1c8d96710e..4bb9e45d13 100644 --- a/docs/fundamentals/snippets/networking/Networking.AppHost/Networking.AppHost.csproj +++ b/docs/fundamentals/snippets/networking/Networking.AppHost/Networking.AppHost.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/docs/fundamentals/snippets/networking/Networking.ServiceDefaults/Networking.ServiceDefaults.csproj b/docs/fundamentals/snippets/networking/Networking.ServiceDefaults/Networking.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/fundamentals/snippets/networking/Networking.ServiceDefaults/Networking.ServiceDefaults.csproj +++ b/docs/fundamentals/snippets/networking/Networking.ServiceDefaults/Networking.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/fundamentals/snippets/params/Parameters.ApiService/Parameters.ApiService.csproj b/docs/fundamentals/snippets/params/Parameters.ApiService/Parameters.ApiService.csproj index 5af75a18e8..95da5e0531 100644 --- a/docs/fundamentals/snippets/params/Parameters.ApiService/Parameters.ApiService.csproj +++ b/docs/fundamentals/snippets/params/Parameters.ApiService/Parameters.ApiService.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/fundamentals/snippets/params/Parameters.AppHost/Parameters.AppHost.csproj b/docs/fundamentals/snippets/params/Parameters.AppHost/Parameters.AppHost.csproj index 4ebd8c8f6b..45e9e84d04 100644 --- a/docs/fundamentals/snippets/params/Parameters.AppHost/Parameters.AppHost.csproj +++ b/docs/fundamentals/snippets/params/Parameters.AppHost/Parameters.AppHost.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/docs/fundamentals/snippets/params/Parameters.ServiceDefaults/Parameters.ServiceDefaults.csproj b/docs/fundamentals/snippets/params/Parameters.ServiceDefaults/Parameters.ServiceDefaults.csproj index 23006b8b7b..94e10ec058 100644 --- a/docs/fundamentals/snippets/params/Parameters.ServiceDefaults/Parameters.ServiceDefaults.csproj +++ b/docs/fundamentals/snippets/params/Parameters.ServiceDefaults/Parameters.ServiceDefaults.csproj @@ -12,7 +12,7 @@ - + diff --git a/docs/fundamentals/snippets/template/YourAppName/YourAppName.ServiceDefaults.csproj b/docs/fundamentals/snippets/template/YourAppName/YourAppName.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/fundamentals/snippets/template/YourAppName/YourAppName.ServiceDefaults.csproj +++ b/docs/fundamentals/snippets/template/YourAppName/YourAppName.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.AppHost/AspireApp1.AppHost.csproj b/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.AppHost/AspireApp1.AppHost.csproj index 65bd0d66ba..eac3bf3064 100644 --- a/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.AppHost/AspireApp1.AppHost.csproj +++ b/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.AppHost/AspireApp1.AppHost.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.ServiceDefaults/AspireApp1.ServiceDefaults.csproj b/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.ServiceDefaults/AspireApp1.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.ServiceDefaults/AspireApp1.ServiceDefaults.csproj +++ b/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.ServiceDefaults/AspireApp1.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.Tests/AspireApp1.Tests.csproj b/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.Tests/AspireApp1.Tests.csproj index c4e26ea722..2894b0cd2b 100644 --- a/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.Tests/AspireApp1.Tests.csproj +++ b/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.Tests/AspireApp1.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.Web/AspireApp1.Web.csproj b/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.Web/AspireApp1.Web.csproj index 57034996c4..344a1197dc 100644 --- a/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.Web/AspireApp1.Web.csproj +++ b/docs/fundamentals/snippets/testing/AspireApp1/AspireApp1.Web/AspireApp1.Web.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/fundamentals/snippets/volumes/VolumeMounts.AppHost/VolumeMounts.AppHost.csproj b/docs/fundamentals/snippets/volumes/VolumeMounts.AppHost/VolumeMounts.AppHost.csproj index 9c3920bc03..30a7a83de1 100644 --- a/docs/fundamentals/snippets/volumes/VolumeMounts.AppHost/VolumeMounts.AppHost.csproj +++ b/docs/fundamentals/snippets/volumes/VolumeMounts.AppHost/VolumeMounts.AppHost.csproj @@ -15,11 +15,11 @@ - - - - - + + + + + diff --git a/docs/fundamentals/snippets/volumes/VolumeMounts.ServiceDefaults/VolumeMounts.ServiceDefaults.csproj b/docs/fundamentals/snippets/volumes/VolumeMounts.ServiceDefaults/VolumeMounts.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/fundamentals/snippets/volumes/VolumeMounts.ServiceDefaults/VolumeMounts.ServiceDefaults.csproj +++ b/docs/fundamentals/snippets/volumes/VolumeMounts.ServiceDefaults/VolumeMounts.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/get-started/build-aspire-apps-with-nodejs.md b/docs/get-started/build-aspire-apps-with-nodejs.md index 0302e611a8..d6e351529f 100644 --- a/docs/get-started/build-aspire-apps-with-nodejs.md +++ b/docs/get-started/build-aspire-apps-with-nodejs.md @@ -1,10 +1,10 @@ --- -title: Add Node.js apps to a .NET Aspire project +title: Orchestrate Node.js apps in .NET Aspire description: Learn how to integrate Node.js and npm apps into a .NET Aspire App Host project. ms.date: 06/13/2024 --- -# Add Node.js apps to a .NET Aspire project +# Orchestrate Node.js apps in .NET Aspire In this article, you learn how to use Node.js and Node Package Manager (`npm`) apps in a .NET Aspire project. The sample app in this article demonstrates [Angular](https://angular.io), [React](https://react.dev/), and [Vue](https://vuejs.org/) client experiences. The following .NET Aspire APIs exist to support these scenarios: diff --git a/docs/get-started/build-aspire-apps-with-python.md b/docs/get-started/build-aspire-apps-with-python.md new file mode 100644 index 0000000000..098a3fabcc --- /dev/null +++ b/docs/get-started/build-aspire-apps-with-python.md @@ -0,0 +1,211 @@ +--- +title: Orchestrate Python apps in .NET Aspire +description: Learn how to integrate Python apps into a .NET Aspire App Host project. +ms.date: 07/23/2024 +--- + +# Orchestrate Python apps in .NET Aspire + +In this article, you learn how to use Python apps in a .NET Aspire project. The sample app in this article demonstrates launching a Python application. The Python extension for .NET Aspire requires the use of virtual environments. + +[!INCLUDE [aspire-prereqs](../includes/aspire-prereqs.md)] + +Additionally, you need to install [Python](https://www.python.org/downloads) on your machine. The sample app in this article was built with Python version 3.12.4 and pip version 24.1.2. To verify your Python and pip versions, run the following commands: + +```python +python --version +``` + +```python +pip --version +``` + +To download Python (including `pip`), see the [Python download page](https://www.python.org/downloads). + +## Create a .NET Aspire project using the template + +To get started launching a Python project in .NET Aspire first use the starter template to create a .NET Aspire application host: + +```dotnetcli +dotnet new aspire -o PythonSample +``` + +In the same terminal session, change directories into the newly created project: + +```dotnetcli +cd PythonSample +``` + +Once the template has been created launch the app host with the following command to ensure that the app host and the [.NET Aspire dashboard](../fundamentals/dashboard/overview.md) launches successfully: + +```dotnetcli +dotnet run --project PythonSample.AppHost/PythonSample.AppHost.csproj +``` + +Once the app host starts it should be possible to click on the dashboard link in the console output. At this point the dashboard will not show any resources. Stop the app host by pressing Ctrl + C in the terminal. + +## Prepare a Python project + +From your previous terminal session where you created the .NET Aspire solution, create a new directory to contain the Python source code. + +```Console +mkdir hello-python +``` + +Change directories into the newly created _hello-python_ directory: + +```Console +cd hello-python +``` + +### Initialize the Python virtual environment + +To work with Python projects, they need to be within a virtual environment. To create a virtual environment, run the following command: + +```python +python -m venv .venv +``` + +For more information on virtual environments, see the [Python: Install packages in a virtual environment using pip and venv](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/). + +To activate the virtual environment, enabling installation and usage of packages, run the following command: + +### [Unix/macOS](#tab/bash) + +```bash +source .venv/bin/activate +``` + +### [Windows](#tab/powershell) + +```powershell +.venv\Scripts\Activate.ps1 +``` + +--- + +Ensure that pip within the virtual environment is up-to-date by running the following command: + +```python +python -m pip install --upgrade pip +``` + +## Install Python packages + +Install the Flask package by creating a _requirements.txt_ file in the _hello-python_ directory and adding the following line: + +```python +Flask==3.0.3 +``` + +Then, install the Flask package by running the following command: + +```python +python -m pip install -r requirements.txt +``` + +After Flask is installed, create a new file named _main.py_ in the _hello-python_ directory and add the following code: + +```python +import os +import flask + +app = flask.Flask(__name__) + +@app.route('/', methods=['GET']) +def hello_world(): + return 'Hello, World!' + +if __name__ == '__main__': + port = int(os.environ.get('PORT', 8111)) + app.run(host='0.0.0.0', port=port) +``` + +The preceding code creates a simple Flask app that listens on port 8111 and returns the message `"Hello, World!"` when the root endpoint is accessed. + +## Update the app host project + +Install the Python hosting package by running the following command: + +```dotnetcli +dotnet add ../PythonSample.AppHost/PythonSample.AppHost.csproj package Aspire.Hosting.Python --version 8.1.0 +``` + +After the package is installed, the project XML should have a new package reference similar to the following: + +```xml + + + + Exe + net8.0 + enable + enable + true + + + + + + + + + + +``` + +Update the app host _Program.cs_ file to include the Python project, by calling the `AddPythonProject` API and specifying the project name, project path, and the entry point file: + +:::code source="snippets/PythonSample/PythonSample.AppHost/Program.cs"::: + +## Run the app + +Now that you've added the Python hosting package, updated the app host _Program.cs_ file, and created a Python project, you can run the app host: + +```dotnetcli +dotnet run --project PythonSample.AppHost/PythonSample.AppHost.csproj +``` + +Launch the dashboard by clicking the link in the console output. The dashboard should display the Python project as a resource. + +:::image source="media/python-dashboard.png" lightbox="media/python-dashboard.png" alt-text=".NET Aspire dashboard: Python sample app."::: + +Select the **Endpoints** link to open the `hello-python` endpoint in a new browser tab. The browser should display the message "Hello, World!": + +:::image source="media/python-hello-world.png" lightbox="media/python-hello-world.png" alt-text=".NET Aspire dashboard: Python sample app endpoint."::: + +Stop the app host by pressing Ctrl + C in the terminal. + +## Add telemetry support. + +To add a bit of observability, add telemetry to help monitor the dependant Python app. In the Python project, add the following OpenTelemetry package as a dependency in the _requirements.txt_ file: + +:::code language="python" source="snippets/PythonSample/hello-python/requirements.txt" highlight="2"::: + +The preceding requirement update, adds the OpenTelemetry package and the OTLP exporter. Next, re-install the Python app requirements into the virtual environment by running the following command: + +```python +python -m pip install -r requirements.txt +``` + +The preceding command installs the OpenTelemetry package and the OTLP exporter, in the virtual environment. Update the Python app to include the OpenTelemetry code, by replacing the existing _main.py_ code with the following: + +:::code language="python" source="snippets/PythonSample/hello-python/main.py"::: + +Update the app host project's _launchSettings.json_ file to include the `ASPIRE_ALLOW_UNSECURED_TRANSPORT` environment variable: + +:::code language="json" source="snippets/PythonSample/PythonSample.AppHost/Properties/launchSettings.json"::: + +The `ASPIRE_ALLOW_UNSECURED_TRANSPORT` variable is required because when running locally the OpenTelemetry client in Python rejects the local development certificate. Launch the _app host_ again: + +```dotnetcli +dotnet run --project PythonSample.AppHost/PythonSample.AppHost.csproj +``` + +Once the app host has launched navigate to the dashboard and note that in addition to console log output, structured logging is also being routed through to the dashboard. + +:::image source="media/python-telemetry-in-dashboard.png" lightbox="media/python-telemetry-in-dashboard.png" alt-text=".NET Aspire dashboard: Structured logging from Python process."::: + +## Summary + +While there are several considerations that are beyond the scope of this article, you learned how to build .NET Aspire solution that integrates with Python. You also learned how to use the `AddPythonProject` API to host Python apps. diff --git a/docs/get-started/media/python-dashboard.png b/docs/get-started/media/python-dashboard.png new file mode 100644 index 0000000000..5d68a57f24 Binary files /dev/null and b/docs/get-started/media/python-dashboard.png differ diff --git a/docs/get-started/media/python-hello-world.png b/docs/get-started/media/python-hello-world.png new file mode 100644 index 0000000000..25f562030c Binary files /dev/null and b/docs/get-started/media/python-hello-world.png differ diff --git a/docs/get-started/media/python-telemetry-in-dashboard.png b/docs/get-started/media/python-telemetry-in-dashboard.png new file mode 100644 index 0000000000..44f4d4940b Binary files /dev/null and b/docs/get-started/media/python-telemetry-in-dashboard.png differ diff --git a/docs/get-started/snippets/PythonSample/PythonSample.AppHost/Program.cs b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/Program.cs new file mode 100644 index 0000000000..15b370cffe --- /dev/null +++ b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/Program.cs @@ -0,0 +1,8 @@ +var builder = DistributedApplication.CreateBuilder(args); + +builder.AddPythonProject("hello-python", "../hello-python", "main.py") + .WithEndpoint(targetPort: 8111, scheme: "http", env: "PORT") + //.WithEnvironment("OTEL_PYTHON_OTLP_TRACES_SSL", "false") + ; + +builder.Build().Run(); diff --git a/docs/get-started/snippets/PythonSample/PythonSample.AppHost/Properties/launchSettings.json b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/Properties/launchSettings.json new file mode 100644 index 0000000000..868c4ed01b --- /dev/null +++ b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/Properties/launchSettings.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:15209", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19171", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20208", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" + } + } + } +} diff --git a/docs/get-started/snippets/PythonSample/PythonSample.AppHost/PythonSample.AppHost.csproj b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/PythonSample.AppHost.csproj new file mode 100644 index 0000000000..e3c32cb096 --- /dev/null +++ b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/PythonSample.AppHost.csproj @@ -0,0 +1,17 @@ + + + + Exe + net8.0 + enable + enable + true + 5fd92a87-fff8-4a09-9f6e-2c0d656e25ba + + + + + + + + diff --git a/docs/get-started/snippets/PythonSample/PythonSample.AppHost/appsettings.Development.json b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/appsettings.Development.json new file mode 100644 index 0000000000..0c208ae918 --- /dev/null +++ b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/docs/get-started/snippets/PythonSample/PythonSample.AppHost/appsettings.json b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/appsettings.json new file mode 100644 index 0000000000..31c092aa45 --- /dev/null +++ b/docs/get-started/snippets/PythonSample/PythonSample.AppHost/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Aspire.Hosting.Dcp": "Warning" + } + } +} diff --git a/docs/get-started/snippets/PythonSample/PythonSample.ServiceDefaults/Extensions.cs b/docs/get-started/snippets/PythonSample/PythonSample.ServiceDefaults/Extensions.cs new file mode 100644 index 0000000000..ce94dc2c43 --- /dev/null +++ b/docs/get-started/snippets/PythonSample/PythonSample.ServiceDefaults/Extensions.cs @@ -0,0 +1,111 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Logging; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.Hosting; + +// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. +// This project should be referenced by each service project in your solution. +// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults +public static class Extensions +{ + public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder) + { + builder.ConfigureOpenTelemetry(); + + builder.AddDefaultHealthChecks(); + + builder.Services.AddServiceDiscovery(); + + builder.Services.ConfigureHttpClientDefaults(http => + { + // Turn on resilience by default + http.AddStandardResilienceHandler(); + + // Turn on service discovery by default + http.AddServiceDiscovery(); + }); + + return builder; + } + + public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder) + { + builder.Logging.AddOpenTelemetry(logging => + { + logging.IncludeFormattedMessage = true; + logging.IncludeScopes = true; + }); + + builder.Services.AddOpenTelemetry() + .WithMetrics(metrics => + { + metrics.AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddRuntimeInstrumentation(); + }) + .WithTracing(tracing => + { + tracing.AddAspNetCoreInstrumentation() + // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) + //.AddGrpcClientInstrumentation() + .AddHttpClientInstrumentation(); + }); + + builder.AddOpenTelemetryExporters(); + + return builder; + } + + private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder) + { + var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); + + if (useOtlpExporter) + { + builder.Services.AddOpenTelemetry().UseOtlpExporter(); + } + + // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package) + //if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"])) + //{ + // builder.Services.AddOpenTelemetry() + // .UseAzureMonitor(); + //} + + return builder; + } + + public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicationBuilder builder) + { + builder.Services.AddHealthChecks() + // Add a default liveness check to ensure app is responsive + .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]); + + return builder; + } + + public static WebApplication MapDefaultEndpoints(this WebApplication app) + { + // Adding health checks endpoints to applications in non-development environments has security implications. + // See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments. + if (app.Environment.IsDevelopment()) + { + // All health checks must pass for app to be considered ready to accept traffic after starting + app.MapHealthChecks("/health"); + + // Only health checks tagged with the "live" tag must pass for app to be considered alive + app.MapHealthChecks("/alive", new HealthCheckOptions + { + Predicate = r => r.Tags.Contains("live") + }); + } + + return app; + } +} diff --git a/docs/get-started/snippets/PythonSample/PythonSample.ServiceDefaults/PythonSample.ServiceDefaults.csproj b/docs/get-started/snippets/PythonSample/PythonSample.ServiceDefaults/PythonSample.ServiceDefaults.csproj new file mode 100644 index 0000000000..589e39190a --- /dev/null +++ b/docs/get-started/snippets/PythonSample/PythonSample.ServiceDefaults/PythonSample.ServiceDefaults.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + enable + enable + true + + + + + + + + + + + + + + + diff --git a/docs/get-started/snippets/PythonSample/PythonSample.sln b/docs/get-started/snippets/PythonSample/PythonSample.sln new file mode 100644 index 0000000000..a80fd19c03 --- /dev/null +++ b/docs/get-started/snippets/PythonSample/PythonSample.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.0.0 +MinimumVisualStudioVersion = 17.8.0.0 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PythonSample.AppHost", "PythonSample.AppHost\PythonSample.AppHost.csproj", "{A80C6371-75DE-47A1-8738-385C54E4B590}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PythonSample.ServiceDefaults", "PythonSample.ServiceDefaults\PythonSample.ServiceDefaults.csproj", "{687DF80B-3F67-49D7-8A94-B67EA5BD9150}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A80C6371-75DE-47A1-8738-385C54E4B590}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A80C6371-75DE-47A1-8738-385C54E4B590}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A80C6371-75DE-47A1-8738-385C54E4B590}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A80C6371-75DE-47A1-8738-385C54E4B590}.Release|Any CPU.Build.0 = Release|Any CPU + {687DF80B-3F67-49D7-8A94-B67EA5BD9150}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {687DF80B-3F67-49D7-8A94-B67EA5BD9150}.Debug|Any CPU.Build.0 = Debug|Any CPU + {687DF80B-3F67-49D7-8A94-B67EA5BD9150}.Release|Any CPU.ActiveCfg = Release|Any CPU + {687DF80B-3F67-49D7-8A94-B67EA5BD9150}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {31663D15-365E-4029-A40F-C4095F36802A} + EndGlobalSection +EndGlobal diff --git a/docs/get-started/snippets/PythonSample/hello-python/main.py b/docs/get-started/snippets/PythonSample/hello-python/main.py new file mode 100644 index 0000000000..7f1da16246 --- /dev/null +++ b/docs/get-started/snippets/PythonSample/hello-python/main.py @@ -0,0 +1,17 @@ +import os +import flask +import logging + +logging.basicConfig() +logging.getLogger().setLevel(logging.NOTSET) + +app = flask.Flask(__name__) + +@app.route('/', methods=['GET']) +def hello_world(): + logging.getLogger(__name__).info("request received!") + return 'Hello, World!' + +if __name__ == '__main__': + port = int(os.environ.get('PORT', 8111)) + app.run(host='0.0.0.0', port=port) \ No newline at end of file diff --git a/docs/get-started/snippets/PythonSample/hello-python/requirements.txt b/docs/get-started/snippets/PythonSample/hello-python/requirements.txt new file mode 100644 index 0000000000..a626628ba2 --- /dev/null +++ b/docs/get-started/snippets/PythonSample/hello-python/requirements.txt @@ -0,0 +1,2 @@ +Flask==3.0.3 +opentelemetry-distro[otlp] \ No newline at end of file diff --git a/docs/get-started/snippets/quickstart/AspireSample/AspireSample.AppHost/AspireSample.AppHost.csproj b/docs/get-started/snippets/quickstart/AspireSample/AspireSample.AppHost/AspireSample.AppHost.csproj index c7ccd1f190..a45d57e615 100644 --- a/docs/get-started/snippets/quickstart/AspireSample/AspireSample.AppHost/AspireSample.AppHost.csproj +++ b/docs/get-started/snippets/quickstart/AspireSample/AspireSample.AppHost/AspireSample.AppHost.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/docs/get-started/snippets/quickstart/AspireSample/AspireSample.ServiceDefaults/AspireSample.ServiceDefaults.csproj b/docs/get-started/snippets/quickstart/AspireSample/AspireSample.ServiceDefaults/AspireSample.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/get-started/snippets/quickstart/AspireSample/AspireSample.ServiceDefaults/AspireSample.ServiceDefaults.csproj +++ b/docs/get-started/snippets/quickstart/AspireSample/AspireSample.ServiceDefaults/AspireSample.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/get-started/snippets/quickstart/AspireSample/AspireSample.Web/AspireSample.Web.csproj b/docs/get-started/snippets/quickstart/AspireSample/AspireSample.Web/AspireSample.Web.csproj index 95909a7892..cee24fbc67 100644 --- a/docs/get-started/snippets/quickstart/AspireSample/AspireSample.Web/AspireSample.Web.csproj +++ b/docs/get-started/snippets/quickstart/AspireSample/AspireSample.Web/AspireSample.Web.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/index.yml b/docs/index.yml index 1121bf09a2..bdf17a369c 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -136,6 +136,9 @@ conceptualContent: - itemType: overview text: Azure Service Bus url: messaging/azure-service-bus-component.md + - itemType: overview + text: Azure Web PubSub + url: messaging/azure-web-pubsub-component.md - itemType: how-to-guide text: RabbitMQ client .NET Aspire component url: messaging/rabbitmq-client-component.md @@ -235,6 +238,15 @@ conceptualContent: - itemType: training text: Use telemetry in a .NET Aspire project url: /training/modules/use-telemetry-dotnet-aspire + - itemType: training + text: Use databases in a .NET Aspire project + url: /training/modules/use-databases-dotnet-aspire-app/ + - itemType: training + text: Improve performance with a cache in a .NET Aspire project + url: /training/modules/improve-performance-cache-aspire/ + - itemType: training + text: Send messages with RabbitMQ in a .NET Aspire project + url: /training/modules/send-messages-rabbitmq-dotnet-aspire-app/ additionalContent: sections: diff --git a/docs/messaging/azure-event-hubs-component.md b/docs/messaging/azure-event-hubs-component.md index d9edff769e..9bf03865ed 100644 --- a/docs/messaging/azure-event-hubs-component.md +++ b/docs/messaging/azure-event-hubs-component.md @@ -2,7 +2,7 @@ title: .NET Aspire Azure Event Hubs component description: This article describes the .NET Aspire Azure Event Hubs component features and capabilities. ms.topic: how-to -ms.date: 07/17/2024 +ms.date: 07/23/2024 --- # .NET Aspire Azure Event Hubs component @@ -94,12 +94,22 @@ var builder = DistributedApplication.CreateBuilder(args); var eventHubs = builder.AddAzureEventHubs("eventHubsConnectionName") .AddEventHub("MyHub"); -var ExampleService = builder.AddProject() +var exampleService = builder.AddProject() .WithReference(eventHubs); ``` The `AddAzureEventHubs` method will read connection information from the AppHost's configuration (for example, from "user secrets") under the `ConnectionStrings:eventHubsConnectionName` config key. The `WithReference` method passes that connection information into a connection string named `eventHubsConnectionName` in the `ExampleService` project. +As of .NET Aspire 8.1, the Azure EventHubs extension for .NET Aspire supports launching a local emulator for EventHubs. You can use the emulator by applying the `RunAsEmulator()` extension method as follows: + +```csharp +var eventHubs = builder.AddAzureEventHubs("eventHubsConnectionName") + .RunAsEmulator() + .AddEventHub("MyHub"); +``` + +The emulator for Azure EventHubs results in two container resources being launched inside .NET Aspire derived from the name of the Event Hubs resource name. + > [!IMPORTANT] > Even though we are creating an Event Hub using the `AddEventHub` at the same time as the namespace, as of .NET Aspire version `preview-5`, the connection string will not include the `EntityPath` property, so the `EventHubName` property must be set in the settings callback for the preferred client. Future versions of Aspire will include the `EntityPath` property in the connection string and will not require the `EventHubName` property to be set in this scenario. diff --git a/docs/messaging/azure-web-pubsub-component.md b/docs/messaging/azure-web-pubsub-component.md new file mode 100644 index 0000000000..1445fac96b --- /dev/null +++ b/docs/messaging/azure-web-pubsub-component.md @@ -0,0 +1,198 @@ +--- +title: .NET Aspire Azure Web PubSub component +description: This article describes the .NET Aspire Azure Web PubSub component features and capabilities. +ms.topic: how-to +ms.date: 07/23/2024 +--- + +# .NET Aspire Azure Web PubSub component + +In this article, you learn how to use the .NET Aspire Azure Web PubSub component. The `Aspire.Azure.Messaging.WebPubSub` library offers options for registering an in the DI container for connecting to [Azure Web PubSub](/azure/azure-web-pubsub). + +## Prerequisites + +- Azure subscription: [create one for free](https://azure.microsoft.com/free/). +- An existing Azure Web PubSub service instance. For more information, see [Create a Web PubSub resource](/azure/azure-web-pubsub/howto-develop-create-instance). Alternatively, you can use a connection string, which isn't recommended in production environments. + +## Get started + +To get started with the .NET Aspire Azure Web PubSub component, install the [Aspire.Azure.Messaging.WebPubSub](https://www.nuget.org/packages/Aspire.Azure.Messaging.WebPubSub) NuGet package in the consuming client project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Azure.Messaging.WebPubSub +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). + +## Example usage + +In the _Program.cs_ file of your project, call the `AddAzureWebPubSubHub` extension method to register a `WebPubSubServiceClient` for use via the dependency injection container. The method takes a connection name parameter. + +```csharp +builder.AddAzureWebPubSubServiceClient("wps"); +``` + +You can then retrieve the `WebPubSubServiceClient` instance using dependency injection. For example, to retrieve the client from a service: + +```csharp +public class ExampleService(WebPubSubServiceClient client) +{ + // Use client... +} +``` + +For more information, see the [Azure.Messaging.WebPubSub documentation](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/webpubsub/Azure.Messaging.WebPubSub/README.md). + +## App host usage + +To add Azure Web PubSub hosting support to your , install the [Aspire.Hosting.Azure.WebPubSub](https://www.nuget.org/packages/Aspire.Hosting.Azure.WebPubSub) NuGet package in the [app host](xref:aspire/app-host) project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Hosting.Azure.WebPubSub +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +In your app host project, add a Web PubSub connection and consume the connection using the following methods: + +```csharp +var webPubSub = builder.AddAzureWebPubSub("wps"); + +var exampleService = builder.AddProject() + .WithReference(webPubSub); +``` + +The `AddAzureWebPubSubHub` method reads connection information from the app host's configuration (for example, from "user secrets") under the `ConnectionStrings:wps` configuration key. The `WithReference` method passes that connection information into a connection string named `wps` in the `ExampleService` project. In the _Program.cs_ file of `ExampleService`, the connection can be consumed using: + +```csharp +builder.AddAzureWebPubSubServiceClient("wps"); +``` + +## Configuration + +The .NET Aspire Azure Web PubSub library provides multiple options to configure the Azure Web PubSub connection based on the requirements and conventions of your project. Note that either a `Endpoint` or a `ConnectionString` is a required to be supplied. + +### Use a connection string + +When using a connection string from the `ConnectionStrings` configuration section, you can provide the name of the connection string when calling `builder.AddAzureWebPubSubHub()`: + +```csharp +builder.AddAzureWebPubSubServiceClient( + "WebPubSubConnectionName", + "your_hub_name"); +``` + +And then the connection information will be retrieved from the `ConnectionStrings` configuration section. Two connection formats are supported: + +#### Use the service endpoint + +The recommended approach is to use the service endpoint, which works with the `AzureMessagingWebPubSubSettings.Credential` property to establish a connection. If no credential is configured, the [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential) is used. + +```json +{ + "ConnectionStrings": { + "WebPubSubConnectionName": "https://xxx.webpubsub.azure.com" + } +} +``` + +#### Connection string + +Alternatively, a connection string can be used. + +```json +{ + "ConnectionStrings": { + "WebPubSubConnectionName": "Endpoint=https://xxx.webpubsub.azure.com;AccessKey==xxxxxxx" + } +} +``` + +### Use configuration providers + +The .NET Aspire Azure Web PubSub library supports [Microsoft.Extensions.Configuration](/dotnet/api/microsoft.extensions.configuration). It loads the `AzureMessagingWebPubSubSettings` and `WebPubSubServiceClientOptions` from configuration by using the `Aspire:Azure:Messaging:WebPubSub` key. Consider the example _appsettings.json_ that configures some of the options: + +```json +{ + "Aspire": { + "Azure": { + "Messaging": { + "WebPubSub": { + "DisableHealthChecks": true, + "HubName": "your_hub_name" + } + } + } + } +} +``` + +### Use inline delegates + +You can also pass the `Action configureSettings` delegate to set up some or all the options inline, for example to disable health checks from code: + +```csharp +builder.AddAzureWebPubSubServiceClient( + "wps", + settings => settings.DisableHealthChecks = true); +``` + +You can also setup the using the optional `Action> configureClientBuilder` parameter of the `AddAzureWebPubSubHub` method. For example, to set the client ID for this client: + +```csharp +builder.AddAzureWebPubSubServiceClient( + "wps", + configureClientBuilder: clientBuilder => + clientBuilder.ConfigureOptions(options => options.Retry.MaxRetries = 5)); +``` + +[!INCLUDE [component-health-checks](../includes/component-health-checks.md)] + +The .NET Aspire Azure Web PubSub component handles exposes a configurable health check that reports as _healthy_, when the client can successfully connect to the Azure Web PubSub service. + +[!INCLUDE [component-observability-and-telemetry](../includes/component-observability-and-telemetry.md)] + +### Logging + +The .NET Aspire Azure Web PubSub component uses the following log categories: + +- `Azure` +- `Azure.Core` +- `Azure.Identity` +- `Azure.Messaging.WebPubSub` + +### Tracing + +The .NET Aspire Azure Web PubSub component will emit the following tracing activities using OpenTelemetry: + +- "Azure.Messaging.WebPubSub.*" + +### Metrics + +The .NET Aspire Azure Web PubSub component currently doesn't support metrics by default due to limitations with the Azure SDK for .NET. If that changes in the future, this section will be updated to reflect those changes. + +## See also + +- [Azure Web PubSub](/azure/azure-web-pubsub/) +- [.NET Aspire components](../fundamentals/components-overview.md) +- [.NET Aspire GitHub repo](https://github.com/dotnet/aspire) diff --git a/docs/real-time/snippets/signalr/SignalR.AppHost/SignalR.AppHost.csproj b/docs/real-time/snippets/signalr/SignalR.AppHost/SignalR.AppHost.csproj index e05915bb9f..8dd8bd2646 100644 --- a/docs/real-time/snippets/signalr/SignalR.AppHost/SignalR.AppHost.csproj +++ b/docs/real-time/snippets/signalr/SignalR.AppHost/SignalR.AppHost.csproj @@ -15,9 +15,9 @@
- - - + + + \ No newline at end of file diff --git a/docs/real-time/snippets/signalr/SignalR.ServiceDefaults/SignalR.ServiceDefaults.csproj b/docs/real-time/snippets/signalr/SignalR.ServiceDefaults/SignalR.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/real-time/snippets/signalr/SignalR.ServiceDefaults/SignalR.ServiceDefaults.csproj +++ b/docs/real-time/snippets/signalr/SignalR.ServiceDefaults/SignalR.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/search/elasticsearch-component.md b/docs/search/elasticsearch-component.md new file mode 100644 index 0000000000..387690e560 --- /dev/null +++ b/docs/search/elasticsearch-component.md @@ -0,0 +1,202 @@ +--- +title: .NET Aspire Elasticsearch component +description: This article describes the .NET Aspire Elasticsearch component features and capabilities. +ms.topic: how-to +ms.date: 07/23/2024 +--- + +# .NET Aspire Elasticsearch component + +In this article, you learn how to use the .NET Aspire Elasticsearch component. The `Aspire.Elastic.Clients.Elasticsearch` library registers a [ElasticsearchClient](https://github.com/elastic/elasticsearch-net) in the DI container for connecting to a Elasticsearch. It enables corresponding health check and telemetry. + +## Prerequisites + +- Elasticsearch cluster. +- Endpoint URI string for accessing the Elasticsearch API endpoint or a CloudId and an ApiKey from [Elastic Cloud](https://www.elastic.co/cloud) + +## Get started + +To get started with the .NET Aspire Elasticsearch component, install the [Aspire.Elastic.Clients.Elasticsearch](https://www.nuget.org/packages/Aspire.Elastic.Clients.Elasticsearch) NuGet package in the consuming client project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Elastic.Clients.Elasticsearch +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). + +## Example usage + +In the _Program.cs_ file of your project, call the `AddElasticsearchClient` extension method to register a `ElasticsearchClient` for use via the dependency injection container. The method takes a connection name parameter. + +```csharp +builder.AddElasticsearchClient("elasticsearch"); +``` + +## App host usage + +To model the Elasticsearch resource in the app host, install the [Aspire.Hosting.Elasticsearch](https://www.nuget.org/packages/Aspire.Hosting.Elasticsearch) NuGet package in the [app host](xref:aspire/app-host) project. + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Aspire.Hosting.Elasticsearch +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +In the _Program.cs_ file of `AppHost`, register a Elasticsearch cluster and consume the connection using the following methods: + +```csharp +var elasticsearch = builder.AddElasticsearch("elasticsearch"); + +var myService = builder.AddProject() + .WithReference(elasticsearch); +``` + +The `WithReference` method configures a connection in the `MyService` project named `elasticsearch`. In the _Program.cs_ file of `MyService`, the Elasticsearch connection can be consumed using: + +```csharp +builder.AddElasticsearchClient("elasticsearch"); +``` + +## Configuration + +The .NET Aspire Elasticsearch client component provides multiple options to configure the server connection based on the requirements and conventions of your project. + +### Use a connection string + +When using a connection string from the `ConnectionStrings` configuration section, you can provide the name of the connection string when calling `builder.AddElasticsearchClient()`: + +```csharp +builder.AddElasticsearchClient("elasticsearch"); +``` + +And then the connection string will be retrieved from the `ConnectionStrings` configuration section: + +```json +{ + "ConnectionStrings": { + "elasticsearch": "http://elastic:password@localhost:27011" + } +} +``` + +### Use configuration providers + +The .NET Aspire Elasticsearch Client component supports [Microsoft.Extensions.Configuration](/dotnet/api/microsoft.extensions.configuration). It loads the `ElasticClientsElasticsearchSettings` from configuration by using the `Aspire:Elastic:Clients:Elasticsearch` key. Consider the following example _appsettings.json_ that configures some of the options: + +```json +{ + "Aspire": { + "Elastic": { + "Clients": { + "Elasticsearch": { + "Endpoint": "http://elastic:password@localhost:27011" + } + } + } + } +} +``` + +### Use inline delegates + +Also you can pass the `Action configureSettings` delegate to set up some or all the options inline, for example to set the API key from code: + +```csharp +builder.AddElasticsearchClient( + "elasticsearch", + settings => + settings.Endpoint = new Uri("http://elastic:password@localhost:27011")); +``` + +### Use a `CloudId` and an `ApiKey` with configuration providers + +When using [Elastic Cloud](https://www.elastic.co/cloud), you can provide the `CloudId` and `ApiKey` in `Aspire:Elastic:Clients:Elasticsearch` section when calling `builder.AddElasticsearchClient()`. + +```csharp +builder.AddElasticsearchClient("elasticsearch"); +``` + +Consider the following example _appsettings.json_ that configures the options: + +```json +{ + "Aspire": { + "Elastic": { + "Clients": { + "Elasticsearch": { + "ApiKey": "", + "CloudId": "" + } + } + } + } +} +``` + +### Use a `CloudId` and an `ApiKey` with inline delegates + +```csharp +builder.AddElasticsearchClient( + "elasticsearch", + settings => + { + settings.ApiKey = ""; + settings.CloudId = ""; + }); +``` + +[!INCLUDE [component-health-checks](../includes/component-health-checks.md)] + +The .NET Aspire Elasticsearch component uses the configured client to perform a `PingAsync`. If the result is an HTTP 200 OK, the health check is considered healthy, otherwise it's unhealthy. Likewise, if there's an exception, the health check is considered unhealthy with the error propagating through the health check failure. + +[!INCLUDE [component-observability-and-telemetry](../includes/component-observability-and-telemetry.md)] + +### Tracing + +The .NET Aspire Elasticsearch component will emit the following tracing activities using OpenTelemetry: + +- `Elastic.Transport` + +## See also + +- [Elasticsearch .NET](https://github.com/elastic/elasticsearch-net) +- [.NET Aspire components](../fundamentals/components-overview.md) +- [.NET Aspire GitHub repo](https://github.com/dotnet/aspire) + + \ No newline at end of file diff --git a/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.AppHost/AspireStorage.AppHost.csproj b/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.AppHost/AspireStorage.AppHost.csproj index f69dddc918..5bc9d73a74 100644 --- a/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.AppHost/AspireStorage.AppHost.csproj +++ b/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.AppHost/AspireStorage.AppHost.csproj @@ -16,8 +16,8 @@
- - + + diff --git a/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.ServiceDefaults/AspireStorage.ServiceDefaults.csproj b/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.ServiceDefaults/AspireStorage.ServiceDefaults.csproj index b8d847c913..84e9efc96f 100644 --- a/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.ServiceDefaults/AspireStorage.ServiceDefaults.csproj +++ b/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.ServiceDefaults/AspireStorage.ServiceDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.Web/AspireStorage.Web.csproj b/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.Web/AspireStorage.Web.csproj index 41c6bc2ddd..21754bb58f 100644 --- a/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.Web/AspireStorage.Web.csproj +++ b/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.Web/AspireStorage.Web.csproj @@ -11,8 +11,8 @@
- - + + diff --git a/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.WorkerService/AspireStorage.WorkerService.csproj b/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.WorkerService/AspireStorage.WorkerService.csproj index f65e12cee3..9d0b8aa205 100644 --- a/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.WorkerService/AspireStorage.WorkerService.csproj +++ b/docs/storage/snippets/tutorial/AspireStorage/AspireStorage.WorkerService/AspireStorage.WorkerService.csproj @@ -8,7 +8,7 @@ - + diff --git a/docs/toc.yml b/docs/toc.yml index 6b327f8576..bb9adc810d 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -12,8 +12,6 @@ items: href: get-started/build-your-first-aspire-app.md - name: Tutorial - Add .NET Aspire to an existing .NET app href: get-started/add-aspire-existing-app.md - - name: Sample - Add Node.js apps to a .NET Aspire project - href: get-started/build-aspire-apps-with-nodejs.md - name: Setup and tooling href: fundamentals/setup-tooling.md - name: What's new in .NET Aspire @@ -24,6 +22,13 @@ items: - name: Overview displayName: orchestration,aspire apphost,aspire app href: fundamentals/app-host-overview.md + - name: Orchestrate Node.js apps in .NET Aspire + href: get-started/build-aspire-apps-with-nodejs.md + - name: Orchestrate Python apps in .NET Aspire + href: get-started/build-aspire-apps-with-python.md + - name: Add Dockerfiles to the app model + href: app-host/withdockerfile.md + displayName: dockerfile,docker - name: Networking overview displayName: inner loop,local networking href: fundamentals/networking-overview.md @@ -135,6 +140,18 @@ items: - name: Azure Table Storage displayName: table storage,azure storage href: storage/azure-storage-tables-component.md + - name: Azure Web PubSub + displayName: web pubsub,real-time,messaging + href: messaging/azure-web-pubsub-component.md + - name: Elasticsearch + displayName: elasticsearch,search + href: search/elasticsearch-component.md + - name: Keycloak + displayName: security,openid connect,single sign-on,sso,identity,federation,account management + href: authentication/keycloak-component.md + - name: Milvus + displayName: milvus,database + href: database/milvus-component.md - name: MongoDB displayName: mongodb,database href: database/mongodb-component.md @@ -165,14 +182,23 @@ items: - name: Overview href: caching/stackexchange-redis-caching-overview.md - name: Redis caching - displayName: caching href: caching/stackexchange-redis-component.md - name: Redis distributed cache - displayName: distributed caching href: caching/stackexchange-redis-distributed-caching-component.md - name: Redis output caching - displayName: output caching href: caching/stackexchange-redis-output-caching-component.md + - name: Redis caching (Garnet) + href: caching/stackexchange-redis-component.md?pivots=garnet + - name: Redis distributed cache (Garnet) + href: caching/stackexchange-redis-distributed-caching-component.md?pivots=garnet + - name: Redis output caching (Garnet) + href: caching/stackexchange-redis-output-caching-component.md?pivots=garnet + - name: Redis caching (Valkey) + href: caching/stackexchange-redis-component.md?pivots=valkey + - name: Redis distributed cache (Valkey) + href: caching/stackexchange-redis-distributed-caching-component.md?pivots=valkey + - name: Redis output caching (Valkey) + href: caching/stackexchange-redis-output-caching-component.md?pivots=valkey - name: SQL Server items: - name: SQL Database - EF Core diff --git a/docs/zones/zone-pivot-groups.yml b/docs/zones/zone-pivot-groups.yml index 6bc5cf7074..ff2b0b95c6 100644 --- a/docs/zones/zone-pivot-groups.yml +++ b/docs/zones/zone-pivot-groups.yml @@ -43,4 +43,13 @@ groups: title: Visual Studio Code - id: dotnet-cli title: .NET CLI - +- id: resp-host + title: RESP Host + prompt: Choose a RESP Hosting resource type + pivots: + - id: redis + title: Redis + - id: garnet + title: Garnet + - id: valkey + title: Valkey