Logging changes, first changes to multi account support
authorPanagiotis Kanavos <pkanavos@gmail.com>
Fri, 14 Oct 2011 14:12:56 +0000 (17:12 +0300)
committerPanagiotis Kanavos <pkanavos@gmail.com>
Fri, 14 Oct 2011 14:12:56 +0000 (17:12 +0300)
27 files changed:
trunk/Pithos.Client.WPF/AppBootstrapper.cs
trunk/Pithos.Client.WPF/Pithos.Client.WPF.csproj
trunk/Pithos.Client.WPF/PithosAccount.cs
trunk/Pithos.Client.WPF/PreferencesView.xaml
trunk/Pithos.Client.WPF/PreferencesView.xaml.cs
trunk/Pithos.Client.WPF/PreferencesViewModel.cs
trunk/Pithos.Client.WPF/Wpf32Window.cs [new file with mode: 0644]
trunk/Pithos.Client.WPF/app.config
trunk/Pithos.Core.Test/MockStatusKeeper.cs
trunk/Pithos.Core.Test/Pithos.Core.Test.csproj
trunk/Pithos.Core.Test/StatusCheckerTest.cs
trunk/Pithos.Core/Agents/CloudTransferAction.cs
trunk/Pithos.Core/Agents/FileAgent.cs
trunk/Pithos.Core/Agents/NetworkAgent.cs
trunk/Pithos.Core/Agents/StatusAgent.cs
trunk/Pithos.Core/Agents/WorkflowAgent.cs
trunk/Pithos.Core/FileState.cs
trunk/Pithos.Core/IStatusKeeper.cs
trunk/Pithos.Core/PithosMonitor.cs
trunk/Pithos.Network/CloudFilesClient.cs
trunk/Pithos.Network/Pithos.Network.csproj
trunk/Pithos.Network/RestClient.cs
trunk/Pithos.ShellExtensions/IoC.cs
trunk/Pithos.ShellExtensions/Menus/FileContextMenu.cs
trunk/Pithos.ShellExtensions/Overlays/IconOverlayBase.cs
trunk/Pithos.ShellExtensions/ShellSettings.cs
trunk/Pithos.ShellExtensions/ShellStatusChecker.cs

index 5f53086..b4c61a4 100644 (file)
@@ -26,23 +26,11 @@ namespace Pithos.Client.WPF
 
            public AppBootstrapper()
            {
-               ConfigureLogging();
+            log4net.Config.XmlConfigurator.Configure();
 
             LogManager.GetLog = type => new log4netLogger(type);
            }
 
-        private static void ConfigureLogging()
-        {
-            var patternLayout = new PatternLayout();
-            patternLayout.ConversionPattern = "%logger (%property{myContext}) [%level]- %message%newline";
-            patternLayout.ActivateOptions();
-            var appender = new TraceAppender { Layout = patternLayout };
-            appender.AddFilter(new LevelRangeFilter{LevelMin=log4net.Core.Level.Info,LevelMax=log4net.Core.Level.Fatal});
-            appender.ActivateOptions();
-            
-            BasicConfigurator.Configure(appender);            
-        }
-
                /// <summary>
                /// By default, we are configured to use MEF
                /// </summary>
@@ -57,9 +45,6 @@ namespace Pithos.Client.WPF
                 catalog.Catalogs.Add(new AssemblyCatalog(type.Assembly));
             }
 
-                      
-
-
                        container = new CompositionContainer(catalog);
 
                        var batch = new CompositionBatch();
@@ -70,10 +55,6 @@ namespace Pithos.Client.WPF
                    batch.AddExportedValue(catalog);
 
 
-
-
-
-
                        container.Compose(batch);
                }
 
index 32fa97a..43dc670 100644 (file)
     </Compile>
     <Compile Include="PreferencesViewModel.cs" />
     <Compile Include="TaskbarViewModel.cs" />
+    <Compile Include="Wpf32Window.cs" />
     <Page Include="FilePropertiesView.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
index 8dd3631..460a2b8 100644 (file)
@@ -4,6 +4,9 @@
 // </copyright>
 // -----------------------------------------------------------------------
 
+using Pithos.Network;
+using log4net;
+
 namespace Pithos.Client.WPF
 {
     using System;
@@ -24,6 +27,8 @@ namespace Pithos.Client.WPF
     /// </summary>
     public static class PithosAccount
     {
+        private static readonly ILog Log = LogManager.GetLogger(typeof(PithosAccount));
+
         /// <summary>
         /// Asynchronously retrieves PITHOS credentials
         /// </summary>
@@ -44,7 +49,7 @@ namespace Pithos.Client.WPF
             HttpListener listener = new HttpListener();
             listener.Prefixes.Add(listenerUrl);
 
-            Trace.TraceInformation("[RETRIEVE] Listening at {0}", listenerUrl);
+            Log.InfoFormat("[RETRIEVE] Listening at {0}", listenerUrl);
 
             listener.Start();
 
@@ -56,7 +61,7 @@ namespace Pithos.Client.WPF
                     {
                         if (tc.IsFaulted)
                         {
-                            Trace.TraceError("[RETRIEVE][ERROR] Receive connection {0}", tc.Exception);
+                            Log.Error("[RETRIEVE][ERROR] Receive connection {0}", tc.Exception);
                             throw tc.Exception;
                         }
                         else
@@ -64,13 +69,13 @@ namespace Pithos.Client.WPF
 
                             var context = tc.Result;
                             var request = context.Request;
-                            Trace.TraceInformation("[RETRIEVE] Got Connection {0}", request.RawUrl);
+                            Log.InfoFormat("[RETRIEVE] Got Connection {0}", request.RawUrl);
 
                             var query = request.QueryString;
                             var userName = query["user"];
                             var token = query["token"];
 
-                            Trace.TraceInformation("[RETRIEVE] Credentials retrieved user:{0} token:{1}", userName, token);
+                            Log.InfoFormat("[RETRIEVE] Credentials retrieved user:{0} token:{1}", userName, token);
                             Respond(context);
                             
                             return new NetworkCredential(userName, token);
@@ -88,7 +93,7 @@ namespace Pithos.Client.WPF
             uriBuilder.Query="next=" + listenerUrl;
 
             var retrieveUri = uriBuilder.Uri;
-            Trace.TraceInformation("[RETRIEVE] Open Browser at {0}", retrieveUri);
+            Log.InfoFormat("[RETRIEVE] Open Browser at {0}", retrieveUri);
             Process.Start(retrieveUri.ToString());
 
             return task;
@@ -104,7 +109,7 @@ namespace Pithos.Client.WPF
                 stream.Write(outBuffer, 0, outBuffer.Length);
             }
 
-            Trace.TraceInformation("[RETRIEVE] Responded");
+            Log.InfoFormat("[RETRIEVE] Responded");
         }
         /// <summary>
         /// Locates a free local port 
index 09fc450..0624cb0 100644 (file)
@@ -4,7 +4,7 @@
         xmlns:tb="clr-namespace:Hardcodet.Wpf.TaskbarNotification;assembly=Hardcodet.Wpf.TaskbarNotification"
         xmlns:cal="http://www.caliburnproject.org" 
         x:Name="TheView"
-        Title="Pithos Preferences" Height="382" Width="445" 
+        Title="Pithos Preferences" Height="381" Width="548" 
         ShowInTaskbar="true"
         WindowStartupLocation="CenterScreen"
         Icon="/Pithos.Client.WPF;component/Images/Tray.ico"
                         <TextBlock Text="Accounts"/>
                     </StackPanel>
                 </TabItem.Header>
-                <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" >
-                    <Grid Margin="5,10,5,5">
+                <Grid VerticalAlignment="Stretch" >
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="Auto"/>
+                        <ColumnDefinition Width="*"/>
+                    </Grid.ColumnDefinitions>
+                    <Grid Margin="5,10,5,5" Column="0" Width="150">
                         <Grid.RowDefinitions>
                             <RowDefinition Height="*"/>
                             <RowDefinition Height="Auto"/>
                             <Button Name="RemoveAccount" Content="Remove" Style="{StaticResource ButtonStyle}" Width="50"/>                            
                         </StackPanel>
                     </Grid>
-                    <GroupBox Header="Account" Padding="5" Margin="5" Height="190" HorizontalAlignment="Stretch" VerticalAlignment="Top" Width="272">
+                    <GroupBox Header="Account" Padding="5" Margin="5" Height="231" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Column="1">
                             <Grid>
                             <Grid.ColumnDefinitions>
                                 <ColumnDefinition Width="Auto"/>
                                 <RowDefinition Height="Auto"/>
                                 <RowDefinition Height="Auto"/>
                                 <RowDefinition Height="Auto"/>
+                                <RowDefinition Height="Auto"/>
                                 <RowDefinition />
                             </Grid.RowDefinitions>
                             <Label Content="Account" Grid.Column="0" Grid.Row="0" Margin="0,5" HorizontalAlignment="Left"/>
                             <TextBox Name="CurrentAccount_AccountName" Grid.Column="1" Grid.Row="0" Margin="5"/>
                             <Label Content="API Key" Grid.Column="0" Grid.Row="1" Margin="0,5" HorizontalAlignment="Left"/>
                             <TextBox  Name="CurrentAccount_ApiKey" Grid.Column="1" Grid.Row="1" Margin="5"/>
-                            <CheckBox Name="CurrentAccount_IsActive" Content="Account is Active" Grid.Column="1" Grid.Row="2" Margin="5"/>
-                            <CheckBox Name="CurrentAccount_UsePithos" Content="Use Pithos Extensions" Grid.Column="1" Grid.Row="3" Margin="5"/>
-                            <Button Name="SelectSyncFolders" Content="Selective Sync" Width="Auto" HorizontalAlignment="Left" Style="{StaticResource ButtonStyle}" Grid.Column="1" Grid.Row="4"/>
+                            <Label Content="Folder" Grid.Column="0" Grid.Row="2" Margin="0,5" HorizontalAlignment="Left"/>
+                            <Grid Grid.Row="2" Grid.Column="1" >
+                                <Grid.ColumnDefinitions>
+                                    <ColumnDefinition Width="*"/>
+                                    <ColumnDefinition Width="Auto"/>
+                                </Grid.ColumnDefinitions>
+                                <TextBox  Name="CurrentAccount_RootPath" Margin="5" HorizontalAlignment="Stretch" Grid.Column="0"/>
+                                <Button Name="MoveAccountFolder" Content="Move ..." Width="60" Height="30" Grid.Column="1" />
+                            </Grid>
+                            <CheckBox Name="CurrentAccount_IsActive" Content="Account is Active" Grid.Column="1" Grid.Row="3" Margin="5"/>
+                            <CheckBox Name="CurrentAccount_UsePithos" Content="Use Pithos Extensions" Grid.Column="1" Grid.Row="4" Margin="5"/>
+                            <Button Name="SelectSyncFolders" Content="Selective Sync" Width="Auto" HorizontalAlignment="Left" Style="{StaticResource ButtonStyle}" Grid.Column="1" Grid.Row="5"/>
                             
                         </Grid>
                         
                     </GroupBox>
                     
-                </StackPanel>
+                </Grid>
             </TabItem>
             <TabItem VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch">
                 <TabItem.Header>
index 86506f4..8027220 100644 (file)
@@ -6,6 +6,7 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
 using System.Windows.Documents;
+using System.Windows.Forms;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
@@ -43,5 +44,6 @@ namespace Pithos.Client.WPF
             
         }
 
