-
Notifications
You must be signed in to change notification settings - Fork 167
Expand file tree
/
Copy pathServerConfiguration.cs
More file actions
134 lines (110 loc) · 3.72 KB
/
Copy pathServerConfiguration.cs
File metadata and controls
134 lines (110 loc) · 3.72 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
125
126
127
128
129
130
131
132
133
134
// <copyright file="ServerConfiguration.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>
#nullable enable
using System;
using System.Collections.Generic;
namespace Datadog.Trace.FeatureFlags.Rcm.Model;
internal sealed class ServerConfiguration
{
private bool _validated;
public string? CreatedAt { get; set; }
public string? Format { get; set; }
public Environment? Environment { get; set; }
public Dictionary<string, Flag>? Flags { get; set; }
/// <summary>
/// Gets or sets the collection of flags that failed validation (e.g., invalid SemVer comparands).
/// Maps flag key to an error message describing the validation failure.
/// Populated by <see cref="Validate"/>.
/// </summary>
internal Dictionary<string, string>? InvalidFlags { get; set; }
/// <summary>
/// Validates all flags by pre-parsing SemVer comparands and identifying
/// flags with invalid configuration. This is called eagerly during config
/// loading (before evaluation) so that invalid flags can be detected and
/// reported without waiting for an evaluation to trigger the error.
/// Idempotent: safe to call multiple times.
/// </summary>
internal void Validate()
{
if (_validated)
{
return;
}
_validated = true;
if (Flags is null)
{
return;
}
foreach (var pair in Flags)
{
var flagKey = pair.Key;
var flag = pair.Value;
if (flag?.Allocations is null)
{
continue;
}
foreach (var allocation in flag.Allocations)
{
if (allocation.Rules is null)
{
continue;
}
foreach (var rule in allocation.Rules)
{
if (rule.Conditions is null)
{
continue;
}
foreach (var condition in rule.Conditions)
{
if (!condition.TryPreparseSemverComparand())
{
InvalidFlags ??= new Dictionary<string, string>();
InvalidFlags[flagKey] = $"Invalid semantic version comparand for flag \"{flagKey}\"";
break;
}
}
if (InvalidFlags is not null && InvalidFlags.ContainsKey(flagKey))
{
break;
}
}
if (InvalidFlags is not null && InvalidFlags.ContainsKey(flagKey))
{
break;
}
}
}
}
internal void Merge(ServerConfiguration other)
{
// Merging changes the flag set, so the merged config needs re-validation.
_validated = false;
InvalidFlags = null;
if (other.CreatedAt is not null)
{
CreatedAt = other.CreatedAt;
}
if (other.Format is not null)
{
Format = other.Format;
}
if (other.Environment is not null)
{
Environment = other.Environment;
}
if (Flags is null)
{
Flags = new Dictionary<string, Flag>();
}
if (other.Flags is not null)
{
foreach (var pair in other.Flags)
{
Flags[pair.Key] = pair.Value;
}
}
}
}