-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathMqttConnectionSettings.cs
More file actions
205 lines (176 loc) · 7.71 KB
/
MqttConnectionSettings.cs
File metadata and controls
205 lines (176 loc) · 7.71 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
using System.Diagnostics;
using System.Text;
namespace MQTTnet.Client.Extensions;
public enum AuthType
{
X509,
Basic
}
public class MqttConnectionSettings
{
private const int Default_KeepAliveInSeconds = 30;
private const string Default_CleanSession = "true";
private const int Default_TcpPort = 8883;
private const string Default_UseTls = "true";
private const string Default_DisableCrl = "false";
public string HostName { get; }
public string? ClientId { get; set; }
public string? CertFile { get; set; }
public string? KeyFile { get; set; }
public string? KeyFilePassword { get; set; }
public AuthType Auth
{
get => !string.IsNullOrEmpty(CertFile) ? AuthType.X509 : AuthType.Basic;
}
public string? Username { get; set; }
public string? Password { get; set; }
public int KeepAliveInSeconds { get; set; }
public bool CleanSession { get; set; }
public int TcpPort { get; set; }
public bool UseTls { get; set; }
public string? CaFile { get; set; }
public bool DisableCrl { get; set; }
public MqttConnectionSettings(string hostname)
{
HostName = hostname;
TcpPort = Default_TcpPort;
KeepAliveInSeconds = Default_KeepAliveInSeconds;
UseTls = Default_UseTls == "true";
DisableCrl = Default_DisableCrl == "true";
CleanSession = Default_CleanSession == "true";
}
public static MqttConnectionSettings FromConnectionString(string cs) => ParseConnectionString(cs);
public static MqttConnectionSettings CreateFromEnvVars(string? envFile = "")
{
if (string.IsNullOrEmpty(envFile))
{
envFile = ".env";
}
if (File.Exists(envFile))
{
Trace.TraceInformation("Loading environment variables from {envFile}" + new FileInfo(envFile).FullName);
foreach (string line in File.ReadAllLines(envFile))
{
int index = line.IndexOf('=');
if (index < 0)
{
continue;
}
string key = line[..index].Trim();
string value = line[(index + 1)..].Trim();
if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(key))
{
continue;
}
Environment.SetEnvironmentVariable(key, value);
}
}
else
{
Trace.TraceWarning($"EnvFile Not found in path {new DirectoryInfo(".").FullName} {envFile}");
}
static string ToUpperCaseFromPascalCase(string pascal) =>
string.Concat(pascal.Select(x => Char.IsUpper(x) ? "_" + x : x.ToString())).ToUpper().TrimStart('_');
static string Env(string name) =>
Environment.GetEnvironmentVariable("MQTT_" + ToUpperCaseFromPascalCase(name)) ?? string.Empty;
string hostname = Env(nameof(HostName));
ArgumentException.ThrowIfNullOrEmpty(hostname, nameof(hostname));
return new MqttConnectionSettings(hostname)
{
ClientId = Env(nameof(ClientId)),
CertFile = Env(nameof(CertFile)),
KeyFile = Env(nameof(KeyFile)),
Username = Env(nameof(Username)),
Password = Env(nameof(Password)),
KeepAliveInSeconds = string.IsNullOrEmpty(Env(nameof(KeepAliveInSeconds))) ? Default_KeepAliveInSeconds : CheckForValidIntegerInput(nameof(KeepAliveInSeconds), Env(nameof(KeepAliveInSeconds))),
CleanSession = Env(nameof(CleanSession)) == "true",
TcpPort = string.IsNullOrEmpty(Env(nameof(TcpPort))) ? Default_TcpPort : CheckForValidIntegerInput(nameof(TcpPort), Env(nameof(TcpPort))),
UseTls = string.IsNullOrEmpty(Env(nameof(UseTls))) ? true : CheckForValidBooleanInput(nameof(UseTls), Env(nameof(UseTls))),
CaFile = Env(nameof(CaFile)),
DisableCrl = Env(nameof(DisableCrl)) == "true",
KeyFilePassword = Env(nameof(KeyFilePassword)),
};
}
private static string GetStringValue(IDictionary<string, string> dict, string propertyName, string defaultValue = "")
{
string result = defaultValue;
if (dict.TryGetValue(propertyName, out string? value))
{
result = value;
}
return result;
}
private static int GetPositiveIntValueOrDefault(IDictionary<string, string> dict, string propertyName, int defaultValue)
{
int result = defaultValue;
if (dict.TryGetValue(propertyName, out string? stringValue))
{
if (int.TryParse(stringValue, out int intValue))
{
result = intValue;
}
}
return result;
}
private static MqttConnectionSettings ParseConnectionString(string connectionString)
{
IDictionary<string, string> map = connectionString.ToDictionary(';', '=');
string hostName = GetStringValue(map, nameof(HostName));
ArgumentNullException.ThrowIfNull(hostName, nameof(hostName));
MqttConnectionSettings cs = new(hostName)
{
ClientId = GetStringValue(map, nameof(ClientId)),
KeyFile = GetStringValue(map, nameof(KeyFile)),
CertFile = GetStringValue(map, nameof(CertFile)),
Username = GetStringValue(map, nameof(Username)),
Password = GetStringValue(map, nameof(Password)),
KeepAliveInSeconds = GetPositiveIntValueOrDefault(map, nameof(KeepAliveInSeconds), Default_KeepAliveInSeconds),
CleanSession = GetStringValue(map, nameof(CleanSession), Default_CleanSession) == "true",
TcpPort = GetPositiveIntValueOrDefault(map, nameof(TcpPort), Default_TcpPort),
UseTls = GetStringValue(map, nameof(UseTls), Default_UseTls) == "true",
CaFile = GetStringValue(map, nameof(CaFile)),
DisableCrl = GetStringValue(map, nameof(DisableCrl), Default_DisableCrl) == "true"
};
return cs;
}
private static int CheckForValidIntegerInput(string envVarName, string envVarValue)
{
if (int.TryParse(envVarValue, out var result))
{
return result;
}
throw new ArgumentException($"An environment variable's type was specified incorrectly: {envVarName}={envVarValue}. Expecting an integer value.");
}
private static bool CheckForValidBooleanInput(string envVarName, string envVarValue)
{
if (bool.TryParse(envVarValue, out var result))
{
return result;
}
throw new ArgumentException($"An environment variable's type was specified incorrectly: {envVarName}={envVarValue}. Expecting a boolean value.");
}
private static void AppendIfNotEmpty(StringBuilder sb, string name, string val)
{
if (!string.IsNullOrEmpty(val))
{
sb.Append($"{name}={val};");
}
}
public override string ToString()
{
StringBuilder result = new ();
AppendIfNotEmpty(result, nameof(HostName), HostName!);
AppendIfNotEmpty(result, nameof(TcpPort), TcpPort.ToString());
AppendIfNotEmpty(result, nameof(Username), Username!);
AppendIfNotEmpty(result, nameof(CleanSession), CleanSession.ToString());
AppendIfNotEmpty(result, nameof(KeepAliveInSeconds), KeepAliveInSeconds.ToString());
AppendIfNotEmpty(result, nameof(CertFile), CertFile!);
AppendIfNotEmpty(result, nameof(KeyFile), KeyFile!);
AppendIfNotEmpty(result, nameof(CaFile), CaFile!);
AppendIfNotEmpty(result, nameof(ClientId), ClientId!);
AppendIfNotEmpty(result, nameof(UseTls), UseTls.ToString());
AppendIfNotEmpty(result, nameof(Auth), Auth!.ToString());
result.Remove(result.Length - 1, 1);
return result.ToString();
}
}