Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dapr component schema #460

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
<PackageVersion Include="RavenDB.Client" Version="6.2.1" />
<PackageVersion Include="RavenDB.TestDriver" Version="6.2.1" />
<PackageVersion Include="AspNetCore.HealthChecks.RavenDB" Version="9.0.0" />
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
<!-- Build dependencies -->
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
<!-- Testcontainers packages -->
Expand Down
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this file still? I don't see the reference of it in the sample

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file is used by this line of the apphost

var pubSub = builder.AddDaprPubSub("pubsub")

this is not new - it's simply in a project relative location

Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ spec:
- name: username
value: guest
- name: password
value: guest
value: guest
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
<UserSecretsId>e7f9178b-87a6-4047-b90a-a1fa9d8137b9</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<None Include=".dapr\components\pubsub.yaml" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" />
<PackageReference Include="Aspire.Hosting.RabbitMQ" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@
.WithEndpoint("tcp", e => e.Port = 5672)
.WithEndpoint("management", e => e.Port = 15672);


var stateStore = builder.AddDaprStateStore("statestore");

var pubSub = builder.AddDaprPubSub("pubsub")
.WithMetadata("password", rmq.Resource.PasswordParameter)
.WaitFor(rmq);

builder.AddProject<Projects.CommunityToolkit_Aspire_Hosting_Dapr_ServiceA>("servicea")
.WithDaprSidecar()
.WithReference(stateStore)
.WithReference(pubSub);
.WithReference(pubSub)
.WithDaprSidecar()
.WaitFor(rmq);

builder.AddProject<Projects.CommunityToolkit_Aspire_Hosting_Dapr_ServiceB>("serviceb")
.WithReference(pubSub)
.WithDaprSidecar()
Comment on lines +19 to 20
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a developer standpoint I would more expect something like:

.WithDaprSidecar()
  .WithReference(pubSub)

Because you configure the sidecare to use the pubSub reference as a pubsub. Not the project.
That would also mean that we would need to break with the Fluent API their or have some WithDaprSidecar parameter that accepts a action or so to configure the sidecar.

You can look for the AzurePostgreSql resource of aspire how you can configure the development contianer. I would prefer an API like their

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To prevent breaking changes for now closing this comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is up to the developer the both work the same

.WithReference(pubSub);
.WaitFor(rmq);

// console app with no appPort (sender only)
builder.AddProject<Projects.CommunityToolkit_Aspire_Hosting_Dapr_ServiceC>("servicec")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet("/secrets", (DaprClient client) =>
{
var secrets = client.GetBulkSecretAsync("secretstore");
return secrets;
});

