• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ThreeMammals / Ocelot / 21076334793

16 Jan 2026 06:14PM UTC coverage: 93.469% (-0.03%) from 93.503%
21076334793

Pull #2125

github

web-flow
Merge df7350da3 into 9fc4e78d3
Pull Request #2125: Remove the `Newtonsoft.Json` package and migrate to `System.Text.Json`

6569 of 7028 relevant lines covered (93.47%)

4285.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.23
src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs
1
using Microsoft.AspNetCore.Hosting;
2
using Microsoft.Extensions.Configuration;
3
using Microsoft.Extensions.Configuration.Memory;
4
using Ocelot.Configuration.File;
5
using Ocelot.Infrastructure;
6
using System.Text;
7
using System.Text.Json;
8

9
namespace Ocelot.DependencyInjection;
10

11
/// <summary>
12
/// Defines extension-methods for the <see cref="IConfigurationBuilder"/> interface.
13
/// </summary>
14
public static partial class ConfigurationBuilderExtensions
15
{
16
    public const string PrimaryConfigFile = "ocelot.json";
17
    public const string GlobalConfigFile = "ocelot.global.json";
18
    public const string EnvironmentConfigFile = "ocelot.{0}.json";
19

20
    [Obsolete("Please set BaseUrl in ocelot.json GlobalConfiguration.BaseUrl")]
21
    public static IConfigurationBuilder AddOcelotBaseUrl(this IConfigurationBuilder builder, string baseUrl)
22
    {
23
        var memorySource = new MemoryConfigurationSource
1✔
24
        {
1✔
25
            InitialData = new List<KeyValuePair<string, string>>
1✔
26
            {
1✔
27
                new("BaseUrl", baseUrl),
1✔
28
            },
1✔
29
        };
1✔
30

31
        return builder.Add(memorySource);
1✔
32
    }
33

34
    /// <summary>
35
    /// Adds Ocelot configuration by environment, reading the required files from the default path.
36
    /// </summary>
37
    /// <param name="builder">Configuration builder to extend.</param>
38
    /// <param name="env">Web hosting environment object.</param>
39
    /// <returns>An <see cref="IConfigurationBuilder"/> object.</returns>
40
    public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, IWebHostEnvironment env)
41
        => builder.AddOcelot(".", env);
2✔
42

43
    /// <summary>
44
    /// Adds Ocelot configuration by environment, reading the required files from the specified folder.
45
    /// </summary>
46
    /// <param name="builder">Configuration builder to extend.</param>
47
    /// <param name="folder">Folder to read files from.</param>
48
    /// <param name="env">Web hosting environment object.</param>
49
    /// <returns>An <see cref="IConfigurationBuilder"/> object.</returns>
50
    public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, string folder, IWebHostEnvironment env)
51
        => builder.AddOcelot(folder, env, MergeOcelotJson.ToFile);
2✔
52

53
    /// <summary>
54
    /// Adds Ocelot configuration by environment and merge option, reading the required files from the current default folder.
55
    /// </summary>
56
    /// <remarks>Use optional arguments for injections and overridings.</remarks>
57
    /// <param name="builder">Configuration builder to extend.</param>
58
    /// <param name="env">Web hosting environment object.</param>
59
    /// <param name="mergeTo">Option to merge files to.</param>
60
    /// <param name="primaryConfigFile">Primary config file.</param>
61
    /// <param name="globalConfigFile">Global config file.</param>
62
    /// <param name="environmentConfigFile">Environment config file.</param>
63
    /// <param name="optional">The 2nd argument of the AddJsonFile.</param>
64
    /// <param name="reloadOnChange">The 3rd argument of the AddJsonFile.</param>
65
    /// <returns>An <see cref="IConfigurationBuilder"/> object.</returns>
66
    public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, IWebHostEnvironment env, MergeOcelotJson mergeTo,
67
        string primaryConfigFile = null, string globalConfigFile = null, string environmentConfigFile = null, bool? optional = null, bool? reloadOnChange = null) // optional injections
68
        => builder.AddOcelot(".", env, mergeTo, primaryConfigFile, globalConfigFile, environmentConfigFile, optional, reloadOnChange);
×
69

70
    /// <summary>
71
    /// Adds Ocelot configuration by environment and merge option, reading the required files from the specified folder.
72
    /// </summary>
73
    /// <remarks>Use optional arguments for injections and overridings.</remarks>
74
    /// <param name="builder">Configuration builder to extend.</param>
75
    /// <param name="folder">Folder to read files from.</param>
76
    /// <param name="env">Web hosting environment object.</param>
77
    /// <param name="mergeTo">Option to merge files to.</param>
78
    /// <param name="primaryConfigFile">Primary config file.</param>
79
    /// <param name="globalConfigFile">Global config file.</param>
80
    /// <param name="environmentConfigFile">Environment config file.</param>
81
    /// <param name="optional">The 2nd argument of the AddJsonFile.</param>
82
    /// <param name="reloadOnChange">The 3rd argument of the AddJsonFile.</param>