+       
     }
 }
index a21698e..d6a25cb 100644 (file)
@@ -16,12 +16,13 @@ using System.Runtime.InteropServices;
 using System.Runtime.Serialization;
 using System.Windows;
 using System.Windows.Forms;
+using System.Windows.Interop;
 using Caliburn.Micro;
 using Hardcodet.Wpf.TaskbarNotification;
 using Pithos.Client.WPF.Configuration;
 using Pithos.Core;
 using Pithos.Interfaces;
-
+using IWin32Window = System.Windows.Forms.IWin32Window;
 using Screen = Caliburn.Micro.Screen;
 
 namespace Pithos.Client.WPF
@@ -41,10 +42,31 @@ namespace Pithos.Client.WPF
         private IEventAggregator _events;
 
 
-        public PithosSettings Settings { get; set; }
+        private PithosSettings _settings;
+        public PithosSettings Settings
+        {
+            get { return _settings; }
+            set
+            {
+                _settings = value;
+                foreach (var account in _settings.Accounts.Where(account=>account.IsActive))
+                {
+                    if (String.IsNullOrWhiteSpace(account.RootPath))
+                    {
+                        account.RootPath = _settings.PithosPath;
+                        _settings.Save();
+                    }
+                }
+                NotifyOfPropertyChange(()=>Settings);
+            }
+        }
 
 
-        public PithosMonitor Monitor { get; private set; }
+        private Dictionary<string,PithosMonitor> _monitors=new Dictionary<string, PithosMonitor>();
+        public Dictionary<string, PithosMonitor> Monitors
+        {
+            get { return _monitors; }            
+        }
 
         private TaskbarViewModel _taskbar;
         public TaskbarViewModel Taskbar
@@ -59,7 +81,7 @@ namespace Pithos.Client.WPF
         //ShellExtensionController _extensionController=new ShellExtensionController();
 
         [ImportingConstructor]
-        public PreferencesViewModel(IEventAggregator events, TaskbarViewModel taskbar, PithosSettings settings, PithosMonitor monitor)
+        public PreferencesViewModel(IEventAggregator events, TaskbarViewModel taskbar, PithosSettings settings)
         {
             _events = events;
             _events.Subscribe(this);
@@ -69,8 +91,7 @@ namespace Pithos.Client.WPF
             Taskbar=taskbar;
             Taskbar.Parent = this;
             
-            Settings=settings;
-            Monitor=monitor;
+            Settings=settings;            
 
 
             Taskbar.UsageMessage = "Using 15% of 50 GB";
@@ -166,11 +187,12 @@ namespace Pithos.Client.WPF
             if (String.IsNullOrWhiteSpace(activeAccount.AccountName))
                 return;
 
-            Monitor.ApiKey = activeAccount.ApiKey;
-            Monitor.UserName = activeAccount.AccountName;
-            Monitor.UsePithos = activeAccount.UsePithos;
+            var monitor = Monitors[activeAccount.AccountName];
+            monitor.ApiKey = activeAccount.ApiKey;
+            monitor.UserName = activeAccount.AccountName;
+            monitor.UsePithos = activeAccount.UsePithos;
 
-            Monitor.Start();
+            monitor.Start();
         }
 
         public void ChangePithosFolder()
@@ -313,12 +335,7 @@ namespace Pithos.Client.WPF
                     return Settings.Accounts[SelectedAccountIndex];
                 return null;
             }
-/*
-            set
-            {
-                _currentAccount = value;
-            }
-*/
+
         }
 
 
@@ -348,5 +365,46 @@ namespace Pithos.Client.WPF
             tv.TaskbarView.ShowBalloonTip(notification.Title, notification.Message, icon);
         }
 
+
+    public void MoveAccountFolder()
+    {
+
+        using (var dlg = new FolderBrowserDialog())
+        {
+            var currentFolder = CurrentAccount.RootPath;
+            dlg.SelectedPath = currentFolder;
+            //Ask the user to select a folder
+            //Note: We need a parent window here, which we retrieve with GetView            
+            var view = (Window)GetView();            
+            if (DialogResult.OK != dlg.ShowDialog(new Wpf32Window(view)))
+                return;            
+
+            var newPath= dlg.SelectedPath;                
+            //Find the account's monitor and stop it
+            var monitor = Monitors[CurrentAccount.AccountName];            
+            monitor.Stop();
+                            
+            var oldPath = monitor.RootPath;                
+            //The old directory may not exist eg. if we create an account for the first time
+            if (Directory.Exists(oldPath))
+            {
+                //If it does, do the move
+                Directory.Move(oldPath, newPath);
+                //We also need to change the path of the existing file states
+                monitor.MoveFileStates(oldPath, newPath);
+            }
+            //Replace the old rootpath with the new
+            CurrentAccount.RootPath = newPath;
+            //TODO: This will save all settings changes. Too coarse grained, need to fix at a later date
+            Settings.Save();            
+            //And start the monitor on the new RootPath            
+            monitor.RootPath = newPath;
+            monitor.Start();
+            //Finally, notify that the Settings, CurrentAccount have changed
+            NotifyOfPropertyChange(() => CurrentAccount);
+            NotifyOfPropertyChange(() => Settings);
+
+        }
+    }
     }
 }
diff --git a/trunk/Pithos.Client.WPF/Wpf32Window.cs b/trunk/Pithos.Client.WPF/Wpf32Window.cs
new file mode 100644 (file)
index 0000000..2b8eb06
--- /dev/null
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows;
+using System.Windows.Interop;
+using IWin32Window = System.Windows.Forms.IWin32Window;
+
+
+namespace Pithos.Client.WPF
+{
+    public class Wpf32Window : IWin32Window
+    {
+        public IntPtr Handle { get; private set; }
+
+        public Wpf32Window(Window wpfWindow)
+        {
+            Handle = new WindowInteropHelper(wpfWindow).Handle;
+        }
+    }
+}
index 446a37c..bd91995 100644 (file)
@@ -7,6 +7,7 @@
     <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
       <section name="Pithos.Client.WPF.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
     </sectionGroup>
+    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
   </configSections>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       </setting>
     </Pithos.Client.WPF.Properties.Settings>
   </applicationSettings>
+  <log4net>
+    <appender name="TraceAppender" type="log4net.Appender.TraceAppender" >
+      <layout type="log4net.Layout.PatternLayout">
+        <conversionPattern value="%logger (%property{myContext}) [%level]- %message%newline" />
+      </layout>
+      <filter type="log4net.Filter.LevelRangeFilter">
+        <levelMin value="DEBUG" />
+        <levelMax value="FATAL" />
+        <acceptOnMatch value="false" />
+      </filter>
+      <filter type="log4net.Filter.LoggerMatchFilter">
+        <loggerToMatch value="NHibernate" />
+        <acceptOnMatch value="false" />
+      </filter>
+      <filter type="log4net.Filter.LoggerMatchFilter">
+        <loggerToMatch value="Caliburn" />
+        <acceptOnMatch value="false" />
+      </filter>
+    </appender>
+    <root>
+      <level value="DEBUG" />
+      <appender-ref ref="TraceAppender" />
+    </root>
+  </log4net>
 </configuration>
\ No newline at end of file
index 9cac001..0d91029 100644 (file)
@@ -126,6 +126,10 @@ namespace Pithos.Core.Test
         public string BlockHash { get; set; }
 
         public int BlockSize { get; set; }
+        public void ChangeRoots(string oldPath, string newPath)
+        {
+            throw new NotImplementedException();
+        }
 
 
         private PithosStatus _pithosStatus = PithosStatus.InSynch;
index 795eb0a..4103523 100644 (file)
@@ -88,6 +88,9 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="Castle.ActiveRecord, Version=3.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL" />
+    <Reference Include="Castle.Core">
+      <HintPath>..\Libraries\Castle.Core.dll</HintPath>
+    </Reference>
     <Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
       <HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll</HintPath>
     </Reference>
