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

ThreeMammals / Ocelot / 20926763792

12 Jan 2026 04:23PM UTC coverage: 93.397% (-0.1%) from 93.503%
20926763792

Pull #1183

github

web-flow
Merge 94e251d0b into 9fc4e78d3
Pull Request #1183: #651 Merge custom JSON properties across multiple `ocelot.X.json` configuration files using Newtonsoft's `JToken` merge functionality

6549 of 7012 relevant lines covered (93.4%)

2996.75 hits per line

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

84.78
src/Ocelot/Configuration/Repository/FileConfigurationPoller.cs
1
using Microsoft.Extensions.Hosting;
2
using Newtonsoft.Json;
3
using Ocelot.Configuration.Creator;
4
using Ocelot.Configuration.File;
5
using Ocelot.Logging;
6
using Ocelot.Infrastructure.Extensions;
7

8
namespace Ocelot.Configuration.Repository;
9

10
public sealed class FileConfigurationPoller : IHostedService, IDisposable
11
{
12
    private readonly IOcelotLogger _logger;
13
    private readonly IFileConfigurationRepository _repo;
14
    private string _previousAsJson;
15
    private Timer _timer;
16
    private bool _polling;
17
    private readonly IFileConfigurationPollerOptions _options;
18
    private readonly IInternalConfigurationRepository _internalConfigRepo;
19
    private readonly IInternalConfigurationCreator _internalConfigCreator;
20

21
    public FileConfigurationPoller(
5✔
22
        IOcelotLoggerFactory factory,
5✔
23
        IFileConfigurationRepository repo,
5✔
24
        IFileConfigurationPollerOptions options,
5✔
25
        IInternalConfigurationRepository internalConfigRepo,
5✔
26
        IInternalConfigurationCreator internalConfigCreator)
5✔
27
    {
28
        _internalConfigRepo = internalConfigRepo;
5✔
29
        _internalConfigCreator = internalConfigCreator;
5✔
30
        _options = options;
5✔
31
        _logger = factory.CreateLogger<FileConfigurationPoller>();
5✔
32
        _repo = repo;
5✔
33
        _previousAsJson = string.Empty;
5✔
34
    }
5✔
35

36
    public Task StartAsync(CancellationToken cancellationToken)
37
    {
38
        _logger.LogInformation($"{nameof(FileConfigurationPoller)} is starting.");
4✔
39

40
        _timer = new Timer(async x =>
4✔
41
        {
4✔
42
            if (_polling)
3✔
43
            {
4✔
44
                return;
×
45
            }
4✔
46

4✔
47
            _polling = true;
3✔
48
            await Poll();
3✔
49
            _polling = false;
3✔
50
        }, null, _options.Delay, _options.Delay);
7✔
51

52
        return Task.CompletedTask;
4✔
53
    }
54

55
    public Task StopAsync(CancellationToken cancellationToken)
56
    {
57
        _logger.LogInformation($"{nameof(FileConfigurationPoller)} is stopping.");
×
58

59
        _timer?.Change(Timeout.Infinite, 0);
×
60

61
        return Task.CompletedTask;
×
62
    }
63

64
    private async Task Poll()
65
    {
66
        _logger.LogInformation($"Started {nameof(Poll)}ing");
3✔
67
        try
68
        {
69
            var fileConfig = await _repo.GetAsync();
3✔
70
            var asJson = ToJson(fileConfig);
3✔
71
            if (asJson != _previousAsJson)
3✔
72
            {
73
                var config = await _internalConfigCreator.Create(fileConfig);
3✔
74
                if (!config.IsError)
3✔
75
                {
76
                    _internalConfigRepo.AddOrReplace(config.Data);
3✔
77
                }
78

79
                _previousAsJson = asJson;
3✔
80
            }
81
        }
3✔
82
        catch (Exception ex)
×
83
        {
84
            _logger.LogWarning($"Error getting file config! Errors are:{Environment.NewLine}{ex.AllMessages}");
×
85
        }
×
86
        finally
87
        {
88
            _logger.LogInformation($"Finished {nameof(Poll)}ing");
3✔
89
        }
90
    }
3✔
91

92
    /// <summary>
93
    /// We could do object comparison here but performance isnt really a problem. This might be an issue one day.
94
    /// </summary>
95
    /// <returns>A <see langword="string"/> with current hash of the config.</returns>
96
    private static string ToJson(FileConfiguration config) => JsonConvert.SerializeObject(config);
3✔
97

98
    public void Dispose()
99
    {
100
        _timer?.Dispose();
6✔
101
    }
4✔
102
}
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