Skip to content

Commit 4a3a1da

Browse files
timheuereerhardt
andauthored
Adds Milvus to the Aspire hosting/component packages (dotnet#4179)
Adding an Aspire Component and Hosting support for working with a Milvus vector database. https://milvus.io/ Does not contain support for Tracing or Metrics, yet. * WIP: Adding Milvus * PR feedback: - Added health check - Added example in doc comments - Modified tests to use testcontainer - Added WithDataBindMount * Fix apikey param, add HC to progress MD * Added EndToEnd integration test * Added database resource model * Updating logo and logo use rights * PR feedback - simplify playground * Attu moved to major.minor container tagging Fix dotnet#796 --------- Co-authored-by: Eric Erhardt <[email protected]>
1 parent 51ff4e3 commit 4a3a1da

File tree

54 files changed

+1878
-7
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1878
-7
lines changed

Aspire.sln

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
Microsoft Visual Studio Solution File, Format Version 12.00
32
# Visual Studio Version 17
43
VisualStudioVersion = 17.0.31903.59
@@ -464,6 +463,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Consumer", "playground\kafk
464463
EndProject
465464
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Producer", "playground\kafka\Producer\Producer.csproj", "{FEE2F9B0-F32D-41B3-8917-0C13DE4F5953}"
466465
EndProject
466+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "milvus", "milvus", "{BD2CD8FB-18EC-4930-8228-C49D89622022}"
467+
EndProject
468+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MilvusPlayground.AppHost", "playground\milvus\MilvusPlayground.AppHost\MilvusPlayground.AppHost.csproj", "{CE3B7E15-2319-45CD-9CED-0017E306DE9A}"
469+
EndProject
470+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MilvusPlayground.ApiService", "playground\milvus\MilvusPlayground.ApiService\MilvusPlayground.ApiService.csproj", "{13219E70-5647-4B71-95DC-2C8AFA2A4C5D}"
471+
EndProject
472+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Milvus", "src\Aspire.Hosting.Milvus\Aspire.Hosting.Milvus.csproj", "{1A3A4865-69F2-4251-9A95-2D57C6A46870}"
473+
EndProject
474+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Milvus.Client", "src\Components\Aspire.Milvus.Client\Aspire.Milvus.Client.csproj", "{1BFE3C02-3B81-4596-99A2-4DCDD9129C9A}"
475+
EndProject
476+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Milvus.Client.Tests", "tests\Aspire.Milvus.Client.Tests\Aspire.Milvus.Client.Tests.csproj", "{9FAE1602-2C69-4D24-8655-A164489441E8}"
477+
EndProject
467478
Global
468479
GlobalSection(SolutionConfigurationPlatforms) = preSolution
469480
Debug|Any CPU = Debug|Any CPU
@@ -1218,6 +1229,26 @@ Global
12181229
{FEE2F9B0-F32D-41B3-8917-0C13DE4F5953}.Debug|Any CPU.Build.0 = Debug|Any CPU
12191230
{FEE2F9B0-F32D-41B3-8917-0C13DE4F5953}.Release|Any CPU.ActiveCfg = Release|Any CPU
12201231
{FEE2F9B0-F32D-41B3-8917-0C13DE4F5953}.Release|Any CPU.Build.0 = Release|Any CPU
1232+
{CE3B7E15-2319-45CD-9CED-0017E306DE9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1233+
{CE3B7E15-2319-45CD-9CED-0017E306DE9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
1234+
{CE3B7E15-2319-45CD-9CED-0017E306DE9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
1235+
{CE3B7E15-2319-45CD-9CED-0017E306DE9A}.Release|Any CPU.Build.0 = Release|Any CPU
1236+
{13219E70-5647-4B71-95DC-2C8AFA2A4C5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1237+
{13219E70-5647-4B71-95DC-2C8AFA2A4C5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
1238+
{13219E70-5647-4B71-95DC-2C8AFA2A4C5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
1239+
{13219E70-5647-4B71-95DC-2C8AFA2A4C5D}.Release|Any CPU.Build.0 = Release|Any CPU
1240+
{1A3A4865-69F2-4251-9A95-2D57C6A46870}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1241+
{1A3A4865-69F2-4251-9A95-2D57C6A46870}.Debug|Any CPU.Build.0 = Debug|Any CPU
1242+
{1A3A4865-69F2-4251-9A95-2D57C6A46870}.Release|Any CPU.ActiveCfg = Release|Any CPU
1243+
{1A3A4865-69F2-4251-9A95-2D57C6A46870}.Release|Any CPU.Build.0 = Release|Any CPU
1244+
{1BFE3C02-3B81-4596-99A2-4DCDD9129C9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1245+
{1BFE3C02-3B81-4596-99A2-4DCDD9129C9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
1246+
{1BFE3C02-3B81-4596-99A2-4DCDD9129C9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
1247+
{1BFE3C02-3B81-4596-99A2-4DCDD9129C9A}.Release|Any CPU.Build.0 = Release|Any CPU
1248+
{9FAE1602-2C69-4D24-8655-A164489441E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1249+
{9FAE1602-2C69-4D24-8655-A164489441E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
1250+
{9FAE1602-2C69-4D24-8655-A164489441E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
1251+
{9FAE1602-2C69-4D24-8655-A164489441E8}.Release|Any CPU.Build.0 = Release|Any CPU
12211252
EndGlobalSection
12221253
GlobalSection(SolutionProperties) = preSolution
12231254
HideSolutionNode = FALSE
@@ -1439,6 +1470,12 @@ Global
14391470
{A39389A0-E780-4B97-808B-DC95CF59B35C} = {920BB263-E68F-4FA2-93FC-2E385EEA405B}
14401471
{7AA4C56C-3BB2-4FF0-BB03-F3F0D6A4FDAB} = {920BB263-E68F-4FA2-93FC-2E385EEA405B}
14411472
{FEE2F9B0-F32D-41B3-8917-0C13DE4F5953} = {920BB263-E68F-4FA2-93FC-2E385EEA405B}
1473+
{BD2CD8FB-18EC-4930-8228-C49D89622022} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0}
1474+
{CE3B7E15-2319-45CD-9CED-0017E306DE9A} = {BD2CD8FB-18EC-4930-8228-C49D89622022}
1475+
{13219E70-5647-4B71-95DC-2C8AFA2A4C5D} = {BD2CD8FB-18EC-4930-8228-C49D89622022}
1476+
{1A3A4865-69F2-4251-9A95-2D57C6A46870} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47}
1477+
{1BFE3C02-3B81-4596-99A2-4DCDD9129C9A} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2}
1478+
{9FAE1602-2C69-4D24-8655-A164489441E8} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
14421479
EndGlobalSection
14431480
GlobalSection(ExtensibilityGlobals) = postSolution
14441481
SolutionGuid = {6DCEDFEC-988E-4CB3-B45B-191EB5086E0C}

Directory.Packages.props

+3
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.2.0" />
102102
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components" Version="4.7.2" />
103103
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Icons" Version="4.7.2" />
104+
<PackageVersion Include="Milvus.Client" Version="2.3.0-preview.1"/>
104105
<PackageVersion Include="MongoDB.Driver" Version="2.25.0" />
105106
<PackageVersion Include="MongoDB.Driver.Core.Extensions.DiagnosticSources" Version="1.4.0" />
106107
<PackageVersion Include="MySqlConnector.DependencyInjection" Version="2.3.6" />
@@ -150,6 +151,8 @@
150151
<PackageVersion Include="Testcontainers.RabbitMq" Version="$(TestcontainersPackageVersion)" />
151152
<PackageVersion Include="Testcontainers.Redis" Version="$(TestcontainersPackageVersion)" />
152153
<PackageVersion Include="Testcontainers.Nats" Version="$(TestcontainersPackageVersion)" />
154+
<PackageVersion Include="Testcontainers.Milvus" Version="$(TestcontainersPackageVersion)" />
155+
153156
<!-- playground apps dependencies -->
154157
<PackageVersion Include="Dapr.AspNetCore" Version="1.13.1" />
155158
<PackageVersion Include="Microsoft.Orleans.Clustering.AzureStorage" Version="8.1.0" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<NoWarn>$(NoWarn);CS8002</NoWarn> <!-- Milvus.Client packages are not signed -->
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\..\..\src\Components\Aspire.Milvus.Client\Aspire.Milvus.Client.csproj" />
12+
<ProjectReference Include="..\..\Playground.ServiceDefaults\Playground.ServiceDefaults.csproj" />
13+
</ItemGroup>
14+
15+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
using Milvus.Client;
2+
3+
var builder = WebApplication.CreateBuilder(args);
4+
5+
// Add service defaults & Aspire components.
6+
builder.AddServiceDefaults();
7+
8+
builder.AddMilvusClient("milvus");
9+
10+
// Add services to the container.
11+
builder.Services.AddProblemDetails();
12+
13+
var app = builder.Build();
14+
15+
// Configure the HTTP request pipeline.
16+
app.UseExceptionHandler();
17+
18+
app.MapDefaultEndpoints();
19+
20+
app.MapGet("/create", async (MilvusClient milvusClient, ILogger<Program> logger) =>
21+
{
22+
string collectionName = "book";
23+
MilvusCollection collection = milvusClient.GetCollection(collectionName);
24+
25+
//Check if this collection exists
26+
var hasCollection = await milvusClient.HasCollectionAsync(collectionName);
27+
28+
if (hasCollection)
29+
{
30+
await collection.DropAsync();
31+
Console.WriteLine("Drop collection {0}", collectionName);
32+
}
33+
34+
collection = await milvusClient.CreateCollectionAsync(
35+
collectionName,
36+
new[] {
37+
FieldSchema.Create<long>("book_id", isPrimaryKey:true),
38+
FieldSchema.Create<long>("word_count"),
39+
FieldSchema.CreateVarchar("book_name", 256),
40+
FieldSchema.CreateFloatVector("book_intro", 2)
41+
}
42+
);
43+
logger.LogInformation("Collection created: book");
44+
45+
Random ran = new();
46+
List<long> bookIds = new();
47+
List<long> wordCounts = new();
48+
List<ReadOnlyMemory<float>> bookIntros = new();
49+
List<string> bookNames = new();
50+
for (long i = 0L; i < 2000; ++i)
51+
{
52+
bookIds.Add(i);
53+
wordCounts.Add(i + 10000);
54+
bookNames.Add($"Book Name {i}");
55+
56+
float[] vector = new float[2];
57+
for (int k = 0; k < 2; ++k)
58+
{
59+
vector[k] = ran.Next();
60+
}
61+
bookIntros.Add(vector);
62+
}
63+
64+
MutationResult result = await collection.InsertAsync(
65+
new FieldData[]
66+
{
67+
FieldData.Create("book_id", bookIds),
68+
FieldData.Create("word_count", wordCounts),
69+
FieldData.Create("book_name", bookNames),
70+
FieldData.CreateFloatVector("book_intro", bookIntros),
71+
});
72+
73+
logger.LogInformation("Added vectors");
74+
75+
// Check result
76+
logger.LogInformation("Insert status: {0},", result.ToString());
77+
78+
// Create index
79+
await collection.CreateIndexAsync(
80+
"book_intro",
81+
//MilvusIndexType.IVF_FLAT,//Use MilvusIndexType.IVF_FLAT.
82+
IndexType.AutoIndex,//Use MilvusIndexType.AUTOINDEX when you are using zilliz cloud.
83+
SimilarityMetricType.L2);
84+
85+
// Check index status
86+
IList<MilvusIndexInfo> indexInfos = await collection.DescribeIndexAsync("book_intro");
87+
88+
foreach (var info in indexInfos)
89+
{
90+
logger.LogInformation("FieldName:{0}, IndexName:{1}, IndexId:{2}", info.FieldName, info.IndexName, info.IndexId);
91+
}
92+
93+
logger.LogInformation("Index created");
94+
95+
// Then load it
96+
await collection.LoadAsync();
97+
98+
logger.LogInformation("Collection loaded");
99+
100+
return Results.Ok("Collection created");
101+
});
102+
103+
app.MapGet("/search", async (MilvusClient milvusClient, ILogger<Program> logger) =>
104+
{
105+
MilvusCollection collection = milvusClient.GetCollection("book");
106+
107+
// Query
108+
string expr = "book_id in [2,4,6,8]";
109+
110+
QueryParameters queryParameters = new();
111+
queryParameters.OutputFields.Add("book_id");
112+
queryParameters.OutputFields.Add("book_name");
113+
queryParameters.OutputFields.Add("word_count");
114+
115+
IReadOnlyList<FieldData> queryResult = await collection.QueryAsync(
116+
expr,
117+
queryParameters);
118+
119+
return queryResult[2];
120+
});
121+
122+
app.Run();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"http": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": true,
8+
"launchUrl": "",
9+
"applicationUrl": "http://localhost:5456",
10+
"environmentVariables": {
11+
"ASPNETCORE_ENVIRONMENT": "Development"
12+
}
13+
},
14+
"https": {
15+
"commandName": "Project",
16+
"dotnetRunMessages": true,
17+
"launchBrowser": true,
18+
"launchUrl": "",
19+
"applicationUrl": "https://localhost:7587;http://localhost:5456",
20+
"environmentVariables": {
21+
"ASPNETCORE_ENVIRONMENT": "Development"
22+
}
23+
}
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# For more info on HTTP files go to https://aka.ms/vs/httpfile
2+
@hostname = https://localhost:7587
3+
4+
# create the collection
5+
GET {{hostname}}/create
6+
7+
###
8+
9+
# search
10+
GET {{hostname}}/search
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning",
6+
"Milvus.Client": "Debug"
7+
}
8+
},
9+
"AllowedHosts": "*"
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Project>
2+
3+
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
4+
5+
<!-- NOTE: This line is only required because we are using P2P references, not NuGet. It will not exist in real apps. -->
6+
<Import Project="../../../src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.props" />
7+
8+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project>
2+
3+
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))" />
4+
5+
<!-- NOTE: These lines are only required because we are using P2P references, not NuGet. They will not exist in real apps. -->
6+
<Import Project="..\..\..\src\Aspire.Hosting.AppHost\build\Aspire.Hosting.AppHost.targets" />
7+
<Import Project="..\..\..\src\Aspire.Hosting.Sdk\SDK\Sdk.targets" />
8+
9+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<IsAspireHost>true</IsAspireHost>
9+
<UserSecretsId>232af89f-d4b7-4fc2-b60a-3dfbe06c11ef</UserSecretsId>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<Compile Include="$(SharedDir)KnownResourceNames.cs" Link="KnownResourceNames.cs" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\..\..\src\Aspire.Dashboard\Aspire.Dashboard.csproj" />
18+
<ProjectReference Include="..\..\..\src\Aspire.Hosting.AppHost\Aspire.Hosting.AppHost.csproj" IsAspireProjectResource="False" />
19+
<ProjectReference Include="..\..\..\src\Aspire.Hosting.Milvus\Aspire.Hosting.Milvus.csproj" IsAspireProjectResource="False" />
20+
<ProjectReference Include="..\MilvusPlayground.ApiService\MilvusPlayground.ApiService.csproj" />
21+
</ItemGroup>
22+
23+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
var builder = DistributedApplication.CreateBuilder(args);
2+
3+
var token = builder.AddParameter("milvusauth", true);
4+
5+
var milvusdb = builder.AddMilvus("milvus", token)
6+
.WithDataVolume("milvus-data")
7+
.WithAttu();
8+
9+
builder.AddProject<Projects.MilvusPlayground_ApiService>("apiservice")
10+
.WithReference(milvusdb);
11+
12+
builder.Build().Run();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"https": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": true,
8+
"applicationUrl": "https://localhost:17115;http://localhost:15293",
9+
"environmentVariables": {
10+
"ASPNETCORE_ENVIRONMENT": "Development",
11+
"DOTNET_ENVIRONMENT": "Development",
12+
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21286",
13+
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22004"
14+
}
15+
},
16+
"http": {
17+
"commandName": "Project",
18+
"dotnetRunMessages": true,
19+
"launchBrowser": true,
20+
"applicationUrl": "http://localhost:15293",
21+
"environmentVariables": {
22+
"ASPNETCORE_ENVIRONMENT": "Development",
23+
"DOTNET_ENVIRONMENT": "Development",
24+
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19152",
25+
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20158"
26+
}
27+
},
28+
"generate-manifest": {
29+
"commandName": "Project",
30+
"launchBrowser": true,
31+
"dotnetRunMessages": true,
32+
"commandLineArgs": "--publisher manifest --output-path aspire-manifest.json",
33+
"applicationUrl": "http://localhost:15293",
34+
"environmentVariables": {
35+
"ASPNETCORE_ENVIRONMENT": "Development",
36+
"DOTNET_ENVIRONMENT": "Development",
37+
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19152"
38+
}
39+
}
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning",
6+
"Aspire.Hosting.Dcp": "Warning"
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)