index 3f0ad1e..83f12ec 100644 (file)
@@ -1,5 +1,8 @@
 using System;
+using System.Linq;
+using Castle.ActiveRecord;
 using NUnit.Framework;
+using Pithos.Core.Agents;
 using Pithos.Interfaces;
 
 namespace Pithos.Core.Test
@@ -81,5 +84,6 @@ namespace Pithos.Core.Test
 
 
         }
+
     }
 }
index bc4a7fa..dbdafaf 100644 (file)
@@ -52,14 +52,40 @@ namespace Pithos.Core.Agents
         }
 
 
-        //Constructor for downloading files
-        public CloudAction(CloudActionType action, ObjectInfo cloudFile)
+
+    }    
+
+    public class CloudDownloadAction:CloudAction
+    {
+        public CloudDownloadAction(ObjectInfo cloudFile)
+            :base(CloudActionType.DownloadUnconditional)
+        {            
+            CloudFile = cloudFile;
+        }
+        
+    }
+    public class CloudDeleteAction:CloudAction
+    {
+        public CloudDeleteAction(string fileName, FileState fileState)
+            : this(new ObjectInfo { Name = fileName },fileState)
+        {
+        }
+
+        public CloudDeleteAction(ObjectInfo cloudFile, FileState fileState) 
+            : base(CloudActionType.DeleteCloud)
         {
-            Action = action;
             CloudFile = cloudFile;
+            FileState = fileState;
         }
+    }
 
-    }    
+    public class CloudUploadAction:CloudAction
+    {
+        public CloudUploadAction(FileInfo fileInfo, FileState state, int blockSize, string algorithm) 
+            : base(CloudActionType.UploadUnconditional,fileInfo,ObjectInfo.Empty,state,blockSize,algorithm)
+        {
+        }
+    }
 
     public class CloudMoveAction:CloudAction
     {
index 44f032c..37891b9 100644 (file)
@@ -9,6 +9,8 @@ using System.Text;
 using System.Threading.Tasks;
 using Pithos.Interfaces;
 using Pithos.Network;
+using log4net;
+using log4net.Core;
 
 namespace Pithos.Core.Agents
 {
@@ -27,6 +29,7 @@ namespace Pithos.Core.Agents
 
         public string RootPath { get; private set; }
 
+        private static readonly ILog Log = LogManager.GetLogger("FileAgent");
 
         public void Start(string rootPath)
         {
@@ -55,7 +58,7 @@ namespace Pithos.Core.Agents
                     var process=message.Then(Process,inbox.CancellationToken);
 
                     inbox.LoopAsync(process,loop,ex=>
-                        Trace.TraceError("[ERROR] File Event Processing:\r{0}", ex));
+                        Log.ErrorFormat("[ERROR] File Event Processing:\r{0}", ex));
                 };
                 loop();
             });
@@ -90,17 +93,17 @@ namespace Pithos.Core.Agents
             {
                 if (File.Exists(state.Path))
                 {
-                    Trace.TraceWarning("File access error occured, retrying {0}\n{1}", state.Path, exc);
+                    Log.WarnFormat("File access error occured, retrying {0}\n{1}", state.Path, exc);
                     _agent.Post(state);
                 }
                 else
                 {
-                    Trace.TraceWarning("File {0} does not exist. Will be ignored\n{1}", state.Path, exc);
+                    Log.WarnFormat("File {0} does not exist. Will be ignored\n{1}", state.Path, exc);
                 }
             }
             catch (Exception exc)
             {
-                Trace.TraceWarning("Error occured while indexing{0. The file will be skipped}\n{1}", state.Path, exc);
+                Log.WarnFormat("Error occured while indexing{0. The file will be skipped}\n{1}", state.Path, exc);
             }
             return CompletedTask<object>.Default;
         }
index 7643c45..967d24e 100644 (file)
@@ -43,7 +43,7 @@ namespace Pithos.Core.Agents
         public int BlockSize { get; set; }
         public string BlockHash { get; set; }
 
-        private static readonly ILog Log = LogManager.GetLogger(typeof(NetworkAgent));
+        private static readonly ILog Log = LogManager.GetLogger("NetworkAgent");
 
 
         public void Start(string pithosContainer, string trashContainer, int blockSize, string blockHash)
@@ -79,7 +79,7 @@ namespace Pithos.Core.Agents
                 throw new ArgumentNullException("action");
             Contract.EndContractBlock();
 
-            using (log4net.LogicalThreadContext.Stacks["NETWORK"].Push("PROCESS"))
+            using (log4net.ThreadContext.Stacks["NETWORK"].Push("PROCESS"))
             {                
                 Log.InfoFormat("[ACTION] Start Processing {0}:{1}->{2}", action.Action, action.LocalFile,
                                action.CloudFile.Name);
@@ -133,11 +133,11 @@ namespace Pithos.Core.Agents
                 {
                     throw;
                 }
-                catch (System.IO.FileNotFoundException exc)
+                catch (FileNotFoundException exc)
                 {
                     Log.ErrorFormat("{0} : {1} -> {2}  failed because the file was not found.\n Rescheduling a delete",
                         action.Action, action.LocalFile, action.CloudFile, exc);
-                    Post(new CloudAction(CloudActionType.DeleteCloud,action.CloudFile));
+                    Post(new CloudDeleteAction(action.CloudFile,action.FileState));
                 }
                 catch (Exception exc)
                 {
@@ -246,12 +246,12 @@ namespace Pithos.Core.Agents
                 throw new ArgumentNullException("action");
             Contract.EndContractBlock();
 
-            Trace.TraceInformation("[ACTION] Start Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
+            Log.InfoFormat("[ACTION] Start Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
 
             try
             {
                 RenameCloudFile(action.OldFileName, action.NewPath, action.NewFileName);
-                Trace.TraceInformation("[ACTION] End Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
+                Log.InfoFormat("[ACTION] End Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
             }
             catch (OperationCanceledException)
             {
@@ -259,7 +259,7 @@ namespace Pithos.Core.Agents
             }
             catch (Exception exc)
             {
-                Trace.TraceError("[REQUEUE] {0} : {1} -> {2} due to exception\r\n{3}",
+                Log.ErrorFormat("[REQUEUE] {0} : {1} -> {2} due to exception\r\n{3}",
                                 action.Action, action.OldFileName, action.NewFileName, exc);
 
                 _agent.Post(action);
@@ -312,7 +312,7 @@ namespace Pithos.Core.Agents
                 throw new ArgumentNullException(accountPath);
             Contract.EndContractBlock();
 
-            using (log4net.LogicalThreadContext.Stacks["SCHEDULE"].Push("Retrieve Remote"))
+            using (log4net.ThreadContext.Stacks["SCHEDULE"].Push("Retrieve Remote"))
             {
                 Log.Info("[LISTENER] Scheduled");
 
@@ -345,7 +345,7 @@ namespace Pithos.Core.Agents
                         ProcessRemoteFiles(accountPath, since);
                         return;
                     }
-                    using (log4net.LogicalThreadContext.Stacks["SCHEDULE"].Push("Process Results"))
+                    using (log4net.ThreadContext.Stacks["SCHEDULE"].Push("Process Results"))
                     {
                         var remoteObjects = ((Task<IList<ObjectInfo>>) task.Result[0]).Result;
                         var trashObjects = ((Task<IList<ObjectInfo>>) task.Result[1]).Result;
@@ -437,7 +437,7 @@ namespace Pithos.Core.Agents
                     if (fileStatus != FileStatus.Deleted)
                     {
                         //Remote files should be downloaded
-                        yield return new CloudAction(CloudActionType.DownloadUnconditional, objectInfo);
+                        yield return new CloudDownloadAction(objectInfo);
                     }
                 }
             }            
@@ -492,7 +492,7 @@ namespace Pithos.Core.Agents
                 throw new ArgumentException("The fileName should not be rooted","fileName");
             Contract.EndContractBlock();
 
-            using ( log4net.LogicalThreadContext.Stacks["DeleteCloudFile"].Push("Delete"))
+            using ( log4net.ThreadContext.Stacks["DeleteCloudFile"].Push("Delete"))
             {
                 var info = FileAgent.GetFileInfo(fileName);
                 var path = info.FullName.ToLower();
@@ -713,7 +713,7 @@ namespace Pithos.Core.Agents
                 throw new ArgumentNullException("topHash");
             Contract.EndContractBlock();
 
-            var upload = Task.Factory.Iterate(UploadIterator(account,container,fileInfo, hash, topHash));
+            var upload = Task.Factory.Iterate(UploadIterator(account,container,fileInfo, hash.ToLower(), topHash.ToLower()));
             upload.Wait();
         }
 
@@ -746,10 +746,10 @@ namespace Pithos.Core.Agents
 
                 //Even if GetObjectInfo times out, we can proceed with the upload            
                 var info = CloudClient.GetObjectInfo(account, container, url);
+                var cloudHash = info.Hash.ToLower();
 
                 //If the file hashes match, abort the upload
-                if (hash.Equals(info.Hash, StringComparison.InvariantCultureIgnoreCase) ||
-                    topHash.Equals(info.Hash, StringComparison.InvariantCultureIgnoreCase))
+                if (hash == cloudHash  || topHash ==cloudHash)
                 {
                     //but store any metadata changes 
                     this.StatusKeeper.StoreInfo(fullFileName, info);
index fc77561..bd50851 100644 (file)
@@ -26,7 +26,7 @@ namespace Pithos.Core.Agents
         private Agent<Action> _persistenceAgent;
 
 
-        private static readonly ILog log = LogManager.GetLogger(typeof(StatusAgent));
+        private static readonly ILog Log = LogManager.GetLogger("StatusAgent");
 
         public StatusAgent()
         {            
@@ -84,9 +84,9 @@ namespace Pithos.Core.Agents
             var connectionString = String.Format(@"Data Source={0}\pithos.db;Version=3", pithosDbPath);
             properties.Add("connection.connection_string", connectionString);
 
-            var source = new InPlaceConfigurationSource();
-
+            var source = new InPlaceConfigurationSource();                        
             source.Add(typeof (ActiveRecordBase), properties);
+            source.SetDebugFlag(false);            
             return source;
         }
 
@@ -107,7 +107,7 @@ namespace Pithos.Core.Agents
                         }
                         catch (Exception ex)
                         {
-                            Trace.TraceError("[ERROR] STATE \n{0}",ex);
+                            Log.ErrorFormat("[ERROR] STATE \n{0}",ex);
                         }
                         queue.DoAsync(loop);
                     });
@@ -192,6 +192,21 @@ namespace Pithos.Core.Agents
         public string BlockHash { get; set; }
 
         public int BlockSize { get; set; }
+        public void ChangeRoots(string oldPath, string newPath)
+        {
+            if (String.IsNullOrWhiteSpace(oldPath))
+                throw new ArgumentNullException("oldPath");
+            if (!Path.IsPathRooted(oldPath))
+                throw new ArgumentException("oldPath must be an absolute path", "oldPath");
+            if (string.IsNullOrWhiteSpace(newPath))
+                throw new ArgumentNullException("newPath");
+            if (!Path.IsPathRooted(newPath))
+                throw new ArgumentException("newPath must be an absolute path", "newPath");
+            Contract.EndContractBlock();
+
+            FileState.ChangeRootPath(oldPath,newPath);
+
+        }
 
         private PithosStatus _pithosStatus=PithosStatus.InSynch;       
 
@@ -226,7 +241,7 @@ namespace Pithos.Core.Agents
             }
             catch (Exception exc)
             {
-                Trace.TraceError(exc.ToString());
+                Log.ErrorFormat(exc.ToString());
                 return defaultValue;
             }
         }
@@ -298,7 +313,7 @@ namespace Pithos.Core.Agents
                     var state = FileState.FindByFilePath(filePath);
                     if (state == null)
                     {
-                        Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", filePath);
+                        Log.WarnFormat("[NOFILE] Unable to set status for {0}.", filePath);
                         return;
                     }
                     setter(state);
@@ -327,7 +342,7 @@ namespace Pithos.Core.Agents
                     var state = FileState.Find(stateID);
                     if (state == null)
                     {
-                        Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", stateID);
+                        Log.WarnFormat("[NOFILE] Unable to set status for {0}.", stateID);
                         return;
                     }
                     setter(state);
@@ -352,7 +367,7 @@ namespace Pithos.Core.Agents
             }
             catch (Exception exc)
             {
-                Trace.TraceError(exc.ToString());
+                Log.ErrorFormat(exc.ToString());
                 return FileOverlayStatus.Unversioned;
             }
         }
@@ -423,7 +438,7 @@ namespace Pithos.Core.Agents
 
             if (state == null)
             {
-                Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", oldPath);
+                Log.WarnFormat("[NOFILE] Unable to set status for {0}.", oldPath);
                 return;
             }
             //NOTE: This will cause problems if path is used as a key in relationships
@@ -546,7 +561,7 @@ namespace Pithos.Core.Agents
                     var state = FileState.FindByFilePath(path);
                     if (state == null)
                     {
-                        Trace.TraceWarning("[NOFILE] Unable to set checkesum for {0}.", path);
+                        Log.WarnFormat("[NOFILE] Unable to set checkesum for {0}.", path);
                         return;
                     }
                     state.Checksum = checksum;
index 2d630c1..3dba9a5 100644 (file)
@@ -8,6 +8,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using Pithos.Interfaces;
+using log4net;
 
 namespace Pithos.Core.Agents
 {
@@ -27,6 +28,8 @@ namespace Pithos.Core.Agents
         [Import]
         public NetworkAgent NetworkAgent { get; set; }
 
+        private static readonly ILog Log = LogManager.GetLogger("WorkflowAgent");
+
         public void Start()
         {
             _agent = Agent<WorkflowState>.Start(inbox =>
@@ -37,7 +40,7 @@ namespace Pithos.Core.Agents
                     var message = inbox.Receive();
                     var process = message.Then(Process, inbox.CancellationToken);                        
                     inbox.LoopAsync(process,loop,ex=>
-                            Trace.TraceError("[ERROR] Synch for {0}:\r{1}", message.Result.FileName, ex));
+                            Log.ErrorFormat("[ERROR] Synch for {0}:\r{1}", message.Result.FileName, ex));
                 };
                 loop();
             });