83
    /// <returns>An <see cref="IConfigurationBuilder"/> object.</returns>
84
    public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, string folder, IWebHostEnvironment env, MergeOcelotJson mergeTo,
85
        string primaryConfigFile = null, string globalConfigFile = null, string environmentConfigFile = null, bool? optional = null, bool? reloadOnChange = null) // optional injections
86
    {
87
        var json = GetMergedOcelotJson(folder, env, null, primaryConfigFile, globalConfigFile, environmentConfigFile);
8✔
88
        primaryConfigFile ??= Path.Join(folder, PrimaryConfigFile); // if not specified, merge & write back to the same folder
8✔
89
        return ApplyMergeOcelotJsonOption(builder, mergeTo, json, primaryConfigFile, optional, reloadOnChange);
8✔
90
    }
91

92
    private static IConfigurationBuilder ApplyMergeOcelotJsonOption(IConfigurationBuilder builder, MergeOcelotJson mergeTo, string json,
93
        string primaryConfigFile, bool? optional, bool? reloadOnChange)
94
    {
95
        return mergeTo == MergeOcelotJson.ToMemory ?
18✔
96
            builder.AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(json))) :
18✔
97
            AddOcelotJsonFile(builder, json, primaryConfigFile, optional, reloadOnChange);
18✔
98
    }
99

100
    [GeneratedRegex(@"^ocelot\.(.*?)\.json$", RegexOptions.IgnoreCase | RegexOptions.Singleline, RegexGlobal.DefaultMatchTimeoutMilliseconds, "en-US")]
101
    private static partial Regex SubConfigRegex();
102

103
    private static string GetMergedOcelotJson(string folder, IWebHostEnvironment env,
104
        FileConfiguration fileConfiguration = null, string primaryFile = null, string globalFile = null, string environmentFile = null)
105
    {
106
        // All versions of overloaded AddOcelot methods call this GetMergedOcelotJson one, so we improve Regex performance by cache increasing.
107
        // Developers can adjust the RegexGlobal value BEFORE calling AddOcelot
108
        // Developers can adjust the Regex.CacheSize value AFTER calling AddOcelot
109
        Regex.CacheSize = RegexGlobal.RegexCacheSize;
18✔
110

111
        var envName = string.IsNullOrEmpty(env?.EnvironmentName) ? "Development" : env.EnvironmentName;
18✔
112
        environmentFile ??= Path.Join(folder, string.Format(EnvironmentConfigFile, envName));
18✔
113
        var reg = SubConfigRegex();
18✔
114
        var environmentFileInfo = new FileInfo(environmentFile);
18✔
115
        var files = new DirectoryInfo(folder)
18✔
116
            .EnumerateFiles()
18✔
117
            .Where(fi => reg.IsMatch(fi.Name) &&
1,800✔
118
                !fi.Name.Equals(environmentFileInfo.Name, StringComparison.OrdinalIgnoreCase) &&
1,800✔
119
                !fi.FullName.Equals(environmentFileInfo.FullName, StringComparison.OrdinalIgnoreCase))
1,800✔
120
            .ToArray();
18✔
121

122
        fileConfiguration ??= new FileConfiguration();
18✔
123
        primaryFile ??= Path.Join(folder, PrimaryConfigFile);
18✔
124
        globalFile ??= Path.Join(folder, GlobalConfigFile);
18✔
125
        var primaryFileInfo = new FileInfo(primaryFile);
18✔
126
        var globalFileInfo = new FileInfo(globalFile);
18✔
127
        foreach (var file in files)
132✔
128
        {
129
            if (files.Length > 1 &&
48✔
130
                file.Name.Equals(primaryFileInfo.Name, StringComparison.OrdinalIgnoreCase) &&
48✔
131
                file.FullName.Equals(primaryFileInfo.FullName, StringComparison.OrdinalIgnoreCase))
48✔
132
            {
133
                continue;
134
            }
135

136
            var lines = File.ReadAllText(file.FullName);
48✔
137
            var config = JsonSerializer.Deserialize<FileConfiguration>(lines, OcelotSerializerOptions.Web);
48✔
138
            if (file.Name.Equals(globalFileInfo.Name, StringComparison.OrdinalIgnoreCase) &&
48✔
139
                file.FullName.Equals(globalFileInfo.FullName, StringComparison.OrdinalIgnoreCase))
48✔
140
            {
141
                fileConfiguration.GlobalConfiguration = config.GlobalConfiguration;
6✔
142
            }
143

144
            fileConfiguration.Aggregates.AddRange(config.Aggregates);
48✔
145
            fileConfiguration.Routes.AddRange(config.Routes);
48✔
146
        }
147

148
        return JsonSerializer.Serialize(fileConfiguration, OcelotSerializerOptions.WebWriteIndented);
18✔
149
    }
150

151
    /// <summary>
152
    /// Adds Ocelot configuration by ready configuration object and writes JSON to the primary configuration file.<br/>
153
    /// Finally, adds JSON file as configuration provider.
154
    /// </summary>
