X-Git-Url: https://code.grnet.gr/git/pithos-ms-client/blobdiff_plain/aa7ac00e76724d9f37e85051b96137d2110183da..0f369429e94e6c8128658b8f45447abbb0b0a5ca:/trunk/Pithos.Core/PithosMonitor.cs diff --git a/trunk/Pithos.Core/PithosMonitor.cs b/trunk/Pithos.Core/PithosMonitor.cs index c9fae62..7ca5a30 100644 --- a/trunk/Pithos.Core/PithosMonitor.cs +++ b/trunk/Pithos.Core/PithosMonitor.cs @@ -40,25 +40,16 @@ */ #endregion using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel.Composition; -using System.Diagnostics; using System.Diagnostics.Contracts; using System.IO; using System.Linq; -using System.Net; -using System.Net.NetworkInformation; -using System.Security.Cryptography; -using System.ServiceModel.Description; -using System.Text; +using System.Reflection; using System.Threading; using System.Threading.Tasks; -using Castle.ActiveRecord.Queries; -using Microsoft.WindowsAPICodePack.Net; using Pithos.Core.Agents; using Pithos.Interfaces; -using System.ServiceModel; using Pithos.Network; using log4net; @@ -67,6 +58,8 @@ namespace Pithos.Core [Export(typeof(PithosMonitor))] public class PithosMonitor:IDisposable { + private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private int _blockSize; private string _blockHash; @@ -139,11 +132,10 @@ namespace Pithos.Core } private AccountInfo _accountInfo; - - - private static readonly ILog Log = LogManager.GetLogger(typeof(PithosMonitor)); + + public bool Pause @@ -152,16 +144,6 @@ namespace Pithos.Core set { FileAgent.Pause = value; - if (value) - { - StatusKeeper.SetPithosStatus(PithosStatus.SyncPaused); - StatusNotification.NotifyChange("Paused"); - } - else - { - StatusKeeper.SetPithosStatus(PithosStatus.InSynch); - StatusNotification.NotifyChange("Synchronizing"); - } } } @@ -183,7 +165,6 @@ namespace Pithos.Core public PithosMonitor() { FileAgent = new FileAgent(); - } private bool _started; @@ -211,13 +192,13 @@ namespace Pithos.Core return; } _cancellationSource = new CancellationTokenSource(); - - CloudClient=new CloudFilesClient(UserName,ApiKey); - CloudClient.UsePithos = true; - CloudClient.AuthenticationUrl = this.AuthenticationUrl; - - _accountInfo = CloudClient.Authenticate(); + lock (this) + { + CloudClient = new CloudFilesClient(UserName, ApiKey) + {UsePithos = true, AuthenticationUrl = AuthenticationUrl}; + _accountInfo = CloudClient.Authenticate(); + } _accountInfo.SiteUri = AuthenticationUrl; _accountInfo.AccountPath = RootPath; @@ -238,6 +219,12 @@ namespace Pithos.Core StatusKeeper.StartProcessing(_cancellationSource.Token); IndexLocalFiles(); + //Extract the URIs from the string collection + var settings = Settings.Accounts.First(s => s.AccountKey == _accountInfo.AccountKey ); + var selectiveUrls=settings.SelectiveFolders.Cast().Select(url => new Uri(url)).ToArray(); + + SetSelectivePaths(selectiveUrls,null,null); + StartWatcherAgent(); StartNetworkAgent(); @@ -253,11 +240,11 @@ namespace Pithos.Core var pithosContainers = new List{ FolderConstants.TrashContainer,FolderConstants.PithosContainer}; foreach (var container in pithosContainers) { - var info=CloudClient.GetContainerInfo(this.UserName, container); + var info=CloudClient.GetContainerInfo(UserName, container); if (info == ContainerInfo.Empty) { - CloudClient.CreateContainer(this.UserName, container); - info = CloudClient.GetContainerInfo(this.UserName, container); + CloudClient.CreateContainer(UserName, container); + info = CloudClient.GetContainerInfo(UserName, container); } _blockSize = info.BlockSize; _blockHash = info.BlockHash; @@ -270,12 +257,15 @@ namespace Pithos.Core private void IndexLocalFiles() { - StatusNotification.NotifyChange("Indexing Local Files",TraceLevel.Info); - using (log4net.ThreadContext.Stacks["Monitor"].Push("Indexing local files")) + using (ThreadContext.Stacks["Operation"].Push("Indexing local files")) { - Log.Info("START"); + try { + //StatusNotification.NotifyChange("Indexing Local Files"); + Log.Info("Start local indexing"); + StatusNotification.SetPithosStatus(PithosStatus.LocalSyncing,"Indexing Local Files"); + var cachePath = Path.Combine(RootPath, FolderConstants.CacheFolder); var directory = new DirectoryInfo(RootPath); var files = @@ -294,6 +284,7 @@ namespace Pithos.Core { Log.Info("[END]"); } + StatusNotification.SetPithosStatus(PithosStatus.LocalComplete,"Indexing Completed"); } } @@ -326,58 +317,24 @@ namespace Pithos.Core } }*/ - internal class LocalFileComparer:EqualityComparer - { - public override bool Equals(CloudAction x, CloudAction y) - { - if (x.Action != y.Action) - return false; - if (x.LocalFile != null && y.LocalFile != null && !x.LocalFile.FullName.Equals(y.LocalFile.FullName)) - return false; - if (x.CloudFile != null && y.CloudFile != null ) - { - if (x.CloudFile.Hash == null & y.CloudFile.Hash != null) - return false; - if (x.CloudFile.Hash != null & y.CloudFile.Hash == null) - return false; - if (x.CloudFile.Hash == null & y.CloudFile.Hash == null) - return (x.CloudFile.Name == y.CloudFile.Name); - if (!x.CloudFile.Hash.Equals(y.CloudFile.Hash)) - return false; - } - if (x.CloudFile == null ^ y.CloudFile == null || - x.LocalFile == null ^ y.LocalFile == null) - return false; - return true; - } - - public override int GetHashCode(CloudAction obj) - { - var hash1 = (obj.LocalFile == null) ? int.MaxValue : obj.LocalFile.FullName.GetHashCode(); - var hash2 = (obj.CloudFile == null) ? int.MaxValue : (obj.CloudFile.Hash ?? obj.CloudFile.Name??"").GetHashCode(); - var hash3 = obj.Action.GetHashCode(); - return hash1 ^ hash2 & hash3; - } - } - - private Timer timer; private void StartNetworkAgent() { - - NetworkAgent.AddAccount(_accountInfo); - NetworkAgent.StatusNotification = StatusNotification; - + + //TODO: The Network and Poll agents are not account specific + //They should be moved outside PithosMonitor NetworkAgent.Start(); + PollAgent.AddAccount(_accountInfo); + PollAgent.StatusNotification = StatusNotification; PollAgent.PollRemoteFiles(); } //Make sure a hidden cache folder exists to store partial downloads - private static string CreateHiddenFolder(string rootPath, string folderName) + private static void CreateHiddenFolder(string rootPath, string folderName) { if (String.IsNullOrWhiteSpace(rootPath)) throw new ArgumentNullException("rootPath"); @@ -404,7 +361,6 @@ namespace Pithos.Core Log.InfoFormat("Reset cache folder to hidden: {0}", folder); } } - return folder; } @@ -412,9 +368,14 @@ namespace Pithos.Core private void StartWatcherAgent() { - AgentLocator.Register(FileAgent,RootPath); + if (Log.IsDebugEnabled) + Log.DebugFormat("Start Folder Monitoring [{0}]",RootPath); + AgentLocator.Register(FileAgent,RootPath); + + FileAgent.IdleTimeout = Settings.FileIdleTimeout; FileAgent.StatusKeeper = StatusKeeper; + FileAgent.StatusNotification = StatusNotification; FileAgent.Workflow = Workflow; FileAgent.CachePath = Path.Combine(RootPath, FolderConstants.CacheFolder); FileAgent.Start(_accountInfo, RootPath); @@ -427,9 +388,6 @@ namespace Pithos.Core if (FileAgent!=null) FileAgent.Stop(); FileAgent = null; - if (timer != null) - timer.Dispose(); - timer = null; } @@ -468,29 +426,58 @@ namespace Pithos.Core StatusKeeper.ChangeRoots(oldPath, newPath); } - public void AddSelectivePaths(string[] added) + public void SetSelectivePaths(Uri[] uris,Uri[] added, Uri[] removed) { - /* FileAgent.SelectivePaths.AddRange(added); - NetworkAgent.SyncPaths(added);*/ + //Convert the uris to paths + var selectivePaths = UrisToFilePaths(uris); + + FileAgent.SelectivePaths=selectivePaths; + WorkflowAgent.SelectivePaths = selectivePaths; + PollAgent.SetSyncUris(_accountInfo.AccountKey,uris); + + var removedPaths = UrisToFilePaths(removed); + UnversionSelectivePaths(removedPaths); + } - public void RemoveSelectivePaths(string[] removed) + /// + /// Mark all unselected paths as Unversioned + /// + /// + private void UnversionSelectivePaths(List removed) { - FileAgent.SelectivePaths.RemoveAll(removed.Contains); - foreach (var removedPath in removed.Where(Directory.Exists)) - { - Directory.Delete(removedPath,true); - } + if (removed == null) + return; + + //Ensure we remove any file state below the deleted folders + FileState.UnversionPaths(removed); } - public IEnumerable GetRootFolders() + + /// + /// Return a list of absolute filepaths from a list of Uris + /// + /// + /// + private List UrisToFilePaths(IEnumerable uris) { - var dirs = from container in CloudClient.ListContainers(UserName) - from dir in CloudClient.ListObjects(UserName, container.Name, "") - select dir.Name; - return dirs; + if (uris == null) + return new List(); + + var own = (from uri in uris + where uri.ToString().StartsWith(_accountInfo.StorageUri.ToString()) + let relativePath = _accountInfo.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath() + //Trim the account name + select Path.Combine(RootPath, relativePath.After(_accountInfo.UserName + '\\'))).ToList(); + var others= (from uri in uris + where !uri.ToString().StartsWith(_accountInfo.StorageUri.ToString()) + let relativePath = _accountInfo.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath() + //Trim the account name + select Path.Combine(RootPath,"others-shared", relativePath)).ToList(); + return own.Union(others).ToList(); } + public ObjectInfo GetObjectInfo(string filePath) { if (String.IsNullOrWhiteSpace(filePath)) @@ -514,7 +501,7 @@ namespace Pithos.Core //Create the root URL for the target account var oldName = UserName; var absoluteUri = _accountInfo.StorageUri.AbsoluteUri; - var nameIndex=absoluteUri.IndexOf(oldName); + var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal); var root=absoluteUri.Substring(0, nameIndex); accountInfo = new AccountInfo @@ -529,7 +516,7 @@ namespace Pithos.Core } else { - accountName = this.UserName; + accountName = UserName; container = parts[0]; relativeUrl = String.Join("/", parts.Splice(1)); } @@ -560,7 +547,7 @@ namespace Pithos.Core //Create the root URL for the target account var oldName = UserName; var absoluteUri = _accountInfo.StorageUri.AbsoluteUri; - var nameIndex=absoluteUri.IndexOf(oldName); + var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal); var root=absoluteUri.Substring(0, nameIndex); accountInfo = new AccountInfo