Skip to content

Commit fe60a3b

Browse files
committed
Merge branch 'main' into aaronpowell/issue32
2 parents ca09b6a + 0570ad3 commit fe60a3b

File tree

4 files changed

+221
-22
lines changed

4 files changed

+221
-22
lines changed

src/Aspire.CommunityToolkit.Hosting.Java/JavaAppHostingExtension.cs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,21 @@ public static class JavaAppHostingExtension
1919
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
2020
public static IResourceBuilder<JavaAppContainerResource> AddJavaApp(this IDistributedApplicationBuilder builder, string name, JavaAppContainerResourceOptions options)
2121
{
22-
if (string.IsNullOrWhiteSpace(options.ContainerImageName) == true)
23-
{
24-
throw new ArgumentException("Container image name must be specified.", nameof(options));
25-
}
22+
ArgumentNullException.ThrowIfNull(builder, nameof(builder));
23+
ArgumentNullException.ThrowIfNull(options, nameof(options));
24+
ArgumentException.ThrowIfNullOrWhiteSpace(name, nameof(name));
25+
ArgumentException.ThrowIfNullOrWhiteSpace(options.ContainerImageName, nameof(options.ContainerImageName));
2626

2727
var resource = new JavaAppContainerResource(name);
2828

29-
var rb = builder.AddResource(resource);
30-
if (string.IsNullOrWhiteSpace(options.ContainerRegistry) == false)
31-
{
32-
rb.WithImageRegistry(options.ContainerRegistry);
33-
}
34-
rb.WithImage(options.ContainerImageName)
35-
.WithImageTag(options.ContainerImageTag)
29+
var rb = builder.AddResource(resource)
30+
.WithAnnotation(new ContainerImageAnnotation { Image = options.ContainerImageName, Tag = options.ContainerImageTag, Registry = options.ContainerRegistry })
3631
.WithHttpEndpoint(port: options.Port, targetPort: options.TargetPort, name: JavaAppContainerResource.HttpEndpointName)
3732
.WithJavaDefaults(options);
33+
3834
if (options.Args is { Length: > 0 })
3935
{
40-
#pragma warning disable CS8604 // Possible null reference argument.
4136
rb.WithArgs(options.Args);
42-
#pragma warning restore CS8604 // Possible null reference argument.
4337
}
4438

4539
return rb;
@@ -52,10 +46,8 @@ public static IResourceBuilder<JavaAppContainerResource> AddJavaApp(this IDistri
5246
/// <param name="name">The name of the resource.</param>
5347
/// <param name="options">The <see cref="JavaAppContainerResourceOptions"/> to configure the Java application.</param>"
5448
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
55-
public static IResourceBuilder<JavaAppContainerResource> AddSpringApp(this IDistributedApplicationBuilder builder, string name, JavaAppContainerResourceOptions options)
56-
{
57-
return builder.AddJavaApp(name, options);
58-
}
49+
public static IResourceBuilder<JavaAppContainerResource> AddSpringApp(this IDistributedApplicationBuilder builder, string name, JavaAppContainerResourceOptions options) =>
50+
builder.AddJavaApp(name, options);
5951

6052
/// <summary>
6153
/// Adds a Java application to the application model. Executes the executable Java app.
@@ -67,6 +59,11 @@ public static IResourceBuilder<JavaAppContainerResource> AddSpringApp(this IDist
6759
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
6860
public static IResourceBuilder<JavaAppExecutableResource> AddJavaApp(this IDistributedApplicationBuilder builder, string name, string workingDirectory, JavaAppExecutableResourceOptions options)
6961
{
62+
ArgumentNullException.ThrowIfNull(builder, nameof(builder));
63+
ArgumentNullException.ThrowIfNull(options, nameof(options));
64+
ArgumentException.ThrowIfNullOrWhiteSpace(name, nameof(name));
65+
ArgumentException.ThrowIfNullOrWhiteSpace(workingDirectory, nameof(workingDirectory));
66+
7067
#pragma warning disable CS8601 // Possible null reference assignment.
7168
string[] allArgs = options.Args is { Length: > 0 }
7269
? ["-jar", options.ApplicationName, .. options.Args]
@@ -90,10 +87,8 @@ public static IResourceBuilder<JavaAppExecutableResource> AddJavaApp(this IDistr
9087
/// <param name="workingDirectory">The working directory to use for the command. If null, the working directory of the current process is used.</param>
9188
/// <param name="options">The <see cref="JavaAppExecutableResourceOptions"/> to configure the Java application.</param>"
9289
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
93-
public static IResourceBuilder<JavaAppExecutableResource> AddSpringApp(this IDistributedApplicationBuilder builder, string name, string workingDirectory, JavaAppExecutableResourceOptions options)
94-
{
95-
return builder.AddJavaApp(name, workingDirectory, options);
96-
}
90+
public static IResourceBuilder<JavaAppExecutableResource> AddSpringApp(this IDistributedApplicationBuilder builder, string name, string workingDirectory, JavaAppExecutableResourceOptions options) =>
91+
builder.AddJavaApp(name, workingDirectory, options);
9792

9893
private static IResourceBuilder<JavaAppContainerResource> WithJavaDefaults(
9994
this IResourceBuilder<JavaAppContainerResource> builder,
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
namespace Aspire.CommunityToolkit.Hosting.Java.Tests;
2+
public class ContainerResourceCreationTests
3+
{
4+
[Fact]
5+
public void AddJavaAppBuilderShouldNotBeNull()
6+
{
7+
IDistributedApplicationBuilder builder = null!;
8+
9+
Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", new JavaAppContainerResourceOptions()));
10+
}
11+
12+
[Fact]
13+
public void AddSpringAppBuilderShouldNotBeNull()
14+
{
15+
IDistributedApplicationBuilder builder = null!;
16+
17+
Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp("spring", new JavaAppContainerResourceOptions()));
18+
}
19+
20+
[Fact]
21+
public void AddJavaAppNameShouldNotBeNullOrWhiteSpace()
22+
{
23+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
24+
25+
Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp(null!, new JavaAppContainerResourceOptions()));
26+
Assert.Throws<ArgumentException>(() => builder.AddJavaApp("", new JavaAppContainerResourceOptions()));
27+
}
28+
29+
[Fact]
30+
public void AddSpringAppNameShouldNotBeNullOrWhiteSpace()
31+
{
32+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
33+
34+
Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp(null!, new JavaAppContainerResourceOptions()));
35+
Assert.Throws<ArgumentException>(() => builder.AddSpringApp("", new JavaAppContainerResourceOptions()));
36+
}
37+
38+
[Fact]
39+
public void AddJavaAppContainerImageNameShouldNotBeNullOrWhiteSpace()
40+
{
41+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
42+
43+
Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", new JavaAppContainerResourceOptions { ContainerImageName = null! }));
44+
Assert.Throws<ArgumentException>(() => builder.AddJavaApp("java", new JavaAppContainerResourceOptions { ContainerImageName = "" }));
45+
}
46+
47+
[Fact]
48+
public void AddJavaAppContainerResourceOptionsShouldNotBeNull()
49+
{
50+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
51+
52+
Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", null!));
53+
}
54+
55+
[Fact]
56+
public void AddSpringAppContainerResourceOptionsShouldNotBeNull()
57+
{
58+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
59+
60+
Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp("spring", null!));
61+
}
62+
63+
[Fact]
64+
public async Task AddJavaAppContainerDetailsSetOnResource()
65+
{
66+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
67+
68+
var options = new JavaAppContainerResourceOptions
69+
{
70+
ContainerImageName = "java-app",
71+
ContainerRegistry = "docker.io",
72+
ContainerImageTag = "latest",
73+
Port = 8080,
74+
TargetPort = 8080,
75+
OtelAgentPath = "path/to/otel",
76+
Args = ["arg1", "arg2"]
77+
};
78+
79+
builder.AddJavaApp("java", options);
80+
81+
using var app = builder.Build();
82+
83+
var appModel = app.Services.GetRequiredService<DistributedApplicationModel>();
84+
85+
var resource = appModel.Resources.OfType<JavaAppContainerResource>().SingleOrDefault();
86+
87+
Assert.NotNull(resource);
88+
Assert.Equal("java", resource.Name);
89+
90+
Assert.True(resource.TryGetLastAnnotation(out ContainerImageAnnotation? imageAnnotations));
91+
Assert.Equal(options.ContainerImageName, imageAnnotations.Image);
92+
Assert.Equal(options.ContainerRegistry, imageAnnotations.Registry);
93+
Assert.Equal(options.ContainerImageTag, imageAnnotations.Tag);
94+
95+
Assert.True(resource.TryGetLastAnnotation(out EndpointAnnotation? httpEndpointAnnotations));
96+
Assert.Equal(options.Port, httpEndpointAnnotations.Port);
97+
Assert.Equal(options.TargetPort, httpEndpointAnnotations.TargetPort);
98+
99+
Assert.True(resource.TryGetLastAnnotation(out CommandLineArgsCallbackAnnotation? argsAnnotations));
100+
CommandLineArgsCallbackContext context = new([]);
101+
await argsAnnotations.Callback(context);
102+
Assert.All(options.Args, arg => Assert.Contains(arg, context.Args));
103+
}
104+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
namespace Aspire.CommunityToolkit.Hosting.Java.Tests;
2+
3+
public class ExecutableResourceCreationTests
4+
{
5+
[Fact]
6+
public void AddJavaAppBuilderShouldNotBeNull()
7+
{
8+
IDistributedApplicationBuilder builder = null!;
9+
10+
Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
11+
}
12+
13+
[Fact]
14+
public void AddSpringAppBuilderShouldNotBeNull()
15+
{
16+
IDistributedApplicationBuilder builder = null!;
17+
18+
Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp("spring", Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
19+
}
20+
21+
[Fact]
22+
public void AddJavaAppNameShouldNotBeNullOrWhiteSpace()
23+
{
24+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
25+
26+
Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp(null!, Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
27+
Assert.Throws<ArgumentException>(() => builder.AddJavaApp("", Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
28+
}
29+
30+
[Fact]
31+
public void AddSpringAppNameShouldNotBeNullOrWhiteSpace()
32+
{
33+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
34+
35+
Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp(null!, Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
36+
Assert.Throws<ArgumentException>(() => builder.AddSpringApp("", Environment.CurrentDirectory, new JavaAppExecutableResourceOptions()));
37+
}
38+
39+
[Fact]
40+
public void AddJavaAppWorkingDirectoryShouldNotBeNullOrWhiteSpace()
41+
{
42+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
43+
44+
Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", null!, new JavaAppExecutableResourceOptions()));
45+
Assert.Throws<ArgumentException>(() => builder.AddJavaApp("java", "", new JavaAppExecutableResourceOptions()));
46+
}
47+
48+
[Fact]
49+
public void AddJavaAppExecutableResourceOptionsShouldNotBeNull()
50+
{
51+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
52+
53+
Assert.Throws<ArgumentNullException>(() => builder.AddJavaApp("java", Environment.CurrentDirectory, null!));
54+
}
55+
56+
[Fact]
57+
public void AddSpringAppContainerResourceOptionsShouldNotBeNull()
58+
{
59+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
60+
61+
Assert.Throws<ArgumentNullException>(() => builder.AddSpringApp("spring", Environment.CurrentDirectory, null!));
62+
}
63+
64+
[Fact]
65+
public async Task AddJavaAppContainerDetailsSetOnResource()
66+
{
67+
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder();
68+
69+
var options = new JavaAppExecutableResourceOptions
70+
{
71+
ApplicationName = "test.jar",
72+
Args = ["--test"],
73+
OtelAgentPath = "otel-agent",
74+
Port = 8080
75+
};
76+
77+
builder.AddJavaApp("java", Environment.CurrentDirectory, options);
78+
79+
using var app = builder.Build();
80+
81+
var appModel = app.Services.GetRequiredService<DistributedApplicationModel>();
82+
83+
var resource = appModel.Resources.OfType<JavaAppExecutableResource>().SingleOrDefault();
84+
85+
Assert.NotNull(resource);
86+
Assert.Equal("java", resource.Name);
87+
88+
Assert.Equal(Environment.CurrentDirectory, resource.WorkingDirectory);
89+
Assert.Equal("java", resource.Command);
90+
91+
Assert.True(resource.TryGetLastAnnotation(out EndpointAnnotation? httpEndpointAnnotations));
92+
Assert.Equal(options.Port, httpEndpointAnnotations.Port);
93+
94+
Assert.True(resource.TryGetLastAnnotation(out CommandLineArgsCallbackAnnotation? argsAnnotations));
95+
CommandLineArgsCallbackContext context = new([]);
96+
await argsAnnotations.Callback(context);
97+
Assert.All(options.Args, arg => Assert.Contains(arg, context.Args));
98+
Assert.Contains("-jar", context.Args);
99+
Assert.Contains(options.ApplicationName, context.Args);
100+
}
101+
}

tests/Aspire.CommunityToolkit.Testing/Aspire.CommunityToolkit.Testing.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
XUnit recommends only using xunit.extensibility.*, xunit.assert, and xunit.abstractions for packages which "extend" xunit.
1313
This allows consumers to decide which type of xunit runner they want to use to run these tests,
1414
and avoids problems with `dotnet pack`.
15-
1615
See https://xunit.github.io/docs/nuget-packages and the special note in https://xunit.github.io/releases/2.3.
1716
-->
1817
<PackageReference Include="xunit.extensibility.execution" />

0 commit comments

Comments
 (0)