Newer
Older
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Xml.Serialization;
namespace ATXCommon.Serializables
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
{
/// <summary>
/// configuration class based on xml
/// </summary>
[Serializable]
public class ServiceConfig
{
[XmlIgnore] public string ValidationWarnings;
public ServiceConfig() {
ValidationWarnings = "";
// set values for the optional XML elements:
SmtpHost = "";
SmtpPort = 25;
SmtpUserCredential = "";
SmtpPasswortCredential = "";
EmailPrefix = "";
AdminEmailAdress = "";
AdminDebugEmailAdress = "";
GraceNotificationDelta = 720;
InterPacketGap = 0;
EnforceInheritedACLs = true;
}
#region required configuration parameters
/// <summary>
/// A human friendly name for the host, to be used in emails etc.
/// </summary>
public string HostAlias { get; set; }
/// <summary>
/// A human friendly name for the target, to be used in emails etc.
/// </summary>
public string DestinationAlias { get; set; }
/// <summary>
/// The base drive for the spooling directories (incoming and managed).
/// </summary>
public string SourceDrive { get; set; }
/// <summary>
/// The name of a directory on SourceDrive that is monitored for new files.
/// </summary>
public string IncomingDirectory { get; set; }
/// <summary>
/// The name of a marker file to be placed in all **sub**directories
/// inside the IncomingDirectory.
/// </summary>
public string MarkerFile { get; set; }
/// <summary>
/// A directory on SourceDrive to hold the three subdirectories "DONE",
/// "PROCESSING" and "UNMATCHED" used during and after transfers.
/// </summary>
public string ManagedDirectory { get; set; }
/// <summary>
/// Target path to transfer files to. Usually a UNC location.
/// </summary>
public string DestinationDirectory { get; set; }
/// <summary>
/// The name of a subdirectory in the DestinationDirectory to be used
/// to keep the temporary data of running transfers.
/// </summary>
public string TmpTransferDir { get; set; }
public string EmailFrom { get; set; }
public int ServiceTimer { get; set; }
public int MaxCpuUsage { get; set; }
public int MinAvailableMemory { get; set; }
public int AdminNotificationDelta { get; set; }
public int StorageNotificationDelta { get; set; }
/// <summary>
/// GracePeriod: number of days after data in the "DONE" location expires,
/// which will trigger a summary email to the admin address.
/// </summary>
public int GracePeriod { get; set; }
public bool SendAdminNotification { get; set; }
public bool SendTransferNotification { get; set; }
public bool Debug { get; set; }
[XmlArray]
[XmlArrayItem(ElementName = "DriveToCheck")]
public List<DriveToCheck> SpaceMonitoring { get; set; }
[XmlArray]
[XmlArrayItem(ElementName = "ProcessName")]
public List<string> BlacklistedProcesses { get; set; }
#endregion
#region optional configuration parameters
public string SmtpHost { get; set; }
public string SmtpUserCredential { get; set; }
public string SmtpPasswortCredential { get; set; }
public int SmtpPort { get; set; }
public string EmailPrefix { get; set; }
public string AdminEmailAdress { get; set; }
public string AdminDebugEmailAdress { get; set; }
public int GraceNotificationDelta { get; set; }
public int InterPacketGap { get; set; }
/// <summary>
/// EnforceInheritedACLs: whether to enforce ACL inheritance when moving files and
/// directories, see https://support.microsoft.com/en-us/help/320246 for more details.
/// </summary>
public bool EnforceInheritedACLs { get; set; }
#endregion
public static void Serialize(string file, ServiceConfig c) {
// the config is never meant to be written by us, therefore:
throw new SettingsPropertyIsReadOnlyException("The config file must not be written by the service!");
}
public static ServiceConfig Deserialize(string file) {
var xs = new XmlSerializer(typeof(ServiceConfig));
var reader = File.OpenText(file);
var config = (ServiceConfig) xs.Deserialize(reader);
reader.Close();
ValidateConfiguration(config);
return config;
}
private static void ValidateConfiguration(ServiceConfig c) {
if (string.IsNullOrEmpty(c.SourceDrive) ||
string.IsNullOrEmpty(c.IncomingDirectory) ||
string.IsNullOrEmpty(c.ManagedDirectory))
throw new ConfigurationErrorsException("mandatory parameter missing!");
if (c.SourceDrive.Substring(1) != @":\")
throw new ConfigurationErrorsException("SourceDrive must be a drive " +
@"letter followed by a colon and a backslash, e.g. 'D:\'!");
// make sure SourceDrive is a local (fixed) disk:
var driveInfo = new DriveInfo(c.SourceDrive);
if (driveInfo.DriveType != DriveType.Fixed)
throw new ConfigurationErrorsException("SourceDrive (" + c.SourceDrive +
") must be a local (fixed) drive, OS reports '" +
driveInfo.DriveType + "')!");
// spooling directories: IncomingDirectory + ManagedDirectory
if (c.IncomingDirectory.StartsWith(@"\"))
throw new ConfigurationErrorsException("IncomingDirectory must not start with a backslash!");
if (c.ManagedDirectory.StartsWith(@"\"))
throw new ConfigurationErrorsException("ManagedDirectory must not start with a backslash!");
if (!Directory.Exists(c.DestinationDirectory))
throw new ConfigurationErrorsException("can't find destination: " + c.DestinationDirectory);
var tmpTransferPath = Path.Combine(c.DestinationDirectory, c.TmpTransferDir);
if (!Directory.Exists(tmpTransferPath))
throw new ConfigurationErrorsException("temporary transfer dir doesn't exist: " + tmpTransferPath);
if (c.ServiceTimer < 1000)
throw new ConfigurationErrorsException("ServiceTimer must not be smaller than 1000 ms!");
// NON-CRITICAL stuff just adds messages to ValidationWarnings:
// DestinationDirectory
if (!c.DestinationDirectory.StartsWith(@"\\"))
c.ValidationWarnings += " - <DestinationDirectory> is not a UNC path!\n";
}
public string Summary() {
var msg =
"HostAlias: " + HostAlias + "\n" +
"SourceDrive: " + SourceDrive + "\n" +
"IncomingDirectory: " + IncomingDirectory + "\n" +
"MarkerFile: " + MarkerFile + "\n" +
"ManagedDirectory: " + ManagedDirectory + "\n" +
"GracePeriod: " + GracePeriod + "\n" +
"DestinationDirectory: " + DestinationDirectory + "\n" +
"TmpTransferDir: " + TmpTransferDir + "\n" +
"EnforceInheritedACLs: " + EnforceInheritedACLs + "\n" +
"ServiceTimer: " + ServiceTimer + "\n" +
"InterPacketGap: " + InterPacketGap + "\n" +
"MaxCpuUsage: " + MaxCpuUsage + "\n" +
"MinAvailableMemory: " + MinAvailableMemory + "\n";
foreach (var processName in BlacklistedProcesses) {
msg += "BlacklistedProcess: " + processName + "\n";
}
foreach (var driveToCheck in SpaceMonitoring) {
msg += "Drive to check free space: " + driveToCheck.DriveName +
" (threshold: " + driveToCheck.SpaceThreshold + ")" + "\n";
}
if (string.IsNullOrEmpty(SmtpHost)) {
msg += "SmtpHost: ====== Not configured, disabling email! ======" + "\n";
} else {
msg +=
"SmtpHost: " + SmtpHost + "\n" +
"EmailFrom: " + EmailFrom + "\n" +
"AdminEmailAdress: " + AdminEmailAdress + "\n" +
"AdminDebugEmailAdress: " + AdminDebugEmailAdress + "\n" +
"StorageNotificationDelta: " + StorageNotificationDelta + "\n" +
"AdminNotificationDelta: " + AdminNotificationDelta + "\n" +
"GraceNotificationDelta: " + GraceNotificationDelta + "\n";
}
return msg;
}
}
}