Skip to content

Commit 12bbb6f

Browse files
joperezreerhardt
andauthored
Update eshop to Aspire 9.2 (#813)
* Update eshop to Aspire 9.2 * Fix tests * Fix issue with bootstrap causing the build to break. * Simplify OpenAI code and configuration * Remove nuget.config changes now that 9.2 is live. Use AspnetVersion property --------- Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>
1 parent a0eef0a commit 12bbb6f

File tree

13 files changed

+67
-89
lines changed

13 files changed

+67
-89
lines changed

Directory.Packages.props

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@
22
<PropertyGroup>
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
5-
<AspnetVersion>9.0.2</AspnetVersion>
6-
<MicrosoftExtensionsVersion>9.0.3</MicrosoftExtensionsVersion>
7-
<MicrosoftExtensionsAIVersion>9.3.0-preview.1.25161.3</MicrosoftExtensionsAIVersion>
8-
<AspireVersion>9.1.0</AspireVersion>
9-
<AspireUnstablePackagesVersion>9.1.0-preview.1.25121.10</AspireUnstablePackagesVersion>
10-
<GrpcVersion>2.67.0</GrpcVersion>
5+
<AspnetVersion>9.0.4</AspnetVersion>
6+
<MicrosoftExtensionsVersion>9.0.4</MicrosoftExtensionsVersion>
7+
<MicrosoftExtensionsAIVersion>9.4.0-preview.1.25207.5</MicrosoftExtensionsAIVersion>
8+
<AspireVersion>9.2.0</AspireVersion>
9+
<AspireUnstablePackagesVersion>9.2.0-preview.1.25209.2</AspireUnstablePackagesVersion>
10+
<GrpcVersion>2.70.0</GrpcVersion>
1111
<DuendeVersion>7.1.1</DuendeVersion>
1212
<ApiVersioningVersion>8.1.0</ApiVersioningVersion>
1313
</PropertyGroup>
1414
<ItemGroup>
1515
<!-- Version together with Aspire -->
1616
<PackageVersion Include="Aspire.Hosting.AppHost" Version="$(AspireVersion)" />
17+
<PackageVersion Include="Aspire.Hosting.Docker" Version="$(AspireUnstablePackagesVersion)" />
1718
<PackageVersion Include="Aspire.Hosting.Azure.CognitiveServices" Version="$(AspireVersion)" />
1819
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="$(AspireVersion)" />
1920
<PackageVersion Include="Aspire.Hosting.RabbitMQ" Version="$(AspireVersion)" />
@@ -38,20 +39,20 @@
3839
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="$(AspnetVersion)" />
3940
<PackageVersion Include="Microsoft.AspNetCore.Components.QuickGrid" Version="$(AspnetVersion)" />
4041
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="$(AspnetVersion)" />
41-
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.2" />
42+
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="$(AspnetVersion)" />
4243
<PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="$(AspnetVersion)" />
4344
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(AspnetVersion)" />
4445
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="$(AspnetVersion)" />
4546
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="$(AspnetVersion)" />
4647

4748
<PackageVersion Include="Microsoft.Extensions.Identity.Stores" Version="$(AspnetVersion)" />
48-
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="9.2.0" />
49+
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="9.4.0" />
4950

5051
<PackageVersion Include="MSTest.TestFramework" Version="3.8.2" />
5152
<PackageVersion Include="MSTest.TestAdapter" Version="3.8.2" />
5253
<!-- Version together with EF -->
5354
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
54-
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.2" />
55+
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.4" />
5556
<PackageVersion Include="NSubstitute" Version="5.3.0" />
5657
<PackageVersion Include="NSubstitute.Analyzers.CSharp" Version="1.0.17" />
5758
<PackageVersion Include="Pgvector" Version="0.3.0" />
@@ -67,8 +68,8 @@
6768
<PackageVersion Include="Microsoft.Extensions.AI.Abstractions" Version="$(MicrosoftExtensionsAIVersion)" />
6869
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="$(MicrosoftExtensionsAIVersion)" />
6970
<PackageVersion Include="Microsoft.Extensions.AI.Ollama" Version="$(MicrosoftExtensionsAIVersion)" />
70-
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.Ollama" Version="9.2.1" />
71-
<PackageVersion Include="CommunityToolkit.Aspire.OllamaSharp" Version="9.2.0-preview.1.250226-0510" />
71+
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.Ollama" Version="9.3.0" />
72+
<PackageVersion Include="CommunityToolkit.Aspire.OllamaSharp" Version="9.3.1-beta.259" />
7273
<!-- Open Telemetry -->
7374
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.11.2" />
7475
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.11.2" />
@@ -89,12 +90,12 @@
8990
<!-- Grpc -->
9091
<PackageVersion Include="Grpc.AspNetCore" Version="$(GrpcVersion)" />
9192
<PackageVersion Include="Grpc.Net.ClientFactory" Version="$(GrpcVersion)" />
92-
<PackageVersion Include="Grpc.Tools" Version="2.70.0" PrivateAssets="All" />
93+
<PackageVersion Include="Grpc.Tools" Version="2.71.0" PrivateAssets="All" />
9394
<!-- Miscellaneous -->
9495
<PackageVersion Include="Automapper" Version="14.0.0" />
9596
<PackageVersion Include="Dapper" Version="2.1.35" />
9697
<PackageVersion Include="FluentValidation.AspNetCore" Version="11.3.0" />
97-
<PackageVersion Include="Google.Protobuf" Version="3.30.0" />
98+
<PackageVersion Include="Google.Protobuf" Version="3.30.1" />
9899
<PackageVersion Include="MediatR" Version="12.4.1" />
99100
<PackageVersion Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
100101
<PackageVersion Include="Polly.Core" Version="8.5.2" />

src/Catalog.API/Extensions/Extensions.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,10 @@ public static void AddApplicationServices(this IHostApplicationBuilder builder)
4343
builder.AddOllamaApiClient("embedding")
4444
.AddEmbeddingGenerator();
4545
}
46-
else if (!string.IsNullOrWhiteSpace(builder.Configuration.GetConnectionString("openai")))
46+
else if (!string.IsNullOrWhiteSpace(builder.Configuration.GetConnectionString("textEmbeddingModel")))
4747
{
48-
builder.AddOpenAIClientFromConfiguration("openai");
49-
builder.Services.AddEmbeddingGenerator(sp => sp.GetRequiredService<OpenAIClient>().AsEmbeddingGenerator(builder.Configuration["AI:OpenAI:EmbeddingModel"]!))
50-
.UseOpenTelemetry()
51-
.UseLogging();
48+
builder.AddOpenAIClientFromConfiguration("textEmbeddingModel")
49+
.AddEmbeddingGenerator();
5250
}
5351

