Skip to content

Commit 42af3cf

Browse files
committed
refactor: write to Surrealist container files
1 parent 87d777c commit 42af3cf

File tree

1 file changed

+96
-79
lines changed

1 file changed

+96
-79
lines changed

src/CommunityToolkit.Aspire.Hosting.SurrealDb/SurrealDbBuilderExtensions.cs

Lines changed: 96 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
using Aspire.Hosting.ApplicationModel;
55
using Microsoft.Extensions.DependencyInjection;
6-
using Microsoft.Extensions.Hosting;
76
using SurrealDb.Net;
7+
using System.Text;
88
using System.Text.Json;
99

1010
namespace Aspire.Hosting;
@@ -284,108 +284,125 @@ public static IResourceBuilder<T> WithSurrealist<T>(
284284

285285
containerName ??= $"{builder.Resource.Name}-surrealist";
286286

287-
const string CONNECTIONS_FILE_PATH = "/usr/share/nginx/html/instance.json";
288-
289287
var surrealistContainer = new SurrealistContainerResource(containerName);
290288
var surrealistContainerBuilder = builder.ApplicationBuilder.AddResource(surrealistContainer)
291289
.WithImage(SurrealDbContainerImageTags.SurrealistImage, SurrealDbContainerImageTags.SurrealistTag)
292290
.WithImageRegistry(SurrealDbContainerImageTags.SurrealistRegistry)
293291
.WithHttpEndpoint(targetPort: 8080, name: "http")
294-
.WithBindMount(Path.GetTempFileName(), CONNECTIONS_FILE_PATH)
295292
.WithRelationship(builder.Resource, "Surrealist")
296293
.ExcludeFromManifest();
294+
295+
surrealistContainerBuilder.WithContainerFiles(
296+
destinationPath: "/usr/share/nginx/html",
297+
callback: async (_, cancellationToken) =>
298+
{
299+
var surrealDbServerInstances =
300+
builder.ApplicationBuilder.Resources.OfType<SurrealDbServerResource>().ToList();
301+
var surrealDbNamespaceResources =
302+
builder.ApplicationBuilder.Resources.OfType<SurrealDbNamespaceResource>().ToList();
303+
var surrealDbDatabaseResources =
304+
builder.ApplicationBuilder.Resources.OfType<SurrealDbDatabaseResource>().ToList();
305+
306+
return [
307+
new ContainerFile
308+
{
309+
Name = "instance.json",
310+
Contents = await WriteSurrealistInstanceJson(
311+
surrealDbServerInstances,
312+
surrealDbNamespaceResources,
313+
surrealDbDatabaseResources,
314+
cancellationToken
315+
).ConfigureAwait(false),
316+
},
317+
];
318+
});
297319

298-
builder.ApplicationBuilder.Eventing.Subscribe<AfterEndpointsAllocatedEvent>((e, ct) =>
320+
configureContainer?.Invoke(surrealistContainerBuilder);
321+
322+
return builder;
323+
}
324+
325+
private static async Task<string> WriteSurrealistInstanceJson(
326+
IList<SurrealDbServerResource> surrealDbServerInstances,
327+
IList<SurrealDbNamespaceResource> surrealDbNamespaceResources,
328+
IList<SurrealDbDatabaseResource> surrealDbDatabaseResources,
329+
CancellationToken cancellationToken
330+
)
331+
{
332+
using var stream = new MemoryStream();
333+
await using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true });
334+
335+
writer.WriteStartObject();
336+
337+
writer.WriteStartArray("connections");
338+
339+
foreach (var surrealInstance in surrealDbServerInstances)
340+
{
341+
if (surrealInstance.PrimaryEndpoint.IsAllocated)
299342
{
300-
var serverFileMount = surrealistContainer.Annotations.OfType<ContainerMountAnnotation>().Single(v => v.Target == CONNECTIONS_FILE_PATH);
301-
var surrealDbServerResources = builder.ApplicationBuilder.Resources.OfType<SurrealDbServerResource>().ToList();
343+
SurrealDbNamespaceResource? uniqueNamespace = null;
344+
SurrealDbDatabaseResource? uniqueDatabase = null;
302345

303-
using var stream = new FileStream(serverFileMount.Source!, FileMode.Create);
304-
using var writer = new Utf8JsonWriter(stream);
346+
var serverNamespaces = surrealDbNamespaceResources
347+
.Where(ns => ns.Parent == surrealInstance)
348+
.ToList();
305349

306-
// Need to grant read access to the config file on unix like systems.
307-
if (!OperatingSystem.IsWindows())
350+
if (serverNamespaces.Count == 1)
308351
{
309-
File.SetUnixFileMode(serverFileMount.Source!, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.GroupRead | UnixFileMode.OtherRead);
352+
uniqueNamespace = serverNamespaces.First();
353+
354+
var nsDatabases = surrealDbDatabaseResources
355+
.Where(db => db.Parent == uniqueNamespace)
356+
.ToList();
357+
358+
if (nsDatabases.Count == 1)
359+
{
360+
uniqueDatabase = nsDatabases.First();
361+
}
310362
}
311363

312-
writer.WriteStartObject();
364+
var endpoint = surrealInstance.PrimaryEndpoint;
313365

314-
writer.WriteStartArray("connections");
366+
writer.WriteStartObject();
315367

316-
var surrealDbNamespaceResources = builder.ApplicationBuilder.Resources.OfType<SurrealDbNamespaceResource>().ToList();
317-
var surrealDbDatabaseResources = builder.ApplicationBuilder.Resources.OfType<SurrealDbDatabaseResource>().ToList();
368+
writer.WriteString("id", surrealInstance.Name);
369+
writer.WriteString("name", surrealInstance.Name);
318370

319-
foreach (var surrealInstance in surrealDbServerResources)
371+
if (uniqueNamespace is not null)
320372
{
321-
if (surrealInstance.PrimaryEndpoint.IsAllocated)
322-
{
323-
SurrealDbNamespaceResource? uniqueNamespace = null;
324-
SurrealDbDatabaseResource? uniqueDatabase = null;
325-
326-
var serverNamespaces = surrealDbNamespaceResources
327-
.Where(ns => ns.Parent == surrealInstance)
328-
.ToList();
329-
330-
if (serverNamespaces.Count == 1)
331-
{
332-
uniqueNamespace = serverNamespaces.First();
333-
334-
var nsDatabases = surrealDbDatabaseResources
335-
.Where(db => db.Parent == uniqueNamespace)
336-
.ToList();
337-
338-
if (nsDatabases.Count == 1)
339-
{
340-
uniqueDatabase = nsDatabases.First();
341-
}
342-
}
343-
344-
var endpoint = surrealInstance.PrimaryEndpoint;
345-
346-
writer.WriteStartObject();
347-
348-
writer.WriteString("id", surrealInstance.Name);
349-
writer.WriteString("name", surrealInstance.Name);
350-
351-
if (uniqueNamespace is not null)
352-
{
353-
writer.WriteString("defaultNamespace", uniqueNamespace.NamespaceName);
354-
}
355-
if (uniqueDatabase is not null)
356-
{
357-
writer.WriteString("defaultDatabase", uniqueDatabase.DatabaseName);
358-
}
359-
360-
writer.WriteStartObject("authentication");
361-
writer.WriteString("protocol", "ws");
362-
// How to do host resolution?
363-
writer.WriteString("hostname", $"localhost:{endpoint.Port}");
364-
writer.WriteString("mode", "root");
365-
if (uniqueNamespace is not null)
366-
{
367-
writer.WriteString("namespace", uniqueNamespace.NamespaceName);
368-
}
369-
if (uniqueDatabase is not null)
370-
{
371-
writer.WriteString("database", uniqueDatabase.DatabaseName);
372-
}
373-
374-
writer.WriteEndObject();
375-
376-
writer.WriteEndObject();
377-
}
373+
writer.WriteString("defaultNamespace", uniqueNamespace.NamespaceName);
374+
}
375+
if (uniqueDatabase is not null)
376+
{
377+
writer.WriteString("defaultDatabase", uniqueDatabase.DatabaseName);
378378
}
379379

380-
writer.WriteEndArray();
380+
writer.WriteStartObject("authentication");
381+
writer.WriteString("protocol", "ws");
382+
// How to do host resolution?
383+
writer.WriteString("hostname", $"localhost:{endpoint.Port}");
384+
writer.WriteString("mode", "root");
385+
if (uniqueNamespace is not null)
386+
{
387+
writer.WriteString("namespace", uniqueNamespace.NamespaceName);
388+
}
389+
if (uniqueDatabase is not null)
390+
{
391+
writer.WriteString("database", uniqueDatabase.DatabaseName);
392+
}
381393

382394
writer.WriteEndObject();
383395

384-
return Task.CompletedTask;
385-
});
396+
writer.WriteEndObject();
397+
}
398+
}
386399

387-
configureContainer?.Invoke(surrealistContainerBuilder);
400+
writer.WriteEndArray();
388401

389-
return builder;
402+
writer.WriteEndObject();
403+
404+
await writer.FlushAsync(cancellationToken);
405+
406+
return Encoding.UTF8.GetString(stream.ToArray());
390407
}
391408
}

0 commit comments

Comments
 (0)