Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
108 changes: 108 additions & 0 deletions Apollo.sln

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions src/Aspire.Hosting.Apollo/ApolloResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Aspire.Hosting.ApplicationModel;

namespace Aspire.Hosting;

/// <summary>
/// Represents an Apollo configuration resource.
/// </summary>
/// <param name="name">The name of the resource.</param>
/// <param name="appId">The Apollo application ID.</param>
/// <param name="metaServer">The Apollo meta server URL.</param>
public class ApolloResource(string name, string? appId, string? metaServer) : Resource(name)
Copy link
Contributor

Choose a reason for hiding this comment

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

Many options are missing, see REAMDE.

Copy link
Author

Choose a reason for hiding this comment

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

Added all missing Apollo configuration options from the README. The implementation now supports:

  • Environment (Env), Cluster, DataCenter
  • Secret for authentication
  • ConfigServer for direct URLs
  • Timeout, RefreshInterval, LocalCacheDir
  • Meta for environment-specific servers
  • Label and Namespaces

All options are exposed through fluent API methods (WithEnvironment, WithCluster, WithSecret, etc.) and properly mapped to environment variables. See commit 83e88fc.

{
/// <summary>
/// Gets the Apollo application ID.
/// </summary>
public string? AppId { get; } = appId;

/// <summary>
/// Gets the Apollo meta server URL.
/// </summary>
public string? MetaServer { get; } = metaServer;
}
72 changes: 72 additions & 0 deletions src/Aspire.Hosting.Apollo/ApolloResourceBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Aspire.Hosting.ApplicationModel;

namespace Aspire.Hosting;

/// <summary>
/// Provides extension methods for adding Apollo configuration resources to an <see cref="IDistributedApplicationBuilder"/>.
/// </summary>
public static class ApolloResourceBuilderExtensions
{
/// <summary>
/// Adds an Apollo configuration server resource to the application.
/// </summary>
/// <param name="builder">The <see cref="IDistributedApplicationBuilder"/>.</param>
/// <param name="name">The name of the resource.</param>
/// <param name="appId">The Apollo application ID.</param>
/// <param name="metaServer">The Apollo meta server URL.</param>
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<ApolloResource> AddApollo(
this IDistributedApplicationBuilder builder,
string name,
string? appId = null,
string? metaServer = null)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentException.ThrowIfNullOrEmpty(name);

var resource = new ApolloResource(name, appId, metaServer);

return builder.AddResource(resource);
}

/// <summary>
/// Adds a binding to an Apollo configuration resource.
/// </summary>
/// <param name="builder">The resource builder.</param>
/// <param name="apollo">The Apollo resource builder to reference.</param>
/// <param name="appId">The Apollo application ID to bind to.</param>
/// <param name="metaServer">The Apollo meta server URL to bind to.</param>
/// <param name="namespaces">Optional list of namespaces to use.</param>
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<TDestination> WithReference<TDestination>(
this IResourceBuilder<TDestination> builder,
IResourceBuilder<ApolloResource> apollo,
string? appId = null,
string? metaServer = null,
string[]? namespaces = null)
where TDestination : IResourceWithEnvironment
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(apollo);

var actualAppId = appId ?? apollo.Resource.AppId;
var actualMetaServer = metaServer ?? apollo.Resource.MetaServer;

if (!string.IsNullOrEmpty(actualAppId))
{
builder.WithEnvironment("Apollo__AppId", actualAppId);
}

if (!string.IsNullOrEmpty(actualMetaServer))
{
builder.WithEnvironment("Apollo__MetaServer", actualMetaServer);
}

if (namespaces != null && namespaces.Length > 0)
{
builder.WithEnvironment("Apollo__Namespaces", string.Join(",", namespaces));
}

return builder;
}
}
22 changes: 22 additions & 0 deletions src/Aspire.Hosting.Apollo/Aspire.Hosting.Apollo.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<AssemblyName>Aspire.Com.Ctrip.Framework.Apollo.Configuration</AssemblyName>
<PackageReleaseNotes>发布日志请点击打开 https://github.com/apolloconfig/apollo.net/releases</PackageReleaseNotes>
<Description>Aspire hosting integration for Apollo Configuration Center

  Provides extension methods and resource definitions for a .NET Aspire AppHost to configure Apollo configuration resources.

$(PackageReleaseNotes)</Description>
<RootNamespace>Aspire.Hosting</RootNamespace>
<TargetFramework>net9.0</TargetFramework>
<Version>$(ApolloVersion).0</Version>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Apollo.Configuration\Apollo.Configuration.csproj" />

<PackageReference Include="Aspire.Hosting" Version="9.0.0" />
</ItemGroup>

</Project>
111 changes: 111 additions & 0 deletions src/Aspire.Hosting.Apollo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Aspire.Com.Ctrip.Framework.Apollo.Configuration

