Skip to content

Commit

Permalink
Make port allocation global.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidfowl committed Mar 29, 2024
1 parent 36bb83b commit 0cb7808
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/Aspire.Hosting/Publishing/ManifestPublishingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public sealed class ManifestPublishingContext(DistributedApplicationExecutionCon
/// </summary>
public Utf8JsonWriter Writer { get; } = writer;

private PortAllocator PortAllocator { get; } = new();

/// <summary>
/// Gets cancellation token for this operation.
/// </summary>
Expand Down Expand Up @@ -268,8 +270,6 @@ public void WriteBindings(IResource resource)
{
if (resource.TryGetEndpoints(out var endpoints))
{
var allocator = new PortAllocator();

Writer.WriteStartObject("bindings");
foreach (var endpoint in endpoints)
{
Expand All @@ -288,7 +288,7 @@ public void WriteBindings(IResource resource)
(ProjectResource, var scheme, null) when scheme is "http" or "https" => null,

// Allocate a dynamic port
_ => allocator.AllocatePort()
_ => PortAllocator.AllocatePort()
};

int? exposedPort = (endpoint.UriScheme, endpoint.Port, targetPort) switch
Expand All @@ -308,18 +308,18 @@ public void WriteBindings(IResource resource)
("https", null, null) => null,

// Other schemes just allocate a port
_ => allocator.AllocatePort()
_ => PortAllocator.AllocatePort()
};

if (exposedPort is int ep)
{
allocator.AddUsedPort(ep);
PortAllocator.AddUsedPort(ep);
Writer.WriteNumber("port", ep);
}

if (targetPort is int tp)
{
allocator.AddUsedPort(tp);
PortAllocator.AddUsedPort(tp);
Writer.WriteNumber("targetPort", tp);
}

Expand Down
29 changes: 29 additions & 0 deletions tests/Aspire.Hosting.Tests/Utils/ManifestUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,35 @@ public static async Task<JsonNode> GetManifest(IResource resource)
return resourceNode;
}

public static async Task<JsonNode[]> GetManifests(IResource[] resources)
{
using var ms = new MemoryStream();
var writer = new Utf8JsonWriter(ms);
var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Publish);
var context = new ManifestPublishingContext(executionContext, Path.Combine(Environment.CurrentDirectory, "manifest.json"), writer);

var results = new List<JsonNode>();

foreach (var r in resources)
{
writer.WriteStartObject();
await context.WriteResourceAsync(r);
writer.WriteEndObject();
writer.Flush();
ms.Position = 0;
var obj = JsonNode.Parse(ms);
Assert.NotNull(obj);
var resourceNode = obj[r.Name];
Assert.NotNull(resourceNode);
results.Add(resourceNode);

ms.Position = 0;
writer.Reset(ms);
}

return [.. results];
}

public static async Task<(JsonNode ManifestNode, string BicepText)> GetManifestWithBicep(IResource resource)
{
var manifestNode = await GetManifest(resource);
Expand Down
47 changes: 47 additions & 0 deletions tests/Aspire.Hosting.Tests/WithEndpointTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,53 @@ public async Task VerifyManifestProjectWithHttpEndpointDoesNotAllocatePort()
Assert.Equal(expectedManifest, manifest.ToString());
}

[Fact]
public async Task VerifyManifestPortAllocationIsGlobal()
{
using var builder = TestDistributedApplicationBuilder.Create();
var container0 = builder.AddContainer("app0", "image")
.WithEndpoint(name: "custom");

var container1 = builder.AddContainer("app1", "image")
.WithEndpoint(name: "custom");

var manifests = await ManifestUtils.GetManifests([container0.Resource, container1.Resource]);
var expectedManifest0 =
"""
{
"type": "container.v0",
"image": "image:latest",
"bindings": {
"custom": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"targetPort": 8000
}
}
}
""";

var expectedManifest1 =
"""
{
"type": "container.v0",
"image": "image:latest",
"bindings": {
"custom": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"targetPort": 8001
}
}
}
""";

Assert.Equal(expectedManifest0, manifests[0].ToString());
Assert.Equal(expectedManifest1, manifests[1].ToString());
}

private static TestProgram CreateTestProgram(string[]? args = null) => TestProgram.Create<WithEndpointTests>(args);

sealed class TestProject : IProjectMetadata
Expand Down

0 comments on commit 0cb7808

Please sign in to comment.