@@ -45,38 +48,51 @@ namespace Pithos.Core.Agents
 
         private Task<object> Process(WorkflowState state)
         {
-            if (state.Skip)
-                return CompletedTask<object>.Default;
-            string path = state.Path.ToLower();            
-
-            //Bypass deleted files, unless the status is Deleted
-            if (!File.Exists(path) && state.Status != FileStatus.Deleted)
+            using (log4net.ThreadContext.Stacks["Workflow"].Push("Process"))
             {
-                state.Skip = true;
-                this.StatusKeeper.ClearFileStatus(path);
-                return CompletedTask<object>.Default;
-            }
-            var fileState = FileState.FindByFilePath(path);
-            var blockHash = NetworkAgent.BlockHash;
-            var blockSize = NetworkAgent.BlockSize;
-            var info = new FileInfo(path);
+                if (Log.IsDebugEnabled) Log.DebugFormat("State {0} {1} {2}", state.FileName,state.Status,state.TriggeringChange);
 
-            switch (state.Status)
-            {
-                case FileStatus.Created:
-                case FileStatus.Modified:
-                    NetworkAgent.Post(new CloudAction(CloudActionType.UploadUnconditional, info, ObjectInfo.Empty, fileState,blockSize,blockHash));
-                    break;
-                case FileStatus.Deleted:
-                    string fileName = info.AsRelativeUrlTo(NetworkAgent.FileAgent.RootPath);                    
-                    NetworkAgent.Post(new CloudAction(CloudActionType.DeleteCloud, null, new ObjectInfo { Name = fileName }, fileState, blockSize, blockHash));
-                    break;
-                case FileStatus.Renamed:
-                    NetworkAgent.Post(new CloudMoveAction(CloudActionType.RenameCloud, state.OldFileName, state.OldPath, state.FileName, state.Path));
-                    break;
-            }
+                if (state.Skip)
+                {
+                    if (Log.IsDebugEnabled) Log.DebugFormat("Skipping {0}",state.FileName);
+                    
+                    return CompletedTask<object>.Default;
+                }
+                string path = state.Path.ToLower();
+
+                //Bypass deleted files, unless the status is Deleted
+                if (!File.Exists(path) && state.Status != FileStatus.Deleted)
+                {
+                    state.Skip = true;
+                    this.StatusKeeper.ClearFileStatus(path);
+                    
+                    if (Log.IsDebugEnabled) Log.DebugFormat("Skipped missing {0}", state.FileName);
+
+                    return CompletedTask<object>.Default;
+                }
+                var fileState = FileState.FindByFilePath(path);
+                var blockHash = NetworkAgent.BlockHash;
+                var blockSize = NetworkAgent.BlockSize;
+                var info = new FileInfo(path);
+
+                switch (state.Status)
+                {
+                    case FileStatus.Created:
+                    case FileStatus.Modified:
+                        NetworkAgent.Post(new CloudUploadAction(info, fileState, blockSize, blockHash));
+                        break;
+                    case FileStatus.Deleted:
+                        string fileName = info.AsRelativeUrlTo(NetworkAgent.FileAgent.RootPath);
+                        NetworkAgent.Post(new CloudDeleteAction(fileName, fileState));
+                        break;
+                    case FileStatus.Renamed:
+                        NetworkAgent.Post(new CloudMoveAction(CloudActionType.RenameCloud, state.OldFileName,
+                                                              state.OldPath, state.FileName, state.Path));
+                        break;
+                }
 
-            return CompletedTask<object>.Default;
+                return CompletedTask<object>.Default;
+            }
         }
 
 
@@ -84,38 +100,48 @@ namespace Pithos.Core.Agents
         public void RestartInterruptedFiles()
         {
             
-            StatusNotification.NotifyChange("Restart processing interrupted files", TraceLevel.Verbose);            
-
-            var pendingEntries = from state in FileState.Queryable
-                                   where state.FileStatus != FileStatus.Unchanged &&
-                                         !state.FilePath.StartsWith(FragmentsPath.ToLower()) &&
-                                         !state.FilePath.EndsWith(".ignore")
-                                   select state;
-
-            var validEntries = from state in pendingEntries
-                             select new WorkflowState
-                             {
-                                 Path = state.FilePath.ToLower(),
-                                 FileName = Path.GetFileName(state.FilePath).ToLower(),
-                                 Hash = state.Checksum,
-                                 Status = state.OverlayStatus == FileOverlayStatus.Unversioned ?
-                                                   FileStatus.Created :
-                                                   state.FileStatus,
-                                 TriggeringChange = state.OverlayStatus == FileOverlayStatus.Unversioned ?
-                                                   WatcherChangeTypes.Created :
-                                                   WatcherChangeTypes.Changed
-                             };
-            foreach (var entry in validEntries)
-            {
-                Post(entry);
-            }            
+            StatusNotification.NotifyChange("Restart processing interrupted files", TraceLevel.Verbose);
 
+            using (log4net.ThreadContext.Stacks["Workflow"].Push("Restart"))
+            {
+                if (Log.IsDebugEnabled)
+                    Log.Debug("Starting interrupted files");
+                
+                var pendingEntries = from state in FileState.Queryable
+                                     where state.FileStatus != FileStatus.Unchanged &&
+                                           !state.FilePath.StartsWith(FragmentsPath.ToLower()) &&
+                                           !state.FilePath.EndsWith(".ignore")
+                                     select state;
+                if (Log.IsDebugEnabled)
+                    Log.DebugFormat("Found {0} interrupted files",pendingEntries.Count());
+
+                var validEntries = from state in pendingEntries
+                                   select new WorkflowState
+                                              {
+                                                  Path = state.FilePath.ToLower(),
+                                                  FileName = Path.GetFileName(state.FilePath).ToLower(),
+                                                  Hash = state.Checksum,
+                                                  Status = state.OverlayStatus == FileOverlayStatus.Unversioned
+                                                               ? FileStatus.Created
+                                                               : state.FileStatus,
+                                                  TriggeringChange =
+                                                      state.OverlayStatus == FileOverlayStatus.Unversioned
+                                                          ? WatcherChangeTypes.Created
+                                                          : WatcherChangeTypes.Changed
+                                              };
+                foreach (var entry in validEntries)
+                {                    
+                    Post(entry);
+                }
+            }
         }       
 
        
 
         public void Post(WorkflowState workflowState)
         {
+            if (Log.IsDebugEnabled)
+                Log.DebugFormat("Posted {0} {1} {2}", workflowState.Path, workflowState.Status, workflowState.TriggeringChange);
             _agent.Post(workflowState);
         }
     }