5452
builder.Services.AddScoped<ICatalogAI, CatalogAI>();

src/Catalog.API/appsettings.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,5 @@
2323
},
2424
"CatalogOptions": {
2525
"UseCustomizationData": false
26-
},
27-
"AI": {
28-
"OpenAI": {
29-
"EmbeddingModel": "text-embedding-3-small"
30-
}
3126
}
3227
}

src/Identity.API/libman.json

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,16 @@
77
"destination": "wwwroot/lib/jquery/"
88
},
99
{
10-
"provider": "unpkg",
1110
"library": "bootstrap@5.2.3",
11+
"destination": "wwwroot/lib/bootstrap/",
1212
"files": [
13-
"dist/css/bootstrap.css",
14-
"dist/css/bootstrap.css.map",
15-
"dist/css/bootstrap.min.css",
16-
"dist/css/bootstrap.min.css.map",
17-
"dist/js/bootstrap.js",
18-
"dist/js/bootstrap.min.js"
19-
],
20-
"destination": "wwwroot/lib/bootstrap/"
13+
"css/bootstrap.css",
14+
"css/bootstrap.css.map",
15+
"css/bootstrap.min.css",
16+
"css/bootstrap.min.css.map",
17+
"js/bootstrap.bundle.js",
18+
"js/bootstrap.bundle.min.js"
19+
]
2120
},
2221
{
2322
"library": "jquery-validation-unobtrusive@4.0.0",

src/WebApp/AIOptions.cs

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/WebApp/Components/Chatbot/ChatState.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public ChatState(
3232

3333
if (_logger.IsEnabled(LogLevel.Debug))
3434
{
35-
_logger.LogDebug("ChatModel: {model}", chatClient.GetService<ChatClientMetadata>()?.ModelId);
35+
_logger.LogDebug("ChatModel: {model}", chatClient.GetService<ChatClientMetadata>()?.DefaultModelId);
3636
}
3737

3838
_chatClient = chatClient;

src/WebApp/Extensions/Extensions.cs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,24 +96,19 @@ public static void AddAuthenticationServices(this IHostApplicationBuilder builde
9696

9797
private static void AddAIServices(this IHostApplicationBuilder builder)
9898
{
99+
ChatClientBuilder? chatClientBuilder = null;
99100
if (builder.Configuration["OllamaEnabled"] is string ollamaEnabled && bool.Parse(ollamaEnabled))
100101
{
101-
builder.AddOllamaApiClient("chat")
102-
.AddChatClient()
103-
.UseFunctionInvocation();
102+
chatClientBuilder = builder.AddOllamaApiClient("chat")
103+
.AddChatClient();
104104
}
105-
else
105+
else if (!string.IsNullOrWhiteSpace(builder.Configuration.GetConnectionString("chatModel")))
106106
{
107-
var chatModel = builder.Configuration.GetSection("AI").Get<AIOptions>()?.OpenAI?.ChatModel;
108-
if (!string.IsNullOrWhiteSpace(builder.Configuration.GetConnectionString("openai")) && !string.IsNullOrWhiteSpace(chatModel))
109-
{
110-
builder.AddOpenAIClientFromConfiguration("openai");
111-
builder.Services.AddChatClient(sp => sp.GetRequiredService<OpenAIClient>().AsChatClient(chatModel ?? "gpt-4o-mini"))
112-
.UseFunctionInvocation()
113-
.UseOpenTelemetry(configure: t => t.EnableSensitiveData = true)
114-
.UseLogging();
115-
}
107+
chatClientBuilder = builder.AddOpenAIClientFromConfiguration("chatModel")
108+
.AddChatClient();
116109
}
110+
111+
chatClientBuilder?.UseFunctionInvocation();
117112
}
118113

119114
public static async Task<string?> GetBuyerIdAsync(this AuthenticationStateProvider authenticationStateProvider)

src/WebApp/appsettings.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,5 @@
99
"EventBus": {
1010
"SubscriptionClientName": "Ordering.webapp"
1111
},
12-
"SessionCookieLifetimeMinutes": 60,
13-
"AI": {
14-
"OpenAI": {
15-
//"ChatModel": ""
16-
}
17-
}
12+
"SessionCookieLifetimeMinutes": 60
1813
}

src/eShop.AppHost/Extensions.cs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ public static IDistributedApplicationBuilder AddOpenAI(this IDistributedApplicat
3838
IResourceBuilder<ProjectResource> webApp)
3939
{
4040
const string openAIName = "openai";
41+
42+
const string textEmbeddingName = "textEmbeddingModel";
4143
const string textEmbeddingModelName = "text-embedding-3-small";
44+
45+
const string chatName = "chatModel";
4246
const string chatModelName = "gpt-4o-mini";
4347

4448
// to use an existing OpenAI resource as a connection string, add the following to the AppHost user secrets:
@@ -47,10 +51,12 @@ public static IDistributedApplicationBuilder AddOpenAI(this IDistributedApplicat
4751
// -or-
4852
// "openai": "Endpoint=https://<name>.openai.azure.com/" (to use Azure OpenAI)
4953
// }
50-
IResourceBuilder<IResourceWithConnectionString> openAI;
51-
if (builder.Configuration.GetConnectionString(openAIName) is not null)
54+
if (builder.Configuration.GetConnectionString(openAIName) is string openAIConnectionString)
5255
{
53-
openAI = builder.AddConnectionString(openAIName);
56+
catalogApi.WithReference(
57+
builder.AddConnectionString(textEmbeddingName, ReferenceExpression.Create($"{openAIConnectionString};Deployment={textEmbeddingModelName}")));
58+
webApp.WithReference(
59+
builder.AddConnectionString(chatName, ReferenceExpression.Create($"{openAIConnectionString};Deployment={chatModelName}")));
5460
}
5561
else
5662
{
@@ -61,7 +67,7 @@ public static IDistributedApplicationBuilder AddOpenAI(this IDistributedApplicat
6167
// "Location": "<location>"
6268
// }
6369

64-
var openAITyped = builder.AddAzureOpenAI(openAIName);
70+
var openAI = builder.AddAzureOpenAI(openAIName);
6571

6672
// to use an existing Azure OpenAI resource via provisioning, add the following to the AppHost user secrets:
6773
// "Parameters": {
@@ -73,26 +79,27 @@ public static IDistributedApplicationBuilder AddOpenAI(this IDistributedApplicat
7379
if (builder.Configuration["Parameters:openaiName"] is not null &&
7480
builder.Configuration["Parameters:openaiResourceGroup"] is not null)
7581
{
76-
openAITyped.AsExisting(
82+
openAI.AsExisting(
7783
builder.AddParameter("openaiName"),
7884
builder.AddParameter("openaiResourceGroup"));
7985
}
8086

81-
openAITyped
82-
.AddDeployment(new AzureOpenAIDeployment(chatModelName, "gpt-4o-mini", "2024-07-18"))
83-
.AddDeployment(new AzureOpenAIDeployment(textEmbeddingModelName, "text-embedding-3-small", "1", skuCapacity: 20)); // 20k tokens per minute are needed to seed the initial embeddings
87+
var chat = openAI.AddDeployment(chatName, chatModelName, "2024-07-18")
88+
.WithProperties(d =>
89+
{
90+
d.DeploymentName = chatModelName;
91+
});
92+
var textEmbedding = openAI.AddDeployment(textEmbeddingName, textEmbeddingModelName, "1")
93+
.WithProperties(d =>
94+
{
95+
d.DeploymentName = textEmbeddingModelName;
96+
d.SkuCapacity = 20; // 20k tokens per minute are needed to seed the initial embeddings
97+
});
8498

85-
openAI = openAITyped;
99+
catalogApi.WithReference(textEmbedding);
100+
webApp.WithReference(chat);
86101
}
87102

88-
catalogApi
89-
.WithReference(openAI)
90-
.WithEnvironment("AI__OPENAI__EMBEDDINGMODEL", textEmbeddingModelName);
91-
92-
webApp
93-
.WithReference(openAI)
94-
.WithEnvironment("AI__OPENAI__CHATMODEL", chatModelName);
95-
96103
return builder;
97104
}
98105

src/eShop.AppHost/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@
9999
.WithEnvironment("WebhooksWebClient", webhooksClient.GetEndpoint(launchProfileName))
100100
.WithEnvironment("WebAppClient", webApp.GetEndpoint(launchProfileName));
101101

102+
// Starting in Aspire 9.2, we can use the new DockerComposePublisher to generate a docker-compose file.
103+
// In order to do so, run 'dotnet run --publisher docker-compose --output-path ./docker-compose' to try it out.
104+
builder.AddDockerComposePublisher();
105+
102106
builder.Build().Run();
103107

104108
// For test use only.

0 commit comments

Comments
 (0)