Skip to content

Commit aa2cea8

Browse files
Adding Resource to CommandLineArgsCallbackContext (#10864)
* Adding new property to CommandLineArgsCallbackContext that exposes the resource Fixes #10863 * Addressing the breaking change issue from code review * Enhance endpoint handling in container and executable tests with HTTP scheme and allocated endpoints --------- Co-authored-by: David Fowler <[email protected]>
1 parent 10baf9a commit aa2cea8

File tree

10 files changed

+73
-13
lines changed

10 files changed

+73
-13
lines changed

src/Aspire.Hosting.Azure.AppContainers/ContainerAppContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ private async Task ProcessArgumentsAsync(CancellationToken cancellationToken)
422422
{
423423
if (resource.TryGetAnnotationsOfType<CommandLineArgsCallbackAnnotation>(out var commandLineArgsCallbackAnnotations))
424424
{
425-
var context = new CommandLineArgsCallbackContext(Args, cancellationToken: cancellationToken)
425+
var context = new CommandLineArgsCallbackContext(Args, resource, cancellationToken: cancellationToken)
426426
{
427427
ExecutionContext = _containerAppEnvironmentContext.ExecutionContext,
428428
};

src/Aspire.Hosting.Azure.AppService/AzureAppServiceWebsiteContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private async Task ProcessArgumentsAsync(CancellationToken cancellationToken)
6262
{
6363
if (resource.TryGetAnnotationsOfType<CommandLineArgsCallbackAnnotation>(out var commandLineArgsCallbackAnnotations))
6464
{
65-
var context = new CommandLineArgsCallbackContext(Args, cancellationToken)
65+
var context = new CommandLineArgsCallbackContext(Args, resource, cancellationToken)
6666
{
6767
ExecutionContext = environmentContext.ExecutionContext
6868
};

src/Aspire.Hosting.Azure/AzureResourcePreparer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ private async Task<HashSet<IAzureResource>> GetAzureReferences(IResource resourc
380380

381381
if (resource.TryGetAnnotationsOfType<CommandLineArgsCallbackAnnotation>(out var commandLineArgsCallbackAnnotations))
382382
{
383-
var context = new CommandLineArgsCallbackContext([], cancellationToken: cancellationToken);
383+
var context = new CommandLineArgsCallbackContext([], resource, cancellationToken: cancellationToken);
384384

385385
foreach (var c in commandLineArgsCallbackAnnotations)
386386
{

src/Aspire.Hosting.Docker/DockerComposeEnvironmentContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private static async Task ProcessArgumentsAsync(DockerComposeServiceResource ser
144144
{
145145
if (serviceResource.TargetResource.TryGetAnnotationsOfType<CommandLineArgsCallbackAnnotation>(out var commandLineArgsCallbacks))
146146
{
147-
var context = new CommandLineArgsCallbackContext(serviceResource.Args, cancellationToken: cancellationToken)
147+
var context = new CommandLineArgsCallbackContext(serviceResource.Args, serviceResource.TargetResource, cancellationToken: cancellationToken)
148148
{
149149
ExecutionContext = executionContext
150150
};

src/Aspire.Hosting.Kubernetes/KubernetesResource.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ private async Task ProcessArgumentsAsync(KubernetesEnvironmentContext environmen
226226
{
227227
if (resource.TryGetAnnotationsOfType<CommandLineArgsCallbackAnnotation>(out var commandLineArgsCallbackAnnotations))
228228
{
229-
var context = new CommandLineArgsCallbackContext([], cancellationToken: cancellationToken);
229+
var context = new CommandLineArgsCallbackContext([], resource, cancellationToken: cancellationToken);
230230

231231
foreach (var c in commandLineArgsCallbackAnnotations)
232232
{

src/Aspire.Hosting/ApplicationModel/CommandLineArgsCallbackAnnotation.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ public CommandLineArgsCallbackAnnotation(Action<IList<object>> callback)
5050
/// <param name="cancellationToken"> The cancellation token associated with this execution.</param>
5151
public sealed class CommandLineArgsCallbackContext(IList<object> args, CancellationToken cancellationToken = default)
5252
{
53+
private readonly IResource? _resource;
54+
55+
/// <summary>
56+
/// Represents a callback context for the list of command-line arguments associated with an executable resource.
57+
/// </summary>
58+
/// <param name="args"> The list of command-line arguments.</param>
59+
/// <param name="resource"> The resource associated with this callback context.</param>
60+
/// <param name="cancellationToken"> The cancellation token associated with this execution.</param>
61+
public CommandLineArgsCallbackContext(IList<object> args, IResource? resource = null, CancellationToken cancellationToken = default)
62+
: this(args, cancellationToken) => _resource = resource;
63+
5364
/// <summary>
5465
/// Gets the list of command-line arguments.
5566
/// </summary>
@@ -69,4 +80,13 @@ public sealed class CommandLineArgsCallbackContext(IList<object> args, Cancellat
6980
/// Gets or sets the logger for the distributed application.
7081
/// </summary>
7182
public ILogger Logger { get; init; } = NullLogger.Instance;
83+
84+
/// <summary>
85+
/// The resource associated with this callback context.
86+
/// </summary>
87+
/// <remarks>
88+
/// This will be set to the resource in all cases where .NET Aspire invokes the callback.
89+
/// </remarks>
90+
/// <exception cref="InvalidOperationException">Thrown when the EnvironmentCallbackContext was created without a specified resource.</exception>
91+
public IResource Resource => _resource ?? throw new InvalidOperationException($"{nameof(Resource)} is not set. This callback context is not associated with a resource.");
7292
}

src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public static async ValueTask ProcessArgumentValuesAsync(
282282
if (resource.TryGetAnnotationsOfType<CommandLineArgsCallbackAnnotation>(out var callbacks))
283283
{
284284
var args = new List<object>();
285-
var context = new CommandLineArgsCallbackContext(args, cancellationToken)
285+
var context = new CommandLineArgsCallbackContext(args, resource, cancellationToken)
286286
{
287287
Logger = logger,
288288
ExecutionContext = executionContext

tests/Aspire.Hosting.Containers.Tests/ContainerResourceTests.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,17 @@ public async Task AddContainerWithArgs()
103103
});
104104

105105
var c2 = appBuilder.AddContainer("container", "none")
106+
.WithEndpoint("ep", e =>
107+
{
108+
e.UriScheme = "http";
109+
e.AllocatedEndpoint = new(e, "localhost", 5678, targetPortExpression: "5678");
110+
})
106111
.WithArgs(context =>
107112
{
108113
context.Args.Add("arg1");
109114
context.Args.Add(c1.GetEndpoint("ep"));
110115
context.Args.Add(testResource);
116+
context.Args.Add(((IResourceWithEndpoints)context.Resource).GetEndpoint("ep"));
111117
});
112118

113119
using var app = appBuilder.Build();
@@ -117,7 +123,8 @@ public async Task AddContainerWithArgs()
117123
Assert.Collection(args,
118124
arg => Assert.Equal("arg1", arg),
119125
arg => Assert.Equal("http://c1:1234", arg), // this is the container hostname
120-
arg => Assert.Equal("connectionString", arg));
126+
arg => Assert.Equal("connectionString", arg),
127+
arg => Assert.Equal("http://container:5678", arg));
121128

122129
// We don't yet process relationships set via the callbacks
123130
// so we don't see the testResource2 nor exe1
@@ -133,8 +140,17 @@ public async Task AddContainerWithArgs()
133140
"args": [
134141
"arg1",
135142
"{c1.bindings.ep.url}",
136-
"{test.connectionString}"
137-
]
143+
"{test.connectionString}",
144+
"{container.bindings.ep.url}"
145+
],
146+
"bindings": {
147+
"ep": {
148+
"scheme": "http",
149+
"protocol": "tcp",
150+
"transport": "http",
151+
"targetPort": 8000
152+
}
153+
}
138154
}
139155
""";
140156

tests/Aspire.Hosting.Tests/ExecutableResourceTests.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,18 @@ public async Task AddExecutableWithArgs()
2525
});
2626

2727
var exe2 = appBuilder.AddExecutable("e2", "python", ".", "app.py", exe1.GetEndpoint("ep"))
28+
.WithEndpoint("ep", e =>
29+
{
30+
e.UriScheme = "http";
31+
e.AllocatedEndpoint = new(e, "localhost", 5678);
32+
})
2833
.WithArgs("arg1", testResource)
2934
.WithArgs(context =>
3035
{
3136
context.Args.Add("arg2");
3237
context.Args.Add(exe1.GetEndpoint("ep"));
3338
context.Args.Add(testResource2);
39+
context.Args.Add(((IResourceWithEndpoints)context.Resource).GetEndpoint("ep"));
3440
});
3541

3642
using var app = appBuilder.Build();
@@ -44,7 +50,8 @@ public async Task AddExecutableWithArgs()
4450
arg => Assert.Equal("connectionString", arg),
4551
arg => Assert.Equal("arg2", arg),
4652
arg => Assert.Equal("http://localhost:1234", arg),
47-
arg => Assert.Equal("anotherConnectionString", arg)
53+
arg => Assert.Equal("anotherConnectionString", arg),
54+
arg => Assert.Equal("http://localhost:5678", arg)
4855
);
4956

5057
Assert.True(exe2.Resource.TryGetAnnotationsOfType<ResourceRelationshipAnnotation>(out var relationships));
@@ -58,6 +65,7 @@ public async Task AddExecutableWithArgs()
5865
});
5966

6067
var manifest = await ManifestUtils.GetManifest(exe2.Resource).DefaultTimeout();
68+
6169
// Note: resource working directory is <repo-root>\tests\Aspire.Hosting.Tests
6270
// Manifest directory is <repo-root>\artifacts\bin\Aspire.Hosting.Tests\Debug\net8.0
6371
var expectedManifest =
@@ -73,8 +81,17 @@ public async Task AddExecutableWithArgs()
7381
"{test.connectionString}",
7482
"arg2",
7583
"{e1.bindings.ep.url}",
76-
"{test2.connectionString}"
77-
]
84+
"{test2.connectionString}",
85+
"{e2.bindings.ep.url}"
86+
],
87+
"bindings": {
88+
"ep": {
89+
"scheme": "http",
90+
"protocol": "tcp",
91+
"transport": "http",
92+
"targetPort": 8000
93+
}
94+
}
7895
}
7996
""";
8097

tests/Aspire.Hosting.Tests/ProjectResourceTests.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,10 +580,16 @@ public async Task AddProjectWithArgs()
580580
});
581581

582582
var project = appBuilder.AddProject<TestProjectWithLaunchSettings>("projectName")
583+
.WithEndpoint("ep", e =>
584+
{
585+
e.UriScheme = "http";
586+
e.AllocatedEndpoint = new(e, "localhost", 8000);
587+
})
583588
.WithArgs(context =>
584589
{
585590
context.Args.Add("arg1");
586591
context.Args.Add(c1.GetEndpoint("ep"));
592+
context.Args.Add(((IResourceWithEndpoints)context.Resource).GetEndpoint("ep"));
587593
});
588594

589595
using var app = appBuilder.Build();
@@ -592,7 +598,8 @@ public async Task AddProjectWithArgs()
592598

593599
Assert.Collection(args,
594600
arg => Assert.Equal("arg1", arg),
595-
arg => Assert.Equal("http://localhost:1234", arg));
601+
arg => Assert.Equal("http://localhost:1234", arg),
602+
arg => Assert.Equal("http://localhost:8000", arg));
596603

597604
// We don't yet process relationships set via the callbacks
598605
Assert.False(project.Resource.TryGetAnnotationsOfType<ResourceRelationshipAnnotation>(out var relationships));

0 commit comments

Comments
 (0)