index bb0c481..c1be0fd 100644 (file)
@@ -110,6 +110,39 @@ namespace Pithos.Core
             
         }
 
+        public static void ChangeRootPath(string oldPath,string newPath)
+        {
+            if (String.IsNullOrWhiteSpace(oldPath))
+                throw new ArgumentNullException("oldPath");
+            if (!Path.IsPathRooted(oldPath))
+                throw new ArgumentException("oldPath must be an absolute path", "oldPath");
+            if (string.IsNullOrWhiteSpace(newPath))
+                throw new ArgumentNullException("newPath");
+            if (!Path.IsPathRooted(newPath))
+                throw new ArgumentException("newPath must be an absolute path", "newPath");
+            Contract.EndContractBlock();
+
+            //Ensure the paths end with the same character
+            if (!oldPath.EndsWith("\\"))
+                oldPath = oldPath + "\\";
+            if (!newPath.EndsWith("\\"))
+                newPath = newPath + "\\";
+
+            using (new TransactionScope())
+            {
+                Execute((session, instance) =>
+                            {
+                                const string hqlUpdate =
+                                    "update FileState set FilePath = replace(FilePath,:oldPath,:newPath) where FilePath like :oldPath || '%' ";
+                                var result=session.CreateQuery(hqlUpdate)
+                                    .SetString("oldPath", oldPath.ToLower())
+                                    .SetString("newPath", newPath.ToLower())
+                                    .ExecuteUpdate();
+                                return null;
+                            }, null);
+            }
+        }
+
         public static Task<FileState> CreateForAsync(string filePath,int blockSize,string algorithm)
         {
             if (blockSize <= 0)
index ded754f..b4f2163 100644 (file)
@@ -29,6 +29,7 @@ namespace Pithos.Core
 
         string BlockHash { get; set; }
         int BlockSize { get; set; }
+        void ChangeRoots(string oldPath, string newPath);
     }
 
     [ContractClassFor(typeof(IStatusKeeper))]
@@ -155,5 +156,12 @@ namespace Pithos.Core
 
         public abstract string BlockHash { get; set; }
         public abstract int BlockSize { get; set; }
+        public void ChangeRoots(string oldPath, string newPath)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(oldPath));
+            Contract.Requires(Path.IsPathRooted(oldPath));
+            Contract.Requires(!string.IsNullOrWhiteSpace(newPath));
+            Contract.Requires(Path.IsPathRooted(newPath));            
+        }
     }
 }
index e097cf0..341db23 100644 (file)
@@ -18,6 +18,7 @@ using Pithos.Core.Agents;
 using Pithos.Interfaces;
 using System.ServiceModel;
 using Pithos.Network;
+using log4net;
 
 namespace Pithos.Core
 {
@@ -61,6 +62,8 @@ namespace Pithos.Core
 
         private ServiceHost _statusService { get; set; }
 
+        private static readonly ILog Log = LogManager.GetLogger(typeof(PithosMonitor));
+
 
         public bool Pause
         {
@@ -182,26 +185,29 @@ namespace Pithos.Core
         private void IndexLocalFiles(string path)
         {
             StatusNotification.NotifyChange("Indexing Local Files",TraceLevel.Info);
-            Trace.TraceInformation("[START] Index Local");
-            try
+            using (log4net.ThreadContext.Stacks["Monitor"].Push("Indexing local files"))
             {
-                var fragmentsPath=Path.Combine(RootPath, FragmentsFolder);
-                var directory = new DirectoryInfo(path);
-                var files =
-                    from file in directory.EnumerateFiles("*", SearchOption.AllDirectories)
-                    where !file.FullName.StartsWith(fragmentsPath,StringComparison.InvariantCultureIgnoreCase) &&
-                            !file.Extension.Equals("ignore",StringComparison.InvariantCultureIgnoreCase)
-                    select file;
-                StatusKeeper.ProcessExistingFiles(files);
-                
-            }
-            catch (Exception exc)
-            {
-                Trace.TraceError("[ERROR] Index Local - {0}", exc);
-            }
-            finally
-            {
-                Trace.TraceInformation("[END] Inxed Local");
+                Log.Info("START");
+                try
+                {
+                    var fragmentsPath = Path.Combine(RootPath, FragmentsFolder);
+                    var directory = new DirectoryInfo(path);
+                    var files =
+                        from file in directory.EnumerateFiles("*", SearchOption.AllDirectories)
+                        where !file.FullName.StartsWith(fragmentsPath, StringComparison.InvariantCultureIgnoreCase) &&
+                              !file.Extension.Equals("ignore", StringComparison.InvariantCultureIgnoreCase)
+                        select file;
+                    StatusKeeper.ProcessExistingFiles(files);
+
+                }
+                catch (Exception exc)
+                {
+                    Log.Error("[ERROR]", exc);
+                }
+                finally
+                {
+                    Log.Info("[END]");
+                }
             }
         }
 
@@ -341,7 +347,7 @@ namespace Pithos.Core
                 var info = Directory.CreateDirectory(folder);
                 info.Attributes |= FileAttributes.Hidden;
 
-                Trace.TraceInformation("Created Fragments Folder: {0}", folder);
+                Log.InfoFormat("Created Fragments Folder: {0}", folder);
             }
             return folder;
         }
@@ -387,6 +393,20 @@ namespace Pithos.Core
         }
 
 
+        public void MoveFileStates(string oldPath, string newPath)
+        {
+            if (String.IsNullOrWhiteSpace(oldPath))
+                throw new ArgumentNullException("oldPath");
+            if (!Path.IsPathRooted(oldPath))
+                throw new ArgumentException("oldPath must be an absolute path","oldPath");
+            if (string.IsNullOrWhiteSpace(newPath))
+                throw new ArgumentNullException("newPath");
+            if (!Path.IsPathRooted(newPath))
+                throw new ArgumentException("newPath must be an absolute path","newPath");
+            Contract.EndContractBlock();
+
+            StatusKeeper.ChangeRoots(oldPath, newPath);
+        }
     }
 
     public interface IStatusNotification
index f542831..42fe041 100644 (file)
@@ -18,6 +18,7 @@ using System.Threading.Algorithms;
 using System.Threading.Tasks;
 using Newtonsoft.Json;
 using Pithos.Interfaces;
+using log4net;
 using WebHeaderCollection = System.Net.WebHeaderCollection;
 
 namespace Pithos.Network
@@ -62,7 +63,9 @@ namespace Pithos.Network
 
         private bool _authenticated = false;
 
-        //
+        private static readonly ILog Log = LogManager.GetLogger("CloudFilesClient");
+
+        
         public void Authenticate(string userName,string apiKey)
         {
             if (String.IsNullOrWhiteSpace(userName))
@@ -72,7 +75,7 @@ namespace Pithos.Network
             Contract.Ensures(_baseClient != null);
             Contract.EndContractBlock();
 
-            Trace.TraceInformation("[AUTHENTICATE] Start for {0}", userName);
+            Log.InfoFormat("[AUTHENTICATE] Start for {0}", userName);
 
             if (_authenticated)
                 return;
@@ -123,7 +126,7 @@ namespace Pithos.Network
             Contract.Assume(_baseClient.Headers!=null);
             _baseClient.Headers.Add("X-Auth-Token", Token);
 
-            Trace.TraceInformation("[AUTHENTICATE] End for {0}", userName);
+            Log.InfoFormat("[AUTHENTICATE] End for {0}", userName);
         }
 
 
