[Nmailserver-commits] SF.net SVN: nmailserver: [227] NMail/trunk
Brought to you by:
dframpton-oss,
tmyroadctfig
|
From: <tmy...@us...> - 2007-06-16 15:02:33
|
Revision: 227
http://svn.sourceforge.net/nmailserver/?rev=227&view=rev
Author: tmyroadctfig
Date: 2007-06-16 08:02:35 -0700 (Sat, 16 Jun 2007)
Log Message:
-----------
Work on the survey service.
Modified Paths:
--------------
NMail/trunk/NMail.Server/NMailServer.cs
NMail/trunk/NMail.Server.Console/NMail.Server.Console.csproj
NMail/trunk/NMail.SurveyService/NMail.SurveyService.csproj
NMail/trunk/NMail.SurveyService/SurveyEnvironment.cs
NMail/trunk/NMail.SurveyService/SurveyInformation.cs
NMail/trunk/NMail.SurveyService/SurveyService.cs
Added Paths:
-----------
NMail/trunk/NMail.SurveyService/SurveyNMail.cs
Modified: NMail/trunk/NMail.Server/NMailServer.cs
===================================================================
--- NMail/trunk/NMail.Server/NMailServer.cs 2007-06-16 15:01:45 UTC (rev 226)
+++ NMail/trunk/NMail.Server/NMailServer.cs 2007-06-16 15:02:35 UTC (rev 227)
@@ -325,7 +325,7 @@
/// <returns>The install location or null if an error occurs.</returns>
public static string GetInstallDirectory() {
string installDirectory = null;
- RegistryKey nmailServerKey = Registry.LocalMachine.OpenSubKey(@"Software\NMail\NMail Server 1.0", false);
+ RegistryKey nmailServerKey = Registry.LocalMachine.OpenSubKey(NMailRegistryKey, false);
if (nmailServerKey != null) {
installDirectory = nmailServerKey.GetValue("InstallDirectory") as string;
@@ -342,5 +342,10 @@
log.Debug("Installation directory: " + installDirectory);
return installDirectory;
}
+
+ /// <summary>
+ /// The base registry key for the NMail server.
+ /// </summary>
+ public const string NMailRegistryKey = @"Software\NMail\NMail Server 1.0";
}
}
Modified: NMail/trunk/NMail.Server.Console/NMail.Server.Console.csproj
===================================================================
--- NMail/trunk/NMail.Server.Console/NMail.Server.Console.csproj 2007-06-16 15:01:45 UTC (rev 226)
+++ NMail/trunk/NMail.Server.Console/NMail.Server.Console.csproj 2007-06-16 15:02:35 UTC (rev 227)
@@ -160,6 +160,10 @@
<Project>{81EA6856-1AA7-4278-B0CC-1F851B987DA0}</Project>
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
</ProjectReference>
+ <ProjectReference Include="..\NMail.SurveyService\NMail.SurveyService.csproj">
+ <Project>{11BFAF65-FA51-4245-8747-F4BA39D10FA3}</Project>
+ <Name>NMail.SurveyService</Name>
+ </ProjectReference>
<ProjectReference Include="..\NMail\NMail.csproj">
<Name>NMail</Name>
<Project>{5A5A5012-B157-49B1-A35F-67EC9680112A}</Project>
Modified: NMail/trunk/NMail.SurveyService/NMail.SurveyService.csproj
===================================================================
--- NMail/trunk/NMail.SurveyService/NMail.SurveyService.csproj 2007-06-16 15:01:45 UTC (rev 226)
+++ NMail/trunk/NMail.SurveyService/NMail.SurveyService.csproj 2007-06-16 15:02:35 UTC (rev 227)
@@ -29,16 +29,22 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
+ <Reference Include="System.configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="SurveyEnvironment.cs" />
<Compile Include="SurveyInformation.cs" />
+ <Compile Include="SurveyNMail.cs" />
<Compile Include="SurveyService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\NMail.Server\NMail.Server.csproj">
+ <Project>{45123319-D913-4A92-BB67-C2C9E1A22A17}</Project>
+ <Name>NMail.Server</Name>
+ </ProjectReference>
<ProjectReference Include="..\NMail\NMail.csproj">
<Project>{5A5A5012-B157-49B1-A35F-67EC9680112A}</Project>
<Name>NMail</Name>
Modified: NMail/trunk/NMail.SurveyService/SurveyEnvironment.cs
===================================================================
--- NMail/trunk/NMail.SurveyService/SurveyEnvironment.cs 2007-06-16 15:01:45 UTC (rev 226)
+++ NMail/trunk/NMail.SurveyService/SurveyEnvironment.cs 2007-06-16 15:02:35 UTC (rev 227)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Collections.Generic;
using System.Text;
Modified: NMail/trunk/NMail.SurveyService/SurveyInformation.cs
===================================================================
--- NMail/trunk/NMail.SurveyService/SurveyInformation.cs 2007-06-16 15:01:45 UTC (rev 226)
+++ NMail/trunk/NMail.SurveyService/SurveyInformation.cs 2007-06-16 15:02:35 UTC (rev 227)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Collections.Generic;
using System.Text;
@@ -17,5 +34,15 @@
get { return environment; }
set { environment = value; }
}
+
+ private SurveyNMail nmail;
+
+ /// <summary>
+ /// The NMail details.
+ /// </summary>
+ public SurveyNMail NMail {
+ get { return nmail; }
+ set { nmail = value; }
+ }
}
}
Added: NMail/trunk/NMail.SurveyService/SurveyNMail.cs
===================================================================
--- NMail/trunk/NMail.SurveyService/SurveyNMail.cs (rev 0)
+++ NMail/trunk/NMail.SurveyService/SurveyNMail.cs 2007-06-16 15:02:35 UTC (rev 227)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+
+using NMail.Configuration;
+
+namespace NMail.SurveyService {
+ /// <summary>
+ /// The NMail survey details.
+ /// </summary>
+ public class SurveyNMail {
+
+ private Version nmailVersion = Assembly.GetAssembly(typeof(NMailConfiguration)).GetName().Version;
+
+ /// <summary>
+ /// The version of the NMail library.
+ /// </summary>
+ public Version NMailVersion {
+ get { return nmailVersion; }
+ set { nmailVersion = value; }
+ }
+
+ private Version executingAssemblyVersion = Assembly.GetExecutingAssembly().GetName().Version;
+
+ /// <summary>
+ /// The version of the executing assembly.
+ /// </summary>
+ public Version ExecutingAssemblyVersion {
+ get { return executingAssemblyVersion; }
+ set { executingAssemblyVersion = value; }
+ }
+ }
+}
Modified: NMail/trunk/NMail.SurveyService/SurveyService.cs
===================================================================
--- NMail/trunk/NMail.SurveyService/SurveyService.cs 2007-06-16 15:01:45 UTC (rev 226)
+++ NMail/trunk/NMail.SurveyService/SurveyService.cs 2007-06-16 15:02:35 UTC (rev 227)
@@ -1,92 +1,314 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Collections.Generic;
using System.IO;
+using System.Net;
using System.Text;
+using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.Win32;
+using NMail.Configuration;
+using NMail.DataTypes;
using NMail.DataTypes.Service;
+using NMail.DataTypes.Message;
+using NMail.Server;
namespace NMail.SurveyService {
/// <summary>
/// A service for periodically surveying the server details and reporting back usage stats.
/// </summary>
public class SurveyService : IService {
-
/// <summary>
/// Creates a new instance of the service.
/// </summary>
- public SurveyService() {
- }
+ public SurveyService() { }
- protected XmlDocument GatherData() {
- //log.Debug("NMail Console Server version: [" + Assembly.GetExecutingAssembly().GetName().Version + "]");
- // log.Debug("NMail Library version: [" + Assembly.GetAssembly(typeof(NMailConfiguration)).GetName().Version + "]");
-
+ /// <summary>
+ /// Gets the current survey information.
+ /// </summary>
+ /// <returns>An XML documeent containing the suvery details.</returns>
+ protected string GatherData() {
MemoryStream ms = new MemoryStream();
XmlSerializer serializer = new XmlSerializer(typeof(SurveyInformation));
serializer.Serialize(ms, new SurveyInformation());
- XmlDocument result = new XmlDocument();
- result.LoadXml(Encoding.Unicode.GetString(ms.ToArray()));
- return result;
+ return Encoding.Unicode.GetString(ms.ToArray());
}
+ /// <summary>
+ /// Gets the last date/time the survey information was sent.
+ /// </summary>
+ /// <returns>The datetime or null.</returns>
+ protected DateTime? GetLastSurveyTimestamp() {
+ RegistryKey nmailServerKey = Registry.LocalMachine.OpenSubKey(NMailServer.NMailRegistryKey, false);
+
+ if (nmailServerKey != null) {
+ string sentString = nmailServerKey.GetValue("LastSuveryTimestamp") as string;
+
+ DateTime sentTimestamp;
+ if (DateTime.TryParse(sentString, out sentTimestamp)) {
+ return sentTimestamp;
+ }
+ }
+
+ // Never sent details
+ return null;
+ }
+
+ /// <summary>
+ /// Sets the last date/time the survey information was sent.
+ /// </summary>
+ protected void SetLastSurveyTimestamp() {
+ RegistryKey nmailServerKey = Registry.LocalMachine.OpenSubKey(NMailServer.NMailRegistryKey, false);
+
+ if (nmailServerKey == null) {
+ nmailServerKey = Registry.LocalMachine.CreateSubKey(NMailServer.NMailRegistryKey);
+ }
+
+ nmailServerKey.SetValue("LastSuveryTimestamp", DateTime.Now.ToString());
+ }
+
+ protected TimeSpan GetWaitPeriod() {
+ DateTime? lastSent = GetLastSurveyTimestamp();
+
+ if (lastSent.HasValue) {
+ // TODO: obtain period from config file
+ return DateTime.Now - (lastSent.Value + TimeSpan.FromDays(30));
+ }
+
+ return TimeSpan.Zero;
+ }
+
+ protected void SendSurveyInformation() {
+ Message message = new Message();
+ message.Subject = "[NMail Survey Information]";
+ message.From = "NMail survey service";
+ message.SetSimpleBody(GatherData());
+
+ SmtpMessage smtpMessage = new SmtpMessage();
+ smtpMessage.Message = message;
+ smtpMessage.SourceAddress = IPAddress.Loopback;
+ smtpMessage.ReportedHost = IPAddress.Loopback;
+ smtpMessage.Sender = new EmailAddress(null, null);
+ smtpMessage.AddRecipient(new EmailAddress("tmy...@us..."));
+
+ NMailConfiguration.Current.Router.SpoolMessage(smtpMessage);
+ }
+
+ /// <summary>
+ /// An event to signal a quit.
+ /// </summary>
+ ManualResetEvent quitEvent = new ManualResetEvent(true);
+
+ /// <summary>
+ /// A flag indicating if the service is running.
+ /// </summary>
+ bool running = false;
+
+ protected void WaitForSurvey(object unused) {
+ // Flag that we're running
+ lock (this) {
+ running = true;
+ }
+
+ while (this.running) {
+ // Get the period to wait
+ TimeSpan waitPeriod = GetWaitPeriod();
+
+ bool quitSignalled = this.quitEvent.WaitOne((int) waitPeriod.TotalMilliseconds, true);
+
+ if (!quitSignalled) {
+ try {
+ // Send the survey information
+ SendSurveyInformation();
+
+ } catch (Exception ex) {
+ // Ignore
+ }
+
+ // Update the last sent time
+ SetLastSurveyTimestamp();
+
+ } else {
+ // Flag that we've quit
+ lock (this) {
+ running = false;
+ }
+ }
+ }
+ }
+
#region IService Members
+ /// <summary>
+ /// Initialise the service. All services are <b>Init</b>ialised before any services are <b>Start</b>ed.
+ /// </summary>
+ public void Init() { }
- public void Init() {}
-
+ /// <summary>
+ /// Start the service.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// If Start() is called before Init().
+ /// </exception>
public void Start() {
- XmlDocument doc = GatherData();
+ lock (this) {
+ if (!this.Running) {
+ this.quitEvent.Reset();
+ ThreadPool.QueueUserWorkItem(new WaitCallback(WaitForSurvey));
+ if (this.started != null) {
+ this.started(this, new EventArgs());
+ }
+ }
+ }
}
+ /// <summary>
+ /// Stop the service. It should be possible to resume the service with a subsequent call to Init and Start.
+ /// If you take too long (arbitrary) to Stop gracefully, then you may get an additional call to Stop
+ /// immediately on another thread, you must be able to handle this.
+ /// </summary>
public void Stop(bool runCurrentToCompletion) {
- throw new Exception("The method or operation is not implemented.");
+ lock (this) {
+ if (this.Running) {
+ this.quitEvent.Set();
+
+ if (this.stopped != null) {
+ this.stopped(this, new EventArgs());
+ }
+ }
+ }
}
+ /// <summary>
+ /// Returns true if this service supports pausing processing without performing a complete shutdown.
+ /// </summary>
public bool SupportsPause {
get { return false; }
}
+ /// <summary>
+ /// Pauses the service from processing but doesn't require a complete shutdown. E.g. a service may stop
+ /// accepting new connections or stop processing its work queue.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// If this service doesn't support pausing.
+ /// </exception>
public void Pause() {
- throw new InvalidOperationException("The method or operation is not implemented.");
+ throw new InvalidOperationException("Can't pause this service.");
}
+ /// <summary>
+ /// Continues processing following a pause command.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// If this service doesn't support pausing.
+ /// </exception>
public void Continue() {
- throw new InvalidOperationException("The method or operation is not implemented.");
+ throw new InvalidOperationException("Can't resume this service.");
}
+ /// <summary>
+ /// Reload the service configuration. This may recycle the service instance by stopping and discarding
+ /// the current IService and returning a new one.
+ /// </summary>
+ /// <remarks>
+ /// The service is <b>running</b> when this is called.
+ /// </remarks>
+ /// <exception cref="System.InvalidOperationException">
+ /// If this service is not running when this is called.
+ /// </exception>
public IService ReloadConfiguration() {
- throw new InvalidOperationException("The method or operation is not implemented.");
+ throw new InvalidOperationException("Can't reload configuration for this service.");
}
+ /// <summary>
+ /// Does this service support reloading configuration parameters on the fly?
+ /// </summary>
public bool AllowsReloadConfiguration {
get { return false; }
}
+ /// <summary>
+ /// Is the service currently running?
+ /// </summary>
public bool Running {
- get { throw new Exception("The method or operation is not implemented."); }
+ get { return this.running; }
}
+ /// <summary>
+ /// The name of this service.
+ /// </summary>
public string Name {
get { return "Survey Service"; }
}
+ /// <summary>
+ /// The description of this service.
+ /// </summary>
public string Description {
get { return "Periodically reports survey and usage information."; }
}
+ /// <summary>
+ /// A URL for details on this service.
+ /// </summary>
public Uri SupportUrl {
get { return new Uri("http://nmailserver.sf.net/support/services/survey"); }
}
- public event EventHandler Started;
+ private event EventHandler started;
- public event EventHandler Stopped;
+ /// <summary>
+ /// The event triggered when the service has been started.
+ /// </summary>
+ /// <remarks>
+ /// Running should return true when this event is received.
+ /// </remarks>
+ public event EventHandler Started {
+ add {
+ this.started += value;
+ }
+ remove {
+ this.started -= value;
+ }
+ }
+ private event EventHandler stopped;
+
+ /// <summary>
+ /// The event triggered when the sevice has been stopped.
+ /// </summary>
+ /// <remarks>
+ /// Running should return false when this event is received.
+ /// </remarks>
+ public event EventHandler Stopped {
+ add {
+ this.stopped += value;
+ }
+ remove {
+ this.stopped -= value;
+ }
+ }
#endregion
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|