Skip to content

Commit 0e94911

Browse files
author
Guy Fankam
committed
Adds proper order for workspace backends (#797). Refactors policy named value dependencies.
1 parent fcbcf1d commit 0e94911

1 file changed

Lines changed: 86 additions & 50 deletions

File tree

src/publisher/Relationships.cs

Lines changed: 86 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
using Azure;
12
using common;
23
using Microsoft.Extensions.DependencyInjection;
34
using Microsoft.Extensions.Hosting;
5+
using OpenTelemetry.Resources;
46
using System;
57
using System.Collections.Concurrent;
68
using System.Collections.Generic;
@@ -287,59 +289,24 @@ await resources.Values
287289
// Process policies for named value references
288290
if (key.Resource is IPolicyResource policyResource)
289291
{
290-
var policyContentOption = await getPolicyFileContents(policyResource, key.Name, key.Parents, operations.ReadFile, cancellationToken);
291-
292-
policyContentOption.Iter(policyContent =>
293-
{
294-
// Get workspace associated with the policy (if any)
295-
var workspaceOption = key.Parents.Head(tuple => tuple.Resource is WorkspaceResource);
296-
297-
// Extract all named values from the policy
298-
getPolicyNamedValues(policyContent)
299-
.Choose(namedValueName =>
300-
// Look for the named value in the same workspace
301-
workspaceOption.Bind(workspace => from workspaceNamedValues in resources.Find(WorkspaceNamedValueResource.Instance)
302-
from workspaceNamedValue in
303-
workspaceNamedValues.Head(key => key.Parents.Any(parent => parent == workspace)
304-
&& key.Name == namedValueName)
305-
select workspaceNamedValue)
306-
// If not found, look for a service-level named value
307-
.IfNone(() => from namedValues in resources.Find(NamedValueResource.Instance)
308-
from namedValue in
309-
namedValues.Head(key => key.Name == namedValueName)
310-
select namedValue))
311-
.Iter(namedValue => pairs.Add((namedValue, key)), cancellationToken);
312-
});
292+
var namedValues = await getPolicyNamedValues(policyResource, key.Name, key.Parents, operations.ReadFile, resources, cancellationToken);
293+
namedValues.Iter(namedValue => pairs.Add((namedValue, key)), cancellationToken);
313294
}
314295

315296
// Process backend pools for individual backend references
316297
if (key.Resource is BackendResource backendResource)
317298
{
318-
var parents = key.Parents;
319-
var serializerOptions = ((IResourceWithDto)backendResource).SerializerOptions;
299+
dtoJsonOption.Map(json => getBackendPoolBackends(backendResource, key.Name, key.Parents, json, cancellationToken))
300+
.IfNone(() => [])
301+
.Iter(backend => pairs.Add((backend, key)), cancellationToken);
302+
}
320303

321-
dtoJsonOption.Bind(json => JsonNodeModule.To<BackendDto>(json, serializerOptions)
322-
.ToOption())
323-
// Get pool backends
324-
.Map(dto => dto.Properties.Pool?.Services ?? [])
304+
// Process workspace backend pools for individual backend references
305+
if (key.Resource is WorkspaceBackendResource workspaceBackendResource)
306+
{
307+
dtoJsonOption.Map(json => getWorkspaceBackendPoolBackends(workspaceBackendResource, key.Name, key.Parents, json, cancellationToken))
325308
.IfNone(() => [])
326-
// Get backend names from their IDs
327-
.Choose(backend =>
328-
{
329-
var nameString = backend.Id?.Split('/').LastOrDefault() ?? string.Empty;
330-
331-
return ResourceName.From(nameString)
332-
.ToOption();
333-
})
334-
// Create resource keys for each backend
335-
.Select(backendName => new ResourceKey
336-
{
337-
Resource = backendResource,
338-
Name = backendName,
339-
Parents = parents
340-
})
341-
// Pair backends with the pool
342-
.Iter(backendPredecessor => pairs.Add((backendPredecessor, key)), cancellationToken);
309+
.Iter(backend => pairs.Add((backend, key)), cancellationToken);
343310
}
344311

345312
// Process non-root API revisions
@@ -355,6 +322,7 @@ from namedValue in
355322
Name = rootName,
356323
Parents = key.Parents
357324
};
325+
358326
pairs.Add((currentRevision, key));
359327
});
360328
}
@@ -372,6 +340,7 @@ from namedValue in
372340
Name = rootName,
373341
Parents = key.Parents
374342
};
343+
375344
pairs.Add((currentRevision, key));
376345
});
377346
}
@@ -511,22 +480,89 @@ static Result<ResourceName> getResourceName(string id, IResource resource, Paren
511480
};
512481
}
513482