@@ -156,29 +159,32 @@ namespace Pithos.Network
 
         public IList<ShareAccountInfo> ListSharingAccounts(DateTime? since=null)
         {
-            Trace.TraceInformation("[START] ListSharingAccounts");
-
-            using (var client = new RestClient(_baseClient))
+            using (log4net.ThreadContext.Stacks["Share"].Push("List Accounts"))
             {
-                client.Parameters.Clear();
-                client.Parameters.Add("format", "json");
-                client.IfModifiedSince = since;
+                if (Log.IsDebugEnabled) Log.DebugFormat("START");
 
-                //Extract the username from the base address
-                client.BaseAddress = RootAddressUri.AbsoluteUri;
-                
-                var content = client.DownloadStringWithRetry(@"", 3);
+                using (var client = new RestClient(_baseClient))
+                {
+                    client.Parameters.Clear();
+                    client.Parameters.Add("format", "json");
+                    client.IfModifiedSince = since;
 
-                client.AssertStatusOK("ListSharingAccounts failed");
+                    //Extract the username from the base address
+                    client.BaseAddress = RootAddressUri.AbsoluteUri;
 
-                //If the result is empty, return an empty list,
-                var infos = String.IsNullOrWhiteSpace(content)
-                    ? new List<ShareAccountInfo>()
-                    //Otherwise deserialize the account list into a list of ShareAccountInfos
-                    : JsonConvert.DeserializeObject<IList<ShareAccountInfo>>(content);
+                    var content = client.DownloadStringWithRetry(@"", 3);
 
-                Trace.TraceInformation("[END] ListSharingAccounts");
-                return infos;
+                    client.AssertStatusOK("ListSharingAccounts failed");
+
+                    //If the result is empty, return an empty list,
+                    var infos = String.IsNullOrWhiteSpace(content)
+                                    ? new List<ShareAccountInfo>()
+                                //Otherwise deserialize the account list into a list of ShareAccountInfos
+                                    : JsonConvert.DeserializeObject<IList<ShareAccountInfo>>(content);
+
+                    Log.DebugFormat("END");
+                    return infos;
+                }
             }
         }
 
@@ -187,20 +193,24 @@ namespace Pithos.Network
         public IList<ObjectInfo> ListSharedObjects(DateTime? since = null)
         {
 
-            Trace.TraceInformation("[START] ListSharedObjects");
-
-            var objects=new List<ObjectInfo>();
-            var accounts=ListSharingAccounts(since);
-            foreach (var account in accounts)
+            using (log4net.ThreadContext.Stacks["Share"].Push("List Objects"))
             {
-                var containers=ListContainers(account.name);
-                foreach (var container in containers)
+                if (Log.IsDebugEnabled) Log.DebugFormat("START");
+
+                var objects = new List<ObjectInfo>();
+                var accounts = ListSharingAccounts(since);
+                foreach (var account in accounts)
                 {
-                    var containerObjects=ListObjects(account.name, container.Name, account.last_modified);
-                    objects.AddRange(containerObjects);
+                    var containers = ListContainers(account.name);
+                    foreach (var container in containers)
+                    {
+                        var containerObjects = ListObjects(account.name, container.Name, account.last_modified);
+                        objects.AddRange(containerObjects);
+                    }
                 }
+                if (Log.IsDebugEnabled) Log.DebugFormat("END");
+                return objects;
             }
-            return objects;
         }
 
         public void ShareObject(string account, string container, string objectName, string shareTo, bool read, bool write)
@@ -219,35 +229,40 @@ namespace Pithos.Network
                 throw new ArgumentNullException("shareTo");
             Contract.EndContractBlock();
 
-            using (var client = new RestClient(_baseClient))
+            using (log4net.ThreadContext.Stacks["Share"].Push("Share Object"))
             {
-            
-                client.BaseAddress = GetAccountUrl(account);
+                if (Log.IsDebugEnabled) Log.DebugFormat("START");
+                
+                using (var client = new RestClient(_baseClient))
+                {
 
-                client.Parameters.Clear();
-                client.Parameters.Add("format", "json");
+                    client.BaseAddress = GetAccountUrl(account);
 
-                string permission = "";
-                if (write)
-                    permission = String.Format("write={0}", shareTo); 
-                else if (read)
-                    permission=String.Format("read={0}", shareTo);                
-                client.Headers.Add("X-Object-Sharing",permission);
-                
-                var content = client.DownloadStringWithRetry(container, 3);
+                    client.Parameters.Clear();
+                    client.Parameters.Add("format", "json");
+
+                    string permission = "";
+                    if (write)
+                        permission = String.Format("write={0}", shareTo);
+                    else if (read)
+                        permission = String.Format("read={0}", shareTo);
+                    client.Headers.Add("X-Object-Sharing", permission);
 
-                client.AssertStatusOK("ShareObject failed");
+                    var content = client.DownloadStringWithRetry(container, 3);
 
-                //If the result is empty, return an empty list,
-                var infos = String.IsNullOrWhiteSpace(content)
-                    ? new List<ObjectInfo>()
-                    //Otherwise deserialize the object list into a list of ObjectInfos
-                    : JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
+                    client.AssertStatusOK("ShareObject failed");
 
-                Trace.TraceInformation("[END] ListObjects");                
+                    //If the result is empty, return an empty list,
+                    var infos = String.IsNullOrWhiteSpace(content)
+                                    ? new List<ObjectInfo>()
+                                //Otherwise deserialize the object list into a list of ObjectInfos
+                                    : JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
+
+                    if (Log.IsDebugEnabled) Log.DebugFormat("END");
+                }
             }
 
-            
+
         }
 
 
@@ -257,33 +272,36 @@ namespace Pithos.Network
                 throw new ArgumentNullException("container");
             Contract.EndContractBlock();
 
-            Trace.TraceInformation("[START] ListObjects");
-
-            using (var client = new RestClient(_baseClient))
+            using (log4net.ThreadContext.Stacks["Objects"].Push("List"))
             {
-                if (!String.IsNullOrWhiteSpace(account))
-                    client.BaseAddress = GetAccountUrl(account);
+                if (Log.IsDebugEnabled) Log.DebugFormat("START");
 
-                client.Parameters.Clear();
-                client.Parameters.Add("format", "json");
-                client.IfModifiedSince = since;
-                var content = client.DownloadStringWithRetry(container, 3);
+                using (var client = new RestClient(_baseClient))
+                {
+                    if (!String.IsNullOrWhiteSpace(account))
+                        client.BaseAddress = GetAccountUrl(account);
 
-                client.AssertStatusOK("ListObjects failed");
+                    client.Parameters.Clear();
+                    client.Parameters.Add("format", "json");
+                    client.IfModifiedSince = since;
+                    var content = client.DownloadStringWithRetry(container, 3);
 
-                //If the result is empty, return an empty list,
-                var infos=String.IsNullOrWhiteSpace(content) 
-                    ? new List<ObjectInfo>() 
-                    //Otherwise deserialize the object list into a list of ObjectInfos
-                    : JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
+                    client.AssertStatusOK("ListObjects failed");
 
-                foreach (var info in infos)
-                {
-                    info.Container = container;
-                    info.Account = account;
+                    //If the result is empty, return an empty list,
+                    var infos = String.IsNullOrWhiteSpace(content)
+                                    ? new List<ObjectInfo>()
+                                //Otherwise deserialize the object list into a list of ObjectInfos
+                                    : JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
+
+                    foreach (var info in infos)
+                    {
+                        info.Container = container;
+                        info.Account = account;
+                    }
+                    if (Log.IsDebugEnabled) Log.DebugFormat("START");
+                    return infos;
                 }
-                Trace.TraceInformation("[END] ListObjects");
-                return infos;
             }
         }
 
@@ -297,24 +315,27 @@ namespace Pithos.Network
                 throw new ArgumentNullException("folder");
             Contract.EndContractBlock();
 
-            Trace.TraceInformation("[START] ListObjects");
-
-            using (var client = new RestClient(_baseClient))
+            using (log4net.ThreadContext.Stacks["Objects"].Push("List"))
             {
-                if (!String.IsNullOrWhiteSpace(account))
-                    client.BaseAddress = GetAccountUrl(account);
+                if (Log.IsDebugEnabled) Log.DebugFormat("START");
 
-                client.Parameters.Clear();
-                client.Parameters.Add("format", "json");
-                client.Parameters.Add("path", folder);
-                client.IfModifiedSince = since;
-                var content = client.DownloadStringWithRetry(container, 3);
-                client.AssertStatusOK("ListObjects failed");
+                using (var client = new RestClient(_baseClient))
+                {
+                    if (!String.IsNullOrWhiteSpace(account))
+                        client.BaseAddress = GetAccountUrl(account);
 
-                var infos = JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
+                    client.Parameters.Clear();
+                    client.Parameters.Add("format", "json");
+                    client.Parameters.Add("path", folder);
+                    client.IfModifiedSince = since;
+                    var content = client.DownloadStringWithRetry(container, 3);
+                    client.AssertStatusOK("ListObjects failed");
 
-                Trace.TraceInformation("[END] ListObjects");
-                return infos;
+                    var infos = JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
+
+                    if (Log.IsDebugEnabled) Log.DebugFormat("END");
+                    return infos;
+                }
             }
         }
 
@@ -325,24 +346,36 @@ namespace Pithos.Network
                 throw new ArgumentNullException("container", "The container property can't be empty");
             Contract.EndContractBlock();
 
-            using (var client = new RestClient(_baseClient))
+            using (log4net.ThreadContext.Stacks["Containters"].Push("Exists"))
             {
-                if (!String.IsNullOrWhiteSpace(account))
-                    client.BaseAddress = GetAccountUrl(account);
+                if (Log.IsDebugEnabled) Log.DebugFormat("START");
 
-                client.Parameters.Clear();
-                client.Head(container, 3);
-
-                switch (client.StatusCode)
+                using (var client = new RestClient(_baseClient))
                 {
-                    case HttpStatusCode.OK:
-                    case HttpStatusCode.NoContent:
-                        return true;
-                    case HttpStatusCode.NotFound:
-                        return false;
-                    default:
-                        throw CreateWebException("ContainerExists", client.StatusCode);
+                    if (!String.IsNullOrWhiteSpace(account))
+                        client.BaseAddress = GetAccountUrl(account);
+
+                    client.Parameters.Clear();
+                    client.Head(container, 3);
+                                        
+                    bool result;
+                    switch (client.StatusCode)
+                    {
+                        case HttpStatusCode.OK:
+                        case HttpStatusCode.NoContent:
+                            result=true;
+                            break;
+                        case HttpStatusCode.NotFound:
+                            result=false;
+                            break;
+                        default:
+                            throw CreateWebException("ContainerExists", client.StatusCode);
+                    }
+                    if (Log.IsDebugEnabled) Log.DebugFormat("END");
+
+                    return result;
                 }
+                
             }
         }
 
