Projekt

Obecné

Profil

Stáhnout (4.85 KB) Statistiky
| Větev: | Tag: | Revize:
1
using LDClient.utils;
2

    
3
namespace LDClient.detection; 
4

    
5
/// <summary>
6
/// This abstract class implements the common functions of the IInfoFetcher interface
7
/// which defines the functionality of an info fetcher.
8
/// </summary>
9
public abstract class AInfoFetcher : IInfoFetcher {
10

    
11
    /// <summary>
12
    /// Default value of a serial number (undefined).
13
    /// </summary>
14
    private const string UndefinedSerialNumber = "number";
15

    
16
    /// <summary>
17
    /// Returns the head serial number of the debugger.
18
    /// </summary>
19
    public string HeadSerialNumber { get; set; } = UndefinedSerialNumber;
20

    
21
    /// <summary>
22
    /// Returns the body serial number of the debugger.
23
    /// </summary>
24
    public string BodySerialNumber { get; set; } = UndefinedSerialNumber;
25

    
26
    /// <summary>
27
    /// Instance of FileUtils which encapsulates common functionality
28
    /// when it comes to dealing with files (limited by the needs of this application).
29
    /// </summary>
30
    public IFileUtils FileUtils;
31

    
32
    /// <summary>
33
    /// Maximum number of attempts to locate and parse the .txt file.
34
    /// </summary>
35
    protected readonly uint _maxAttempts;
36

    
37
    /// <summary>
38
    /// Period (how often) the application tries to locate and parse the .txt file.
39
    /// </summary>
40
    protected readonly uint _waitPeriodMs;
41

    
42
    /// <summary>
43
    /// Path to the .txt file which is generated from the debugger.
44
    /// </summary>
45
    protected readonly string _infoFilePath;
46

    
47
    /// <summary>
48
    /// Abstract constructor of this class 
49
    /// </summary>
50
    /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param>
51
    /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param>
52
    /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param>
53

    
54
    protected AInfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath) {
55
        this.FileUtils = new FileUtils();
56
        this._maxAttempts = maxAttempts;
57
        this._waitPeriodMs = waitPeriodMs;
58
        this._infoFilePath = infoFilePath;
59
    }
60

    
61
    /// <summary>
62
    /// Abstract definition of the data fetching function
63
    /// Function should send the commands to the debugger.
64
    /// </summary>
65
    /// <returns>true on success</returns>
66
    protected abstract bool FetchData();
67

    
68
    /// <summary>
69
    /// Fetches data from the debugger. It sends the commands defined
70
    /// in the appsettings.json file to the debugger and tries to
71
    /// parse the .txt (contains the serial numbers).
72
    /// </summary>
73
    /// <returns>True, if data was fetched successfully. False otherwise.</returns>
74
    public async Task<bool> FetchDataAsync() {
75
        Program.DefaultLogger.Info("Fetching data from the debugger.");
76
        // Send the commands to the debugger.
77
        var success = FetchData();
78

    
79
        // Make sure that all commands were sent and executed successfully.
80
        if (!success) {
81
            Program.DefaultLogger.Error("Failed to fetch data from the debugger.");
82
            return false;
83
        }
84
        // Periodically try to parse the .txt file. 
85
        for (var i = 0; i < _maxAttempts; i++) {
86
            Program.DefaultLogger.Info($"{i}. attempt to parse the info file.");
87
            // Try to parse .txt file.
88
            if (RetrieveDebuggerInfo(_infoFilePath)) {
89
                Program.DefaultLogger.Info($"Info file has been parsed successfully.");
90
                return true;
91
            }
92
            // Wait for a specified number of milliseconds.
93
            await Task.Delay((int)_waitPeriodMs);
94
        }
95
        Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created.");
96
        return false;
97
    }
98

    
99
    /// <summary>
100
    /// Tries to retrieve information from the debugger.
101
    /// </summary>
102
    /// <param name="filePath">path to the .txt file that contains all information</param>
103
    /// <returns>True if the information was retrieved successfully. False, otherwise.</returns>
104

    
105
    protected bool RetrieveDebuggerInfo(string filePath) {
106
        try {
107
            // Read the content of the .txt file.
108
            var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n");
109

    
110
            // Parse it (try to find the serial numbers)
111
            var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent);
112

    
113
            // Store the serial numbers into class variables (properties)
114
            HeadSerialNumber = headSerialNumber;
115
            BodySerialNumber = bodySerialNumber;
116

    
117
            // Finally, delete the file.
118
            File.Delete(filePath);
119
        } catch (Exception exception) {
120
            Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}");
121
            return false;
122
        }
123
        return true;
124
    }
125
}
(1-1/10)