app.MapGet("/weatherforecast", async (DaprClient client) =>
{
await client.PublishEventAsync("pubsub", "weather", new WeatherForecastMessage("Weather forecast requested!"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<AdditionalPackageTags>aspire integration hosting dapr</AdditionalPackageTags>
Expand All @@ -11,6 +11,7 @@

<ItemGroup>
<PackageReference Include="Aspire.Hosting" />
<PackageReference Include="YamlDotNet" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using Aspire.Hosting.ApplicationModel;

namespace CommunityToolkit.Aspire.Hosting.Dapr;
internal sealed record DaprComponentConfigurationAnnotation(Action<DaprComponentSchema> Configure) : IResourceAnnotation;
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,4 @@ namespace CommunityToolkit.Aspire.Hosting.Dapr;
/// Indicates that a Dapr component should be used with the sidecar for the associated resource.
/// </summary>
/// <param name="Component">The Dapr component to use.</param>
public sealed record DaprComponentReferenceAnnotation(IDaprComponentResource Component) : IResourceAnnotation
{
}
public sealed record DaprComponentReferenceAnnotation(IDaprComponentResource Component) : IResourceAnnotation;
138 changes: 138 additions & 0 deletions src/CommunityToolkit.Aspire.Hosting.Dapr/DaprComponentSchema.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace CommunityToolkit.Aspire.Hosting.Dapr;

internal interface IDaprComponentSpecMetadata : IList<DaprComponentSpecMetadata>;

internal class DaprComponentSchema
{
internal static readonly ISerializer serializer = BuildSerializer();
internal static readonly IDeserializer deserializer = BuildDeSerializer();

public string ApiVersion { get; init; } = "dapr.io/v1alpha1";
public string Kind { get; init; } = "Component";
public DaprComponentAuth? Auth { get; set; }
public DaprComponentMetadata Metadata { get; init; } = default!;
public DaprComponentSpec Spec { get; init; } = default!;

// Required for deserialization
public DaprComponentSchema() { }

public DaprComponentSchema(string name, string type)
{
Metadata = new DaprComponentMetadata { Name = name };
Spec = new DaprComponentSpec
{
Type = type,
Metadata = []
};
}
public override string ToString()
{
return serializer.Serialize(this);
}
public static implicit operator DaprComponentSchema(string yamlContent)
{
return deserializer.Deserialize<DaprComponentSchema>(yamlContent);
}
private static IDeserializer BuildDeSerializer()
{
DeserializerBuilder builder = new();
builder.WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithTypeDiscriminatingNodeDeserializer(static o =>
{
Dictionary<string, Type> keyMappings = new()
{
["value"] = typeof(DaprComponentSpecMetadataValue),
["secretKeyRef"] = typeof(DaprComponentSpecMetadataSecret)
};
o.AddUniqueKeyTypeDiscriminator<DaprComponentSpecMetadata>(keyMappings);
});
return builder.Build();
}

private static ISerializer BuildSerializer()
{
SerializerBuilder builder = new();
builder.WithNamingConvention(CamelCaseNamingConvention.Instance)
.ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitDefaults);
return builder.Build();
}

}
internal class DaprComponentMetadata
{
public required string Name { get; init; }
public string? Namespace { get; init; }

}

internal class DaprComponentAuth
{
public required string SecretStore { get; init; }
}

internal class GenericDaprComponentSpecMetadata : List<DaprComponentSpecMetadata>, IDaprComponentSpecMetadata;

internal class DaprComponentSpec : DaprComponentSpec<GenericDaprComponentSpecMetadata> { }

internal class DaprComponentSpec<TSpecMetadata> where TSpecMetadata : IDaprComponentSpecMetadata
{
public required string Type { get; init; }
public string Version { get; init; } = "v1";
public required TSpecMetadata Metadata { get; init; }
}

/// <summary>
/// Represents a Dapr component spec metadata item
/// </summary>
public abstract class DaprComponentSpecMetadata
{
/// <summary>
/// The name of the metadata item
/// </summary>
[YamlMember(Order = 1)]
public required string Name { get; init; }
}

/// <summary>
/// Represents a Dapr component spec metadata item with a value
/// </summary>
public sealed class DaprComponentSpecMetadataValue : DaprComponentSpecMetadata
{
/// <summary>
/// The value of the metadata item
/// </summary>
[YamlMember(Order = 2)]
public required string Value { get; set; }
}

/// <summary>
/// Represents a Dapr component spec metadata item with a secret key reference
/// </summary>
public sealed class DaprComponentSpecMetadataSecret : DaprComponentSpecMetadata
{
/// <summary>
/// The secret key reference of the metadata item
/// </summary>
[YamlMember(Order = 2)]
public required DaprSecretKeyRef SecretKeyRef { get; set; }

}

/// <summary>
/// Represents a Dapr secret key reference
/// </summary>
public sealed class DaprSecretKeyRef
{
/// <summary>
/// The name of the secret
/// </summary>
public required string Name { get; init; } = default!;
/// <summary>
/// The key of the secret
/// </summary>
public required string Key { get; init; } = default!;
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using Aspire.Hosting.ApplicationModel;

namespace CommunityToolkit.Aspire.Hosting.Dapr;
internal record DaprComponentSecretAnnotation(string Key, string Value) : IResourceAnnotation;
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ internal static class DaprConstants
public static class BuildingBlocks
{
public const string PubSub = "pubsub";

public const string StateStore = "state";
public const string SecretStore = "secretstore";
}
}
Loading
Loading