@@ -384,64 +417,68 @@ namespace Pithos.Network
                 throw new ArgumentNullException("objectName", "The objectName property can't be empty");
             Contract.EndContractBlock();
 
-            using (var client = new RestClient(_baseClient))
-            {
-                if (!String.IsNullOrWhiteSpace(account))
-                    client.BaseAddress = GetAccountUrl(account);                    
-                try
+            using (log4net.ThreadContext.Stacks["Objects"].Push("GetObjectInfo"))
+            {                
+
+                using (var client = new RestClient(_baseClient))
                 {
-                    client.Parameters.Clear();
+                    if (!String.IsNullOrWhiteSpace(account))
+                        client.BaseAddress = GetAccountUrl(account);
+                    try
+                    {
+                        client.Parameters.Clear();
 
-                    client.Head(container + "/" + objectName, 3);
+                        client.Head(container + "/" + objectName, 3);
 
-                    if (client.TimedOut)
-                        return ObjectInfo.Empty;
+                        if (client.TimedOut)
+                            return ObjectInfo.Empty;
 
-                    switch (client.StatusCode)
+                        switch (client.StatusCode)
+                        {
+                            case HttpStatusCode.OK:
+                            case HttpStatusCode.NoContent:
+                                var keys = client.ResponseHeaders.AllKeys.AsQueryable();
+                                var tags = (from key in keys
+                                            where key.StartsWith("X-Object-Meta-")
+                                            let name = key.Substring(14)
+                                            select new {Name = name, Value = client.ResponseHeaders[name]})
+                                    .ToDictionary(t => t.Name, t => t.Value);
+                                var extensions = (from key in keys
+                                                  where key.StartsWith("X-Object-") && !key.StartsWith("X-Object-Meta-")
+                                                  select new {Name = key, Value = client.ResponseHeaders[key]})
+                                    .ToDictionary(t => t.Name, t => t.Value);
+                                var info = new ObjectInfo
+                                               {
+                                                   Name = objectName,
+                                                   Hash = client.GetHeaderValue("ETag"),
+                                                   Content_Type = client.GetHeaderValue("Content-Type"),
+                                                   Tags = tags,
+                                                   Last_Modified = client.LastModified,
+                                                   Extensions = extensions
+                                               };
+                                return info;
+                            case HttpStatusCode.NotFound:
+                                return ObjectInfo.Empty;
+                            default:
+                                throw new WebException(
+                                    String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}",
+                                                  objectName, client.StatusCode));
+                        }
+
+                    }
+                    catch (RetryException)
                     {
-                        case HttpStatusCode.OK:
-                        case HttpStatusCode.NoContent:
-                            var keys = client.ResponseHeaders.AllKeys.AsQueryable();
-                            var tags = (from key in keys
-                                        where key.StartsWith("X-Object-Meta-")
-                                        let name = key.Substring(14)
-                                        select new {Name = name, Value = client.ResponseHeaders[name]})
-                                .ToDictionary(t => t.Name, t => t.Value);
-                            var extensions = (from key in keys
-                                              where key.StartsWith("X-Object-") && !key.StartsWith("X-Object-Meta-")                                              
-                                              select new {Name = key, Value = client.ResponseHeaders[key]})
-                                .ToDictionary(t => t.Name, t => t.Value);
-                            var info = new ObjectInfo
-                                                 {
-                                                     Name = objectName,
-                                                     Hash = client.GetHeaderValue("ETag"),
-                                                     Content_Type = client.GetHeaderValue("Content-Type"),
-                                                     Tags = tags,
-                                                     Last_Modified = client.LastModified,
-                                                     Extensions = extensions
-                                                 };
-                            return info;
-                        case HttpStatusCode.NotFound:
-                            return ObjectInfo.Empty;
-                        default:
-                            throw new WebException(
-                                String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}",
-                                              objectName, client.StatusCode));
+                        Log.WarnFormat("[RETRY FAIL] GetObjectInfo for {0} failed.");
+                        return ObjectInfo.Empty;
                     }
-
-                }
-                catch(RetryException)
-                {
-                    Trace.TraceWarning("[RETRY FAIL] GetObjectInfo for {0} failed.");
-                    return ObjectInfo.Empty;
-                }
-                catch(WebException e)
-                {
-                    Trace.TraceError(
-                        String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}",
-                                      objectName, client.StatusCode), e);
-                    throw;
-                }
+                    catch (WebException e)
+                    {
+                        Log.Error(
+                            String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}",
+                                          objectName, client.StatusCode), e);
+                        throw;
+                    }
+                }                
             }
 
         }
@@ -576,9 +613,9 @@ namespace Pithos.Network
                 var uri = builder.Uri;
 
                 //Download progress is reported to the Trace log
-                Trace.TraceInformation("[GET] START {0}", objectName);
+                Log.InfoFormat("[GET] START {0}", objectName);
                 client.DownloadProgressChanged += (sender, args) => 
-                    Trace.TraceInformation("[GET PROGRESS] {0} {1}% {2} of {3}",
+                    Log.InfoFormat("[GET PROGRESS] {0} {1}% {2} of {3}",
                                     fileName, args.ProgressPercentage,
                                     args.BytesReceived,
                                     args.TotalBytesToReceive);                                
@@ -595,18 +632,18 @@ namespace Pithos.Network
                                           //And report failure or completion
                                           if (download.IsFaulted)
                                           {
-                                              Trace.TraceError("[GET] FAIL for {0} with \r{1}", objectName,
+                                              Log.ErrorFormat("[GET] FAIL for {0} with \r{1}", objectName,
                                                                download.Exception);
                                           }
                                           else
                                           {
-                                              Trace.TraceInformation("[GET] END {0}", objectName);                                             
+                                              Log.InfoFormat("[GET] END {0}", objectName);                                             
                                           }
                                       });
             }
             catch (Exception exc)
             {
-                Trace.TraceError("[GET] END {0} with {1}", objectName, exc);
+                Log.ErrorFormat("[GET] END {0} with {1}", objectName, exc);
                 throw;
             }
 
@@ -692,7 +729,7 @@ namespace Pithos.Network
                 //Any other status code is unexpected but there was no exception. We can probably continue processing
                 else
                 {
-                    Trace.TraceWarning("Unexcpected status code when putting map: {0} - {1}",client.StatusCode,client.StatusDescription);                    
+                    Log.WarnFormat("Unexcpected status code when putting map: {0} - {1}",client.StatusCode,client.StatusDescription);                    
                 }
                 return empty;
             });
@@ -762,14 +799,14 @@ namespace Pithos.Network
 
             client.Headers[HttpRequestHeader.ContentType] = "application/octet-stream";
 
-            Trace.TraceInformation("[BLOCK POST] START");
+            Log.InfoFormat("[BLOCK POST] START");
 
             client.UploadProgressChanged += (sender, args) => 
-                Trace.TraceInformation("[BLOCK POST PROGRESS] {0}% {1} of {2}",
+                Log.InfoFormat("[BLOCK POST PROGRESS] {0}% {1} of {2}",
                                     args.ProgressPercentage, args.BytesSent,
                                     args.TotalBytesToSend);
             client.UploadFileCompleted += (sender, args) => 
-                Trace.TraceInformation("[BLOCK POST PROGRESS] Completed ");
+                Log.InfoFormat("[BLOCK POST PROGRESS] Completed ");
 
             
             //Send the block
@@ -781,11 +818,11 @@ namespace Pithos.Network
                 if (upload.IsFaulted)
                 {
                     var exception = upload.Exception.InnerException;
-                    Trace.TraceError("[BLOCK POST] FAIL with \r{0}", exception);                        
+                    Log.ErrorFormat("[BLOCK POST] FAIL with \r{0}", exception);                        
                     throw exception;
                 }
                     
-                Trace.TraceInformation("[BLOCK POST] END");
+                Log.InfoFormat("[BLOCK POST] END");
             });
             return uploadTask;            
         }
@@ -832,7 +869,7 @@ namespace Pithos.Network
                     //And report failure or completion
                     if (download.IsFaulted)
                     {
-                        Trace.TraceError("[GET HASH] FAIL for {0} with \r{1}", objectName,
+                        Log.ErrorFormat("[GET HASH] FAIL for {0} with \r{1}", objectName,
                                         download.Exception);
                         throw download.Exception;
                     }
@@ -840,13 +877,13 @@ namespace Pithos.Network
                     //The server will return an empty string if the file is empty
                     var json = download.Result;
                     var treeHash = TreeHash.Parse(json);
-                    Trace.TraceInformation("[GET HASH] END {0}", objectName);                                             
+                    Log.InfoFormat("[GET HASH] END {0}", objectName);                                             
                     return treeHash;
                 });
             }
             catch (Exception exc)
             {
-                Trace.TraceError("[GET HASH] END {0} with {1}", objectName, exc);
+                Log.ErrorFormat("[GET HASH] END {0} with {1}", objectName, exc);
                 throw;
             }
 
@@ -892,15 +929,22 @@ namespace Pithos.Network
                 client.Headers.Add("ETag", etag);
 
 