514-
static ImmutableHashSet<ResourceName> getPolicyNamedValues(BinaryData policyContent)
483+
async ValueTask<ImmutableHashSet<ResourceKey>> getPolicyNamedValues(IPolicyResource resource, ResourceName name, ParentChain parents, ReadFile readFile, IDictionary<IResource, ImmutableHashSet<ResourceKey>> resources, CancellationToken cancellationToken)
515484
{
516-
var policyContentText = policyContent.ToString();
485+
var workspaceOption = parents.Head(tuple => tuple.Resource is WorkspaceResource);
517486

518-
if (string.IsNullOrWhiteSpace(policyContentText))
487+
var namedValueNames = await getPolicyNamedValueNames(resource, name, parents, readFile, resources, cancellationToken);
488+
489+
return [.. namedValueNames.Choose(name => findNamedValue(name, workspaceOption, resources))];
490+
}
491+
492+
async ValueTask<ImmutableHashSet<ResourceName>> getPolicyNamedValueNames(IPolicyResource resource, ResourceName name, ParentChain parents, ReadFile readFile, IDictionary<IResource, ImmutableHashSet<ResourceKey>> resources, CancellationToken cancellationToken)
493+
{
494+
var contentsOption = from binaryData in await getPolicyFileContents(resource, name, parents, readFile, cancellationToken)
495+
select binaryData.ToString();
496+
497+
var contents = contentsOption.IfNoneNull() ?? string.Empty;
498+
499+
if (string.IsNullOrWhiteSpace(contents))
519500
{
520501
return [];
521502
}
522503

523504
var regex = new Regex("{{\\s*(.*?)\\s*}}", RegexOptions.CultureInvariant);
524505

525-
return [.. regex.Matches(policyContentText)
506+
return [.. regex.Matches(contents)
526507
.Choose(match => ResourceName.From(match.Groups[1].Value.Trim())
527508
.ToOption())];
528509
}
529510

511+
Option<ResourceKey> findNamedValue(ResourceName name, Option<(IResource, ResourceName)> workspaceOption, IDictionary<IResource, ImmutableHashSet<ResourceKey>> resources) =>
512+
// Look for the named value in the workspace
513+
workspaceOption.Bind(workspace => from namedValues in resources.Find(WorkspaceNamedValueResource.Instance)
514+
from namedValue in namedValues.Head(key => key.Name == name
515+
&& key.Parents.Any(parent => parent == workspace))
516+
select namedValue)
517+
// If not found, look for a service-level named value
518+
.IfNone(() => from namedValues in resources.Find(NamedValueResource.Instance)
519+
from namedValue in namedValues.Head(key => key.Name == name)
520+
select namedValue);
521+
522+
static ImmutableHashSet<ResourceKey> getBackendPoolBackends(BackendResource resource, ResourceName name, ParentChain parents, JsonObject dto, CancellationToken cancellationToken)
523+
{
524+
var serializerOptions = ((IResourceWithDto)resource).SerializerOptions;
525+
526+
return [.. JsonNodeModule.To<BackendDto>(dto, serializerOptions)
527+
.Map(backendDto => backendDto.Properties.Pool?.Services ?? [])
528+
.IfError(_ => [])
529+
.Choose(backend =>
530+
{
531+
var nameString = backend.Id?.Split('/').LastOrDefault() ?? string.Empty;
532+
533+
return ResourceName.From(nameString)
534+
.ToOption();
535+
})
536+
.Select(backendName => new ResourceKey
537+
{
538+
Resource = resource,
539+
Name = backendName,
540+
Parents = parents
541+
})];
542+
}
543+
544+
static ImmutableHashSet<ResourceKey> getWorkspaceBackendPoolBackends(WorkspaceBackendResource resource, ResourceName name, ParentChain parents, JsonObject dto, CancellationToken cancellationToken)
545+
{
546+
var serializerOptions = ((IResourceWithDto)resource).SerializerOptions;
547+
548+
return [.. JsonNodeModule.To<WorkspaceBackendDto>(dto, serializerOptions)
549+
.Map(backendDto => backendDto.Properties.Pool?.Services ?? [])
550+
.IfError(_ => [])
551+
.Choose(backend =>
552+
{
553+
var nameString = backend.Id?.Split('/').LastOrDefault() ?? string.Empty;
554+
555+
return ResourceName.From(nameString)
556+
.ToOption();
557+
})
558+
.Select(backendName => new ResourceKey
559+
{
560+
Resource = resource,
561+
Name = backendName,
562+
Parents = parents
563+
})];
564+
}
565+
530566
static bool isPredecessorWithOptionalArtifacts(ResourceKey key) =>
531567
key.Resource switch
532568
{

0 commit comments

Comments
 (0)