Provides extension methods and resource definitions for a .NET Aspire AppHost to configure Apollo Configuration Center resources.

## Getting Started

### Install the package

In your AppHost project, install the Aspire Apollo Hosting library with [NuGet](https://www.nuget.org):

```dotnetcli
dotnet add package Aspire.Com.Ctrip.Framework.Apollo.Configuration
```

## Usage Examples

### Basic Usage

In the _Program.cs_ file of your `AppHost` project, add an Apollo resource and consume it using the following methods:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var apollo = builder.AddApollo("apollo",
appId: "your-app-id",
metaServer: "http://localhost:8080");

var myService = builder.AddProject<Projects.MyService>("myservice")
.WithReference(apollo);

builder.Build().Run();
```

### Using Existing Apollo Server

If you have an existing Apollo configuration server running, you can reference it:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var apollo = builder.AddApollo("apollo",
appId: "SampleApp",
metaServer: "http://apollo-config-server:8080");

var myService = builder.AddProject<Projects.MyService>("myservice")
.WithReference(apollo,
appId: "SampleApp",
namespaces: new[] { "application", "database" });

builder.Build().Run();
```

### Custom Namespaces

You can specify custom Apollo namespaces:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var apollo = builder.AddApollo("apollo",
appId: "MyApp",
metaServer: "http://localhost:8080");

var myService = builder.AddProject<Projects.MyService>("myservice")
.WithReference(apollo,
namespaces: new[] { "application", "redis.config", "database.config" });

builder.Build().Run();
```

## Configuration in Service Projects

In your service projects, the Apollo configuration will be automatically available through environment variables:

- `Apollo__AppId`: The Apollo application ID
- `Apollo__MetaServer`: The Apollo meta server URL
- `Apollo__Namespaces`: Comma-separated list of namespaces (if specified)

These can be used with the existing Apollo.NET client libraries. The Apollo client will automatically read these environment variables, or you can explicitly configure it:

```csharp
var builder = WebApplication.CreateBuilder(args);

// Apollo configuration is automatically available from environment variables
// The AddApollo extension will read Apollo__AppId, Apollo__MetaServer, etc.
builder.Configuration.AddApollo(builder.Configuration.GetSection("Apollo"));

var app = builder.Build();
app.Run();
```

Alternatively, if you have additional configuration in appsettings.json, it will be merged with the environment variables (environment variables take precedence):

```json
{
"Apollo": {
"Cluster": "default",
"Secret": "your-secret-here"
}
}
```

## Additional Documentation

* [Apollo Configuration Center](https://github.com/apolloconfig/apollo)
* [Apollo.NET Client](https://github.com/apolloconfig/apollo.net)
* [.NET Aspire Documentation](https://learn.microsoft.com/dotnet/aspire/)

## Feedback & Contributing

https://github.com/apolloconfig/apollo.net
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;
using Xunit;

namespace Aspire.Hosting.Apollo.Tests;

public class ApolloResourceBuilderExtensionsTests
{
[Fact]
public void AddApollo_CreatesApolloResource()
{
// Arrange
var builder = DistributedApplication.CreateBuilder();

// Act
var apolloBuilder = builder.AddApollo("apollo", "testApp", "http://localhost:8080");

// Assert
Assert.NotNull(apolloBuilder);
Assert.NotNull(apolloBuilder.Resource);
Assert.IsType<ApolloResource>(apolloBuilder.Resource);
Assert.Equal("apollo", apolloBuilder.Resource.Name);
Assert.Equal("testApp", apolloBuilder.Resource.AppId);
Assert.Equal("http://localhost:8080", apolloBuilder.Resource.MetaServer);
}

[Fact]
public void AddApollo_WithNullBuilder_ThrowsArgumentNullException()
{
// Arrange
IDistributedApplicationBuilder builder = null!;

// Act & Assert
Assert.Throws<ArgumentNullException>(() => builder.AddApollo("apollo"));
}

[Fact]
public void AddApollo_WithEmptyName_ThrowsArgumentException()
{
// Arrange
var builder = DistributedApplication.CreateBuilder();

// Act & Assert
Assert.Throws<ArgumentException>(() => builder.AddApollo(""));
}

[Fact]
public void AddApollo_WithNullAppIdAndMetaServer_CreatesResource()
{
// Arrange
var builder = DistributedApplication.CreateBuilder();

// Act
var apolloBuilder = builder.AddApollo("apollo");

// Assert
Assert.NotNull(apolloBuilder);
Assert.NotNull(apolloBuilder.Resource);
Assert.Equal("apollo", apolloBuilder.Resource.Name);
Assert.Null(apolloBuilder.Resource.AppId);
Assert.Null(apolloBuilder.Resource.MetaServer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Aspire.Hosting.Apollo\Aspire.Hosting.Apollo.csproj" />
</ItemGroup>

</Project>