155
    /// <remarks>Use optional arguments for injections and overridings.</remarks>
156
    /// <param name="builder">Configuration builder to extend.</param>
157
    /// <param name="fileConfiguration">File configuration to add as JSON provider.</param>
158
    /// <param name="primaryConfigFile">Primary config file.</param>
159
    /// <param name="optional">The 2nd argument of the AddJsonFile.</param>
160
    /// <param name="reloadOnChange">The 3rd argument of the AddJsonFile.</param>
161
    /// <returns>An <see cref="IConfigurationBuilder"/> object.</returns>
162
    public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, FileConfiguration fileConfiguration,
163
        string primaryConfigFile = null, bool? optional = null, bool? reloadOnChange = null) // optional injections
164
    {
165
        var json = JsonSerializer.Serialize(fileConfiguration, OcelotSerializerOptions.WebWriteIndented);
1✔
166
        return AddOcelotJsonFile(builder, json, primaryConfigFile, optional, reloadOnChange);
1✔
167
    }
168

169
    /// <summary>
170
    /// Adds Ocelot configuration by ready configuration object, environment and merge option, reading the required files from the current default folder.
171
    /// </summary>
172
    /// <param name="builder">Configuration builder to extend.</param>
173
    /// <param name="fileConfiguration">File configuration to add as JSON provider.</param>
174
    /// <param name="env">Web hosting environment object.</param>
175
    /// <param name="mergeTo">Option to merge files to.</param>
176
    /// <param name="primaryConfigFile">Primary config file.</param>
177
    /// <param name="globalConfigFile">Global config file.</param>
178
    /// <param name="environmentConfigFile">Environment config file.</param>
179
    /// <param name="optional">The 2nd argument of the AddJsonFile.</param>
180
    /// <param name="reloadOnChange">The 3rd argument of the AddJsonFile.</param>
181
    /// <returns>An <see cref="IConfigurationBuilder"/> object.</returns>
182
    public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, FileConfiguration fileConfiguration, IWebHostEnvironment env, MergeOcelotJson mergeTo,
183
        string primaryConfigFile = null, string globalConfigFile = null, string environmentConfigFile = null, bool? optional = null, bool? reloadOnChange = null) // optional injections
184
    {
185
        var json = GetMergedOcelotJson(".", env, fileConfiguration, primaryConfigFile, globalConfigFile, environmentConfigFile);
10✔
186
        return ApplyMergeOcelotJsonOption(builder, mergeTo, json, primaryConfigFile, optional, reloadOnChange);
10✔
187
    }
188

189
    /// <summary>
190
    /// Adds Ocelot primary configuration file (aka ocelot.json).<br/>
191
    /// Writes JSON to the file.<br/>
192
    /// Adds the file as a JSON configuration provider via the <see cref="JsonConfigurationExtensions.AddJsonFile(IConfigurationBuilder, string, bool, bool)"/> extension.
193
    /// </summary>
194
    /// <remarks>Use optional arguments for injections and overridings.</remarks>
195
    /// <param name="builder">The builder to extend.</param>
196
    /// <param name="json">JSON data of the Ocelot configuration.</param>
197
    /// <param name="primaryFile">Primary config file.</param>
198
    /// <param name="optional">The 2nd argument of the AddJsonFile.</param>
199
    /// <param name="reloadOnChange">The 3rd argument of the AddJsonFile.</param>
200
    /// <returns>An <see cref="IConfigurationBuilder"/> object.</returns>
201
    private static IConfigurationBuilder AddOcelotJsonFile(IConfigurationBuilder builder, string json,
202
        string primaryFile = null, bool? optional = null, bool? reloadOnChange = null) // optional injections
203
    {
204
        var primary = primaryFile ?? PrimaryConfigFile;
7✔
205
        File.WriteAllText(primary, json);
7✔
206
        return builder?.AddJsonFile(primary, optional ?? false, reloadOnChange ?? false);
7✔
207
    }
208

209
    /// <summary>
210
    /// Adds Ocelot primary configuration file (aka ocelot.json) in read-only mode.
211
    /// <para>Adds the file as a JSON configuration provider via the <see cref="JsonConfigurationExtensions.AddJsonFile(IConfigurationBuilder, string, bool, bool)"/> extension.</para>
212
    /// </summary>
213
    /// <remarks>Use optional arguments for injections and overridings.</remarks>
214
    /// <param name="builder">The builder to extend.</param>
215
    /// <param name="primaryFile">Primary config file path.</param>
216
    /// <param name="optional">The 2nd argument of the AddJsonFile.</param>
217
    /// <param name="reloadOnChange">The 3rd argument of the AddJsonFile.</param>
218
    /// <returns>An <see cref="IConfigurationBuilder"/> object.</returns>
219
    public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder,
220
        string primaryFile = null, bool? optional = null, bool? reloadOnChange = null) // optional injections
221
        => builder.AddJsonFile(primaryFile ?? PrimaryConfigFile, optional ?? false, reloadOnChange ?? false);
×
222
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc