using System.Collections.Concurrent;
using System.ComponentModel.Composition;
using System.Diagnostics;
+using System.Diagnostics.Contracts;
using System.IO;
+using System.Net;
using System.Runtime.InteropServices;
using System.ServiceModel;
using System.ServiceModel.Description;
_statusChecker = statusChecker;
_events = events;
Settings = settings;
-
-
-
+
UsageMessage = "Using 15% of 50 GB";
StatusMessage = "In Synch";
if (_monitors.TryGetValue(accountName,out monitor))
{
//If the account is active
- if (account.IsActive)
+ if (account.IsActive)
//Start the monitor. It's OK to start an already started monitor,
//it will just ignore the call
monitor.Start();
- private Task StartMonitor(PithosMonitor monitor)
+ private Task StartMonitor(PithosMonitor monitor,int retries=0)
{
return Task.Factory.StartNew(() =>
{
try
{
Log.InfoFormat("Start Monitoring {0}", monitor.UserName);
+
monitor.Start();
}
+ catch (WebException exc)
+ {
+ if (AbandonRetry(monitor, retries))
+ return;
+
+ if (IsUnauthorized(exc))
+ {
+ var message = String.Format("API Key Expired for {0}. Starting Renewal",monitor.UserName);
+ Log.Error(message,exc);
+ TryAuthorize(monitor,retries);
+ }
+ else
+ {
+ TryLater(monitor, exc,retries);
+ }
+ }
catch (Exception exc)
{
- var message =
- String.Format("An exception occured. Can't start monitoring\nWill retry in 10 seconds");
- Task.Factory.StartNewDelayed(10000, () => StartMonitor(monitor));
- _events.Publish(new Notification {Title = "Error", Message = message, Level = TraceLevel.Error});
- Log.Error(message, exc);
+ if (AbandonRetry(monitor, retries))
+ return;
+
+ TryLater(monitor,exc,retries);
}
}
});
}
+ private bool AbandonRetry(PithosMonitor monitor, int retries)
+ {
+ if (retries > 1)
+ {
+ var message = String.Format("Monitoring of account {0} has failed too many times. Will not retry",
+ monitor.UserName);
+ _events.Publish(new Notification
+ {Title = "Account monitoring failed", Message = message, Level = TraceLevel.Error});
+ return true;
+ }
+ return false;
+ }
+
+
+ private Task TryAuthorize(PithosMonitor monitor,int retries)
+ {
+ _events.Publish(new Notification { Title = "Authorization failed", Message = "Your API Key has probably expired. You will be directed to a page where you can renew it", Level = TraceLevel.Error });
+
+ var authorize= PithosAccount.RetrieveCredentialsAsync(Settings.PithosSite);
+
+ return authorize.ContinueWith(t =>
+ {
+ if (t.IsFaulted)
+ {
+ string message = String.Format("API Key retrieval for {0} failed", monitor.UserName);
+ Log.Error(message,t.Exception.InnerException);
+ _events.Publish(new Notification { Title = "Authorization failed", Message = message, Level = TraceLevel.Error });
+ return;
+ }
+ var credentials = t.Result;
+ var account =Settings.Accounts.FirstOrDefault(act => act.AccountName == credentials.UserName);
+ account.ApiKey = credentials.Password;
+ monitor.ApiKey = credentials.Password;
+ Task.Factory.StartNewDelayed(10000, () => StartMonitor(monitor,retries+1));
+ });
+ }
+
+ private static bool IsUnauthorized(WebException exc)
+ {
+ if (exc==null)
+ throw new ArgumentNullException("exc");
+ Contract.EndContractBlock();
+
+ var response = exc.Response as HttpWebResponse;
+ if (response == null)
+ return false;
+ return (response.StatusCode == HttpStatusCode.Unauthorized);
+ }
+
+ private void TryLater(PithosMonitor monitor, Exception exc,int retries)
+ {
+ var message = String.Format("An exception occured. Can't start monitoring\nWill retry in 10 seconds");
+ Task.Factory.StartNewDelayed(10000, () => StartMonitor(monitor,retries+1));
+ _events.Publish(new Notification
+ {Title = "Error", Message = message, Level = TraceLevel.Error});
+ Log.Error(message, exc);
+ }
+
public void NotifyChange(string status, TraceLevel level=TraceLevel.Info)
{