-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathEmbeddedRuntimeTrafficPolicy.cs
More file actions
124 lines (107 loc) · 5.68 KB
/
EmbeddedRuntimeTrafficPolicy.cs
File metadata and controls
124 lines (107 loc) · 5.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using DotPilot.Core.Features.RuntimeFoundation;
namespace DotPilot.Runtime.Host.Features.RuntimeFoundation;
internal static class EmbeddedRuntimeTrafficPolicy
{
private const string PolicySummary =
"Client and grain transitions stay explicit so the embedded host can reject unsupported hops before the runtime model grows.";
private const string MermaidHeader = "flowchart LR";
private const string MermaidArrow = " --> ";
private const string MermaidActiveArrow = " ==> ";
public static string Summary => PolicySummary;
public static IReadOnlyList<EmbeddedRuntimeTrafficTransitionDescriptor> AllowedTransitions =>
[
CreateClientTransition(EmbeddedRuntimeHostNames.SessionGrainName),
CreateClientTransition(EmbeddedRuntimeHostNames.WorkspaceGrainName),
CreateClientTransition(EmbeddedRuntimeHostNames.FleetGrainName),
CreateClientTransition(EmbeddedRuntimeHostNames.PolicyGrainName),
CreateClientTransition(EmbeddedRuntimeHostNames.ArtifactGrainName),
CreateTransition(EmbeddedRuntimeHostNames.SessionGrainName, EmbeddedRuntimeHostNames.WorkspaceGrainName, nameof(ISessionGrain.UpsertAsync), nameof(IWorkspaceGrain.GetAsync)),
CreateTransition(EmbeddedRuntimeHostNames.SessionGrainName, EmbeddedRuntimeHostNames.FleetGrainName, nameof(ISessionGrain.UpsertAsync), nameof(IFleetGrain.GetAsync)),
CreateTransition(EmbeddedRuntimeHostNames.SessionGrainName, EmbeddedRuntimeHostNames.PolicyGrainName, nameof(ISessionGrain.UpsertAsync), nameof(IPolicyGrain.GetAsync)),
CreateTransition(EmbeddedRuntimeHostNames.SessionGrainName, EmbeddedRuntimeHostNames.ArtifactGrainName, nameof(ISessionGrain.UpsertAsync), nameof(IArtifactGrain.UpsertAsync)),
CreateTransition(EmbeddedRuntimeHostNames.FleetGrainName, EmbeddedRuntimeHostNames.PolicyGrainName, nameof(IFleetGrain.GetAsync), nameof(IPolicyGrain.GetAsync)),
];
public static bool IsAllowed(EmbeddedRuntimeTrafficProbe probe)
{
ArgumentNullException.ThrowIfNull(probe);
var sourceName = GetGrainName(probe.SourceGrainType);
var targetName = GetGrainName(probe.TargetGrainType);
return AllowedTransitions.Any(transition =>
string.Equals(transition.Source, sourceName, StringComparison.Ordinal) &&
string.Equals(transition.Target, targetName, StringComparison.Ordinal) &&
transition.SourceMethods.Contains(probe.SourceMethod, StringComparer.Ordinal) &&
transition.TargetMethods.Contains(probe.TargetMethod, StringComparer.Ordinal));
}
public static string CreateMermaidDiagram()
{
return CreateMermaidDiagramCore(activeTransition: null);
}
public static string CreateMermaidDiagram(EmbeddedRuntimeTrafficProbe probe)
{
ArgumentNullException.ThrowIfNull(probe);
var activeTransition = (
Source: GetGrainName(probe.SourceGrainType),
Target: GetGrainName(probe.TargetGrainType),
SourceMethod: probe.SourceMethod,
TargetMethod: probe.TargetMethod);
return CreateMermaidDiagramCore(activeTransition);
}
private static EmbeddedRuntimeTrafficTransitionDescriptor CreateClientTransition(string target)
{
return new(
EmbeddedRuntimeHostNames.ClientSourceName,
target,
[EmbeddedRuntimeHostNames.ClientSourceMethodName],
[nameof(ISessionGrain.GetAsync), nameof(ISessionGrain.UpsertAsync)],
false);
}
private static EmbeddedRuntimeTrafficTransitionDescriptor CreateTransition(
string source,
string target,
string sourceMethod,
string targetMethod)
{
return new(
source,
target,
[sourceMethod],
[targetMethod],
false);
}
private static string GetGrainName(Type grainType)
{
ArgumentNullException.ThrowIfNull(grainType);
return grainType == typeof(ISessionGrain) ? EmbeddedRuntimeHostNames.SessionGrainName
: grainType == typeof(IWorkspaceGrain) ? EmbeddedRuntimeHostNames.WorkspaceGrainName
: grainType == typeof(IFleetGrain) ? EmbeddedRuntimeHostNames.FleetGrainName
: grainType == typeof(IPolicyGrain) ? EmbeddedRuntimeHostNames.PolicyGrainName
: grainType == typeof(IArtifactGrain) ? EmbeddedRuntimeHostNames.ArtifactGrainName
: grainType.Name;
}
private static string CreateMermaidDiagramCore((string Source, string Target, string SourceMethod, string TargetMethod)? activeTransition)
{
var lines = new List<string>(AllowedTransitions.Count + 1)
{
MermaidHeader,
};
foreach (var transition in AllowedTransitions)
{
var isActive = activeTransition is not null &&
string.Equals(transition.Source, activeTransition.Value.Source, StringComparison.Ordinal) &&
string.Equals(transition.Target, activeTransition.Value.Target, StringComparison.Ordinal) &&
transition.SourceMethods.Contains(activeTransition.Value.SourceMethod, StringComparer.Ordinal) &&
transition.TargetMethods.Contains(activeTransition.Value.TargetMethod, StringComparer.Ordinal);
var arrow = isActive ? MermaidActiveArrow : MermaidArrow;
lines.Add(
string.Concat(
transition.Source,
arrow,
transition.Target,
" : ",
string.Join(", ", transition.SourceMethods),
" -> ",
string.Join(", ", transition.TargetMethods)));
}
return string.Join(Environment.NewLine, lines);
}
}