-                Trace.TraceInformation("[PUT] START {0}", objectName);
+                Log.InfoFormat("[PUT] START {0}", objectName);
                 client.UploadProgressChanged += (sender, args) =>
                 {
-                    Trace.TraceInformation("[PUT PROGRESS] {0} {1}% {2} of {3}", fileName, args.ProgressPercentage, args.BytesSent, args.TotalBytesToSend);
+                    using (log4net.ThreadContext.Stacks["PUT"].Push("Progress"))
+                    {
+                        Log.InfoFormat("{0} {1}% {2} of {3}", fileName, args.ProgressPercentage,
+                                       args.BytesSent, args.TotalBytesToSend);
+                    }
                 };
 
                 client.UploadFileCompleted += (sender, args) =>
                 {
-                    Trace.TraceInformation("[PUT PROGRESS] Completed {0}", fileName);
+                    using (log4net.ThreadContext.Stacks["PUT"].Push("Progress"))
+                    {
+                        Log.InfoFormat("Completed {0}", fileName);
+                    }
                 };
                 return client.UploadFileTask(uri, "PUT", fileName)
                     .ContinueWith(upload=>
@@ -910,16 +954,16 @@ namespace Pithos.Network
                                           if (upload.IsFaulted)
                                           {
                                               var exc = upload.Exception.InnerException;
-                                              Trace.TraceError("[PUT] FAIL for {0} with \r{1}",objectName,exc);
+                                              Log.ErrorFormat("[PUT] FAIL for {0} with \r{1}",objectName,exc);
                                               throw exc;
                                           }
                                           else
-                                            Trace.TraceInformation("[PUT] END {0}", objectName);
+                                            Log.InfoFormat("[PUT] END {0}", objectName);
                                       });
             }
             catch (Exception exc)
             {
-                Trace.TraceError("[PUT] END {0} with {1}", objectName, exc);
+                Log.ErrorFormat("[PUT] END {0} with {1}", objectName, exc);
                 throw;
             }                
 
index 20defa9..49df2fb 100644 (file)
     <CodeContractsAnalysisWarningLevel>2</CodeContractsAnalysisWarningLevel>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="log4net">
+      <HintPath>..\Libraries\log4net.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.ComponentModel.Composition" />
     <Reference Include="System.Core" />
index 8a0b984..ebcae22 100644 (file)
@@ -11,6 +11,7 @@ using System.IO;
 using System.Net;
 using System.Runtime.Serialization;
 using System.Threading.Tasks;
+using log4net;
 
 namespace Pithos.Network
 {
@@ -47,6 +48,9 @@ namespace Pithos.Network
             }            
         }
 
+        private static readonly ILog Log = LogManager.GetLogger("RestClient");
+
+
         [ContractInvariantMethod]
         private void Invariants()
         {
@@ -104,34 +108,27 @@ namespace Pithos.Network
 
         protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
         {
-            var response = (HttpWebResponse) base.GetWebResponse(request, result);            
-            StatusCode=response.StatusCode;
-            StatusDescription=response.StatusDescription;
-            return response;
+            return ProcessResponse(()=>base.GetWebResponse(request, result));
         }
 
-        private readonly List<HttpStatusCode> _allowedStatusCodes=new List<HttpStatusCode>{HttpStatusCode.NotModified};
-        public List<HttpStatusCode> AllowedStatusCodes
+        protected override WebResponse GetWebResponse(WebRequest request)
         {
-            get
-            {
-                return _allowedStatusCodes;
-            }            
+            return ProcessResponse(() => base.GetWebResponse(request));
         }
 
-        protected override WebResponse GetWebResponse(WebRequest request)
+        private WebResponse ProcessResponse(Func<WebResponse> getResponse)
         {
             try
-            {                
-                var response = (HttpWebResponse)base.GetWebResponse(request);
+            {
+                var response = (HttpWebResponse)getResponse();
                 StatusCode = response.StatusCode;
-                LastModified=response.LastModified;                
-                StatusDescription = response.StatusDescription;                
+                LastModified = response.LastModified;
+                StatusDescription = response.StatusDescription;
                 return response;
             }
             catch (WebException exc)
-            {                
-                if (exc.Response!=null)
+            {
+                if (exc.Response != null)
                 {
                     var response = (exc.Response as HttpWebResponse);
                     if (AllowedStatusCodes.Contains(response.StatusCode))
@@ -145,13 +142,22 @@ namespace Pithos.Network
                     if (exc.Response.ContentLength > 0)
                     {
                         string content = GetContent(exc.Response);
-                        Trace.TraceError(content);
+                        Log.ErrorFormat(content);
                     }
                 }
                 throw;
             }
         }
 
+        private readonly List<HttpStatusCode> _allowedStatusCodes=new List<HttpStatusCode>{HttpStatusCode.NotModified};
+        public List<HttpStatusCode> AllowedStatusCodes
+        {
+            get
+            {
+                return _allowedStatusCodes;
+            }            
+        }
+
         public DateTime LastModified { get; private set; }
 
         private static string GetContent(WebResponse webResponse)
@@ -263,25 +269,25 @@ namespace Pithos.Network
                 var exc = ex.InnerException;
                 if (exc is RetryException)
                 {
-                    Trace.TraceError("[{0}] RETRY FAILED for {1} after {2} retries",method,address,retries);
+                    Log.ErrorFormat("[{0}] RETRY FAILED for {1} after {2} retries",method,address,retries);
                 }
                 else
                 {
-                    Trace.TraceError("[{0}] FAILED for {1} with \n{2}", method, address, exc);
+                    Log.ErrorFormat("[{0}] FAILED for {1} with \n{2}", method, address, exc);
                 }
                 throw;
 
             }
             catch(Exception ex)
             {
-                Trace.TraceError("[{0}] FAILED for {1} with \n{2}", method, address, ex);
+                Log.ErrorFormat("[{0}] FAILED for {1} with \n{2}", method, address, ex);
                 throw;
             }
         }
         
         private static void TraceStart(string method, string actualAddress)
         {
-            Trace.WriteLine(String.Format("[{0}] {1} {2}", method, DateTime.Now, actualAddress));
+            Log.InfoFormat("[{0}] {1} {2}", method, DateTime.Now, actualAddress);
         }
 
         private string GetActualAddress(string address)
@@ -396,12 +402,12 @@ namespace Pithos.Network
                                 TimedOut = true;
                                 if (retryCount == 0)
                                 {                                    
-                                    Trace.TraceError("[ERROR] Timed out too many times. \n{0}\n",e);
+                                    Log.ErrorFormat("[ERROR] Timed out too many times. \n{0}\n",e);
                                     tcs.SetException(new RetryException("Timed out too many times.", e));                                    
                                 }
                                 else
                                 {
-                                    Trace.TraceError(
+                                    Log.ErrorFormat(
                                         "[RETRY] Timed out after {0} ms. Will retry {1} more times\n{2}", Timeout,
                                         retryCount, e);
                                     Retry(original, retryCount - 1, tcs);
index f4a8b22..4e87b31 100644 (file)
@@ -60,7 +60,7 @@ namespace Pithos.ShellExtensions
             }
             catch (Exception exc)
             {
-                Trace.TraceError("Composition Error: {0}",exc);
+                Log.ErrorFormat("Composition Error: {0}",exc);
                 throw;
             }
         }
index a7f2396..8bc2067 100644 (file)
@@ -371,7 +371,7 @@ namespace Pithos.ShellExtensions.Menus
 
             if (!NativeMethods.InsertMenu(hMenu, idCmdFirst, MF.MF_SEPARATOR | MF.MF_BYPOSITION, 0, String.Empty))
             {
-                Trace.TraceError("Error adding separator 1\r\n{0}", Marshal.GetLastWin32Error());
+                Log.ErrorFormat("Error adding separator 1\r\n{0}", Marshal.GetLastWin32Error());
                 return Marshal.GetHRForLastWin32Error();
             }
 
@@ -402,7 +402,7 @@ namespace Pithos.ShellExtensions.Menus
             sep.fType = MFT.MFT_SEPARATOR;*/
             if (!NativeMethods.InsertMenu(hMenu, (uint)_items.Values.Count + idCmdFirst+1,MF.MF_SEPARATOR|MF.MF_BYPOSITION, 0, String.Empty))
             {
-                Trace.TraceError("Error adding separator 1\r\n{0}", Marshal.GetLastWin32Error());
+                Log.ErrorFormat("Error adding separator 1\r\n{0}", Marshal.GetLastWin32Error());
                 return Marshal.GetHRForLastWin32Error();
             }
 
index 1874ae0..0095470 100644 (file)
@@ -140,7 +140,7 @@ namespace Pithos.ShellExtensions.Overlays
             catch (Exception ex)
             {
                 //Log and rethrow
-                Trace.TraceError("Failed to unregister overlay {0}:{1} with error {2}",iconName,type.GUID,ex.Message); 
+                Log.ErrorFormat("Failed to unregister overlay {0}:{1} with error {2}",iconName,type.GUID,ex.Message); 
                 throw;  
             }
         }
index 628466b..db4b7d2 100644 (file)
@@ -142,7 +142,7 @@ namespace Pithos.ShellExtensions
             }
             catch (Exception exc)
             {
-                Trace.TraceError("[ERROR] while loading settings:\r{0}",exc);
+                Log.ErrorFormat("[ERROR] while loading settings:\r{0}",exc);
                 _settings = new Lazy<IPithosSettings>(LoadSettings);
             }
             return null;
index 2464bc8..73ccac7 100644 (file)
@@ -39,7 +39,7 @@ namespace Pithos.ShellExtensions
             }
             catch (Exception exc)
             {
-                Trace.TraceError("[ERROR] retrieving overlay status for {0}:\r{1}",path,exc);
+                Log.ErrorFormat("[ERROR] retrieving overlay status for {0}:\r{1}",path,exc);
                 return FileOverlayStatus.Unversioned;
             }
         }