Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / PithosMonitor.cs @ 8f44fd3a

History | View | Annotate | Download (19.8 kB)

1 255f5f86 Panagiotis Kanavos
#region
2 255f5f86 Panagiotis Kanavos
/* -----------------------------------------------------------------------
3 255f5f86 Panagiotis Kanavos
 * <copyright file="PithosMonitor.cs" company="GRNet">
4 255f5f86 Panagiotis Kanavos
 * 
5 255f5f86 Panagiotis Kanavos
 * Copyright 2011-2012 GRNET S.A. All rights reserved.
6 255f5f86 Panagiotis Kanavos
 *
7 255f5f86 Panagiotis Kanavos
 * Redistribution and use in source and binary forms, with or
8 255f5f86 Panagiotis Kanavos
 * without modification, are permitted provided that the following
9 255f5f86 Panagiotis Kanavos
 * conditions are met:
10 255f5f86 Panagiotis Kanavos
 *
11 255f5f86 Panagiotis Kanavos
 *   1. Redistributions of source code must retain the above
12 255f5f86 Panagiotis Kanavos
 *      copyright notice, this list of conditions and the following
13 255f5f86 Panagiotis Kanavos
 *      disclaimer.
14 255f5f86 Panagiotis Kanavos
 *
15 255f5f86 Panagiotis Kanavos
 *   2. Redistributions in binary form must reproduce the above
16 255f5f86 Panagiotis Kanavos
 *      copyright notice, this list of conditions and the following
17 255f5f86 Panagiotis Kanavos
 *      disclaimer in the documentation and/or other materials
18 255f5f86 Panagiotis Kanavos
 *      provided with the distribution.
19 255f5f86 Panagiotis Kanavos
 *
20 255f5f86 Panagiotis Kanavos
 *
21 255f5f86 Panagiotis Kanavos
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22 255f5f86 Panagiotis Kanavos
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 255f5f86 Panagiotis Kanavos
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 255f5f86 Panagiotis Kanavos
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25 255f5f86 Panagiotis Kanavos
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 255f5f86 Panagiotis Kanavos
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 255f5f86 Panagiotis Kanavos
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 255f5f86 Panagiotis Kanavos
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 255f5f86 Panagiotis Kanavos
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 255f5f86 Panagiotis Kanavos
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 255f5f86 Panagiotis Kanavos
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 255f5f86 Panagiotis Kanavos
 * POSSIBILITY OF SUCH DAMAGE.
33 255f5f86 Panagiotis Kanavos
 *
34 255f5f86 Panagiotis Kanavos
 * The views and conclusions contained in the software and
35 255f5f86 Panagiotis Kanavos
 * documentation are those of the authors and should not be
36 255f5f86 Panagiotis Kanavos
 * interpreted as representing official policies, either expressed
37 255f5f86 Panagiotis Kanavos
 * or implied, of GRNET S.A.
38 255f5f86 Panagiotis Kanavos
 * </copyright>
39 255f5f86 Panagiotis Kanavos
 * -----------------------------------------------------------------------
40 255f5f86 Panagiotis Kanavos
 */
41 255f5f86 Panagiotis Kanavos
#endregion
42 d78cbf09 Panagiotis Kanavos
using System;
43 d78cbf09 Panagiotis Kanavos
using System.Collections.Generic;
44 d78cbf09 Panagiotis Kanavos
using System.ComponentModel.Composition;
45 d78cbf09 Panagiotis Kanavos
using System.Diagnostics.Contracts;
46 d78cbf09 Panagiotis Kanavos
using System.IO;
47 d78cbf09 Panagiotis Kanavos
using System.Linq;
48 db8a9589 Panagiotis Kanavos
using System.Reflection;
49 d78cbf09 Panagiotis Kanavos
using System.Threading;
50 d78cbf09 Panagiotis Kanavos
using System.Threading.Tasks;
51 9c4346c9 Panagiotis Kanavos
using Pithos.Core.Agents;
52 d78cbf09 Panagiotis Kanavos
using Pithos.Interfaces;
53 5ce54458 Panagiotis Kanavos
using Pithos.Network;
54 5120f3cb Panagiotis Kanavos
using log4net;
55 d78cbf09 Panagiotis Kanavos
56 d78cbf09 Panagiotis Kanavos
namespace Pithos.Core
57 d78cbf09 Panagiotis Kanavos
{
58 d78cbf09 Panagiotis Kanavos
    [Export(typeof(PithosMonitor))]
59 d78cbf09 Panagiotis Kanavos
    public class PithosMonitor:IDisposable
60 d78cbf09 Panagiotis Kanavos
    {
61 db8a9589 Panagiotis Kanavos
        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62 db8a9589 Panagiotis Kanavos
63 5ce54458 Panagiotis Kanavos
        private int _blockSize;
64 5ce54458 Panagiotis Kanavos
        private string _blockHash;
65 5ce54458 Panagiotis Kanavos
66 d78cbf09 Panagiotis Kanavos
        [Import]
67 d78cbf09 Panagiotis Kanavos
        public IPithosSettings Settings{get;set;}
68 d78cbf09 Panagiotis Kanavos
69 4ec636f6 Panagiotis Kanavos
        private IStatusKeeper _statusKeeper;
70 4ec636f6 Panagiotis Kanavos
71 d78cbf09 Panagiotis Kanavos
        [Import]
72 4ec636f6 Panagiotis Kanavos
        public IStatusKeeper StatusKeeper
73 4ec636f6 Panagiotis Kanavos
        {
74 4ec636f6 Panagiotis Kanavos
            get { return _statusKeeper; }
75 4ec636f6 Panagiotis Kanavos
            set
76 4ec636f6 Panagiotis Kanavos
            {
77 4ec636f6 Panagiotis Kanavos
                _statusKeeper = value;
78 4ec636f6 Panagiotis Kanavos
                FileAgent.StatusKeeper = value;
79 4ec636f6 Panagiotis Kanavos
            }
80 4ec636f6 Panagiotis Kanavos
        }
81 4ec636f6 Panagiotis Kanavos
82 4ec636f6 Panagiotis Kanavos
83 4ec636f6 Panagiotis Kanavos
        private IPithosWorkflow _workflow;
84 d78cbf09 Panagiotis Kanavos
85 d78cbf09 Panagiotis Kanavos
        [Import]
86 4ec636f6 Panagiotis Kanavos
        public IPithosWorkflow Workflow
87 4ec636f6 Panagiotis Kanavos
        {
88 4ec636f6 Panagiotis Kanavos
            get { return _workflow; }
89 4ec636f6 Panagiotis Kanavos
            set
90 4ec636f6 Panagiotis Kanavos
            {
91 4ec636f6 Panagiotis Kanavos
                _workflow = value;
92 4ec636f6 Panagiotis Kanavos
                FileAgent.Workflow = value;
93 4ec636f6 Panagiotis Kanavos
            }
94 4ec636f6 Panagiotis Kanavos
        }
95 d78cbf09 Panagiotis Kanavos
96 d78cbf09 Panagiotis Kanavos
        public ICloudClient CloudClient { get; set; }
97 d78cbf09 Panagiotis Kanavos
98 0c02aa65 Panagiotis Kanavos
        public IStatusNotification StatusNotification { get; set; }
99 0c02aa65 Panagiotis Kanavos
100 4ec636f6 Panagiotis Kanavos
        //[Import]
101 4ec636f6 Panagiotis Kanavos
        public FileAgent FileAgent { get; private set; }
102 4ec636f6 Panagiotis Kanavos
103 4ec636f6 Panagiotis Kanavos
        private WorkflowAgent _workflowAgent;
104 4ec636f6 Panagiotis Kanavos
105 9c4346c9 Panagiotis Kanavos
        [Import]
106 4ec636f6 Panagiotis Kanavos
        public WorkflowAgent WorkflowAgent
107 4ec636f6 Panagiotis Kanavos
        {
108 4ec636f6 Panagiotis Kanavos
            get { return _workflowAgent; }
109 4ec636f6 Panagiotis Kanavos
            set
110 4ec636f6 Panagiotis Kanavos
            {
111 4ec636f6 Panagiotis Kanavos
                _workflowAgent = value;
112 4ec636f6 Panagiotis Kanavos
                FileAgent.WorkflowAgent = value;
113 4ec636f6 Panagiotis Kanavos
            }
114 4ec636f6 Panagiotis Kanavos
        }
115 9c4346c9 Panagiotis Kanavos
        
116 9c4346c9 Panagiotis Kanavos
        [Import]
117 aa7ac00e Panagiotis Kanavos
        public NetworkAgent NetworkAgent { get; set; }
118 aa7ac00e Panagiotis Kanavos
        [Import]
119 aa7ac00e Panagiotis Kanavos
        public PollAgent PollAgent { get; set; }       
120 9c4346c9 Panagiotis Kanavos
121 0eea575a Panagiotis Kanavos
        public string UserName { get; set; }
122 c92e02f3 Panagiotis Kanavos
        private string _apiKey;
123 c92e02f3 Panagiotis Kanavos
        public string ApiKey
124 c92e02f3 Panagiotis Kanavos
        {
125 c92e02f3 Panagiotis Kanavos
            get { return _apiKey; }
126 c92e02f3 Panagiotis Kanavos
            set
127 c92e02f3 Panagiotis Kanavos
            {
128 c92e02f3 Panagiotis Kanavos
                _apiKey = value;
129 c92e02f3 Panagiotis Kanavos
                if (_accountInfo != null)
130 c92e02f3 Panagiotis Kanavos
                    _accountInfo.Token = value;
131 c92e02f3 Panagiotis Kanavos
            }
132 c92e02f3 Panagiotis Kanavos
        }
133 0eea575a Panagiotis Kanavos
134 0bd56b7c Panagiotis Kanavos
        private AccountInfo _accountInfo;
135 c53aa229 Panagiotis Kanavos
136 eeee29e3 Panagiotis Kanavos
137 db8a9589 Panagiotis Kanavos
138 db8a9589 Panagiotis Kanavos
139 5120f3cb Panagiotis Kanavos
140 d78cbf09 Panagiotis Kanavos
141 d78cbf09 Panagiotis Kanavos
        public bool Pause
142 d78cbf09 Panagiotis Kanavos
        {
143 5ce54458 Panagiotis Kanavos
            get { return FileAgent.Pause; }
144 d78cbf09 Panagiotis Kanavos
            set
145 d78cbf09 Panagiotis Kanavos
            {
146 5ce54458 Panagiotis Kanavos
                FileAgent.Pause = value;
147 d78cbf09 Panagiotis Kanavos
            }
148 d78cbf09 Panagiotis Kanavos
        }
149 d78cbf09 Panagiotis Kanavos
150 c28a075a Panagiotis Kanavos
        private string _rootPath;
151 c28a075a Panagiotis Kanavos
        public string RootPath
152 c28a075a Panagiotis Kanavos
        {
153 c28a075a Panagiotis Kanavos
            get { return _rootPath; }
154 7e26c075 Panagiotis Kanavos
            set 
155 c28a075a Panagiotis Kanavos
            {
156 7e26c075 Panagiotis Kanavos
                _rootPath = String.IsNullOrWhiteSpace(value) 
157 7e26c075 Panagiotis Kanavos
                    ? String.Empty 
158 7e26c075 Panagiotis Kanavos
                    : value.ToLower();
159 c28a075a Panagiotis Kanavos
            }
160 c28a075a Panagiotis Kanavos
        }
161 0eea575a Panagiotis Kanavos
162 d78cbf09 Panagiotis Kanavos
163 d78cbf09 Panagiotis Kanavos
        CancellationTokenSource _cancellationSource;
164 d78cbf09 Panagiotis Kanavos
165 4ec636f6 Panagiotis Kanavos
        public PithosMonitor()
166 4ec636f6 Panagiotis Kanavos
        {
167 5d7b20e8 Panagiotis Kanavos
            FileAgent = new FileAgent();
168 4ec636f6 Panagiotis Kanavos
        }
169 7e26c075 Panagiotis Kanavos
        private bool _started;
170 d78cbf09 Panagiotis Kanavos
171 d78cbf09 Panagiotis Kanavos
        public void Start()
172 c53aa229 Panagiotis Kanavos
        {            
173 c53aa229 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(ApiKey))
174 c53aa229 Panagiotis Kanavos
                throw new InvalidOperationException("The ApiKey is empty");
175 c53aa229 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(UserName))
176 c53aa229 Panagiotis Kanavos
                throw new InvalidOperationException("The UserName is empty");
177 c53aa229 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(AuthenticationUrl))
178 c53aa229 Panagiotis Kanavos
                throw new InvalidOperationException("The Authentication url is empty");
179 c53aa229 Panagiotis Kanavos
            Contract.EndContractBlock();
180 c53aa229 Panagiotis Kanavos
181 437abfca Panagiotis Kanavos
            //If the account doesn't have a valid path, don't start monitoring but don't throw either
182 437abfca Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(RootPath))
183 437abfca Panagiotis Kanavos
                //TODO; Warn user?
184 437abfca Panagiotis Kanavos
                return;
185 437abfca Panagiotis Kanavos
186 70f12b36 Panagiotis Kanavos
            WorkflowAgent.StatusNotification = StatusNotification;
187 70f12b36 Panagiotis Kanavos
188 0c02aa65 Panagiotis Kanavos
            StatusNotification.NotifyChange("Starting");
189 7e26c075 Panagiotis Kanavos
            if (_started)
190 d78cbf09 Panagiotis Kanavos
            {
191 d78cbf09 Panagiotis Kanavos
                if (!_cancellationSource.IsCancellationRequested)
192 d78cbf09 Panagiotis Kanavos
                    return;
193 d78cbf09 Panagiotis Kanavos
            }
194 29672672 Panagiotis Kanavos
            _cancellationSource = new CancellationTokenSource();
195 d78cbf09 Panagiotis Kanavos
196 8f44fd3a pkanavos
            lock (this)
197 8f44fd3a pkanavos
            {
198 8f44fd3a pkanavos
                CloudClient = new CloudFilesClient(UserName, ApiKey)
199 8f44fd3a pkanavos
                                  {UsePithos = true, AuthenticationUrl = AuthenticationUrl};
200 8f44fd3a pkanavos
                _accountInfo = CloudClient.Authenticate();
201 8f44fd3a pkanavos
            }
202 23821bd2 Panagiotis Kanavos
            _accountInfo.SiteUri = AuthenticationUrl;
203 c53aa229 Panagiotis Kanavos
            _accountInfo.AccountPath = RootPath;
204 c53aa229 Panagiotis Kanavos
205 5750d7cc Panagiotis Kanavos
206 5750d7cc Panagiotis Kanavos
            var pithosFolder = Path.Combine(RootPath, FolderConstants.PithosContainer);
207 5750d7cc Panagiotis Kanavos
            if (!Directory.Exists(pithosFolder))
208 5750d7cc Panagiotis Kanavos
                Directory.CreateDirectory(pithosFolder);
209 77e10b4f Panagiotis Kanavos
            //Create the cache folder and ensure it is hidden
210 77e10b4f Panagiotis Kanavos
            CreateHiddenFolder(RootPath, FolderConstants.CacheFolder);
211 77e10b4f Panagiotis Kanavos
212 0bd56b7c Panagiotis Kanavos
            var policy=CloudClient.GetAccountPolicies(_accountInfo);
213 c53aa229 Panagiotis Kanavos
214 0bd56b7c Panagiotis Kanavos
            StatusNotification.NotifyAccount(policy);
215 3c43ec9b Panagiotis Kanavos
            EnsurePithosContainers();
216 9c4346c9 Panagiotis Kanavos
            
217 5ce54458 Panagiotis Kanavos
            StatusKeeper.BlockHash = _blockHash;
218 5ce54458 Panagiotis Kanavos
            StatusKeeper.BlockSize = _blockSize;
219 9c4346c9 Panagiotis Kanavos
            
220 3c43ec9b Panagiotis Kanavos
            StatusKeeper.StartProcessing(_cancellationSource.Token);
221 c28a075a Panagiotis Kanavos
            IndexLocalFiles();
222 759bd3c4 Panagiotis Kanavos
            //Extract the URIs from the string collection
223 ebc37b0d pkanavos
            var settings = Settings.Accounts.First(s => s.AccountKey == _accountInfo.AccountKey );
224 fec5da06 Panagiotis Kanavos
            var selectiveUrls=settings.SelectiveFolders.Cast<string>().Select(url => new Uri(url)).ToArray();
225 759bd3c4 Panagiotis Kanavos
226 759bd3c4 Panagiotis Kanavos
            SetSelectivePaths(selectiveUrls,null,null);
227 759bd3c4 Panagiotis Kanavos
            
228 c28a075a Panagiotis Kanavos
            StartWatcherAgent();
229 c53aa229 Panagiotis Kanavos
230 c53aa229 Panagiotis Kanavos
            StartNetworkAgent();
231 70f12b36 Panagiotis Kanavos
            
232 c92e02f3 Panagiotis Kanavos
            WorkflowAgent.RestartInterruptedFiles(_accountInfo);
233 c92e02f3 Panagiotis Kanavos
            _started = true;
234 29672672 Panagiotis Kanavos
        }
235 29672672 Panagiotis Kanavos
236 3c43ec9b Panagiotis Kanavos
        private void EnsurePithosContainers()
237 3c43ec9b Panagiotis Kanavos
        {
238 3c43ec9b Panagiotis Kanavos
239 cfed7823 Panagiotis Kanavos
            //Create the two default containers if they are missing
240 c53aa229 Panagiotis Kanavos
            var pithosContainers = new List<string>{ FolderConstants.TrashContainer,FolderConstants.PithosContainer};
241 3c43ec9b Panagiotis Kanavos
            foreach (var container in pithosContainers)
242 cfed7823 Panagiotis Kanavos
            {                
243 c636df1f Panagiotis Kanavos
                var info=CloudClient.GetContainerInfo(UserName, container);
244 5ce54458 Panagiotis Kanavos
                if (info == ContainerInfo.Empty)
245 5ce54458 Panagiotis Kanavos
                {
246 c636df1f Panagiotis Kanavos
                    CloudClient.CreateContainer(UserName, container);
247 c636df1f Panagiotis Kanavos
                    info = CloudClient.GetContainerInfo(UserName, container);
248 5ce54458 Panagiotis Kanavos
                }
249 5ce54458 Panagiotis Kanavos
                _blockSize = info.BlockSize;
250 5ce54458 Panagiotis Kanavos
                _blockHash = info.BlockHash;
251 c53aa229 Panagiotis Kanavos
                _accountInfo.BlockSize = _blockSize;
252 c53aa229 Panagiotis Kanavos
                _accountInfo.BlockHash = _blockHash;
253 3c43ec9b Panagiotis Kanavos
            }
254 3c43ec9b Panagiotis Kanavos
        }
255 3c43ec9b Panagiotis Kanavos
256 79736291 Panagiotis Kanavos
        public string AuthenticationUrl { get; set; }
257 79736291 Panagiotis Kanavos
258 c28a075a Panagiotis Kanavos
        private void IndexLocalFiles()
259 b5061ac8 Panagiotis Kanavos
        {
260 6bcdd8e2 Panagiotis Kanavos
            using (ThreadContext.Stacks["Operation"].Push("Indexing local files"))
261 b5061ac8 Panagiotis Kanavos
            {
262 174bbb6e Panagiotis Kanavos
                
263 5120f3cb Panagiotis Kanavos
                try
264 5120f3cb Panagiotis Kanavos
                {
265 174bbb6e Panagiotis Kanavos
                    //StatusNotification.NotifyChange("Indexing Local Files");
266 174bbb6e Panagiotis Kanavos
                    Log.Info("Start local indexing");
267 174bbb6e Panagiotis Kanavos
                    StatusNotification.SetPithosStatus(PithosStatus.LocalSyncing,"Indexing Local Files");                    
268 174bbb6e Panagiotis Kanavos
269 77e10b4f Panagiotis Kanavos
                    var cachePath = Path.Combine(RootPath, FolderConstants.CacheFolder);
270 c28a075a Panagiotis Kanavos
                    var directory = new DirectoryInfo(RootPath);
271 5120f3cb Panagiotis Kanavos
                    var files =
272 5120f3cb Panagiotis Kanavos
                        from file in directory.EnumerateFiles("*", SearchOption.AllDirectories)
273 77e10b4f Panagiotis Kanavos
                        where !file.FullName.StartsWith(cachePath, StringComparison.InvariantCultureIgnoreCase) &&
274 5120f3cb Panagiotis Kanavos
                              !file.Extension.Equals("ignore", StringComparison.InvariantCultureIgnoreCase)
275 5120f3cb Panagiotis Kanavos
                        select file;
276 5120f3cb Panagiotis Kanavos
                    StatusKeeper.ProcessExistingFiles(files);
277 5120f3cb Panagiotis Kanavos
278 5120f3cb Panagiotis Kanavos
                }
279 5120f3cb Panagiotis Kanavos
                catch (Exception exc)
280 5120f3cb Panagiotis Kanavos
                {
281 5120f3cb Panagiotis Kanavos
                    Log.Error("[ERROR]", exc);
282 5120f3cb Panagiotis Kanavos
                }
283 5120f3cb Panagiotis Kanavos
                finally
284 5120f3cb Panagiotis Kanavos
                {
285 5120f3cb Panagiotis Kanavos
                    Log.Info("[END]");
286 5120f3cb Panagiotis Kanavos
                }
287 174bbb6e Panagiotis Kanavos
                StatusNotification.SetPithosStatus(PithosStatus.LocalComplete,"Indexing Completed");
288 b5061ac8 Panagiotis Kanavos
            }
289 b5061ac8 Panagiotis Kanavos
        }
290 b5061ac8 Panagiotis Kanavos
291 9c4346c9 Panagiotis Kanavos
        
292 c53aa229 Panagiotis Kanavos
  
293 eeee29e3 Panagiotis Kanavos
294 eeee29e3 Panagiotis Kanavos
295 70f12b36 Panagiotis Kanavos
       /* private void StartWorkflowAgent()
296 29672672 Panagiotis Kanavos
        {
297 65282d58 Panagiotis Kanavos
            WorkflowAgent.StatusNotification = StatusNotification;
298 65282d58 Panagiotis Kanavos
299 65282d58 Panagiotis Kanavos
/*            //On Vista and up we can check for a network connection
300 56b53955 Panagiotis Kanavos
            bool connected=Environment.OSVersion.Version.Major < 6 || NetworkListManager.IsConnectedToInternet;
301 29672672 Panagiotis Kanavos
            //If we are not connected retry later
302 29672672 Panagiotis Kanavos
            if (!connected)
303 29672672 Panagiotis Kanavos
            {
304 9c4346c9 Panagiotis Kanavos
                Task.Factory.StartNewDelayed(10000, StartWorkflowAgent);
305 29672672 Panagiotis Kanavos
                return;
306 70f12b36 Panagiotis Kanavos
            }#1#
307 29672672 Panagiotis Kanavos
308 29672672 Panagiotis Kanavos
            try
309 29672672 Panagiotis Kanavos
            {
310 9c4346c9 Panagiotis Kanavos
                WorkflowAgent.Start();                
311 29672672 Panagiotis Kanavos
            }
312 29672672 Panagiotis Kanavos
            catch (Exception)
313 29672672 Panagiotis Kanavos
            {
314 29672672 Panagiotis Kanavos
                //Faild to authenticate due to network or account error
315 29672672 Panagiotis Kanavos
                //Retry after a while
316 9c4346c9 Panagiotis Kanavos
                Task.Factory.StartNewDelayed(10000, StartWorkflowAgent);
317 29672672 Panagiotis Kanavos
            }
318 70f12b36 Panagiotis Kanavos
        }*/
319 d78cbf09 Panagiotis Kanavos
320 174bbb6e Panagiotis Kanavos
321 c53aa229 Panagiotis Kanavos
        private void StartNetworkAgent()
322 d78cbf09 Panagiotis Kanavos
        {
323 9c4346c9 Panagiotis Kanavos
            NetworkAgent.StatusNotification = StatusNotification;
324 174bbb6e Panagiotis Kanavos
325 174bbb6e Panagiotis Kanavos
            //TODO: The Network and Poll agents are not account specific
326 174bbb6e Panagiotis Kanavos
            //They should be moved outside PithosMonitor
327 c53aa229 Panagiotis Kanavos
            NetworkAgent.Start();
328 d78cbf09 Panagiotis Kanavos
329 fec5da06 Panagiotis Kanavos
            PollAgent.AddAccount(_accountInfo);
330 fec5da06 Panagiotis Kanavos
331 aa7ac00e Panagiotis Kanavos
            PollAgent.StatusNotification = StatusNotification;
332 aa7ac00e Panagiotis Kanavos
333 aa7ac00e Panagiotis Kanavos
            PollAgent.PollRemoteFiles();
334 d78cbf09 Panagiotis Kanavos
        }
335 d78cbf09 Panagiotis Kanavos
336 77e10b4f Panagiotis Kanavos
        //Make sure a hidden cache folder exists to store partial downloads
337 c636df1f Panagiotis Kanavos
        private static void CreateHiddenFolder(string rootPath, string folderName)
338 5ce54458 Panagiotis Kanavos
        {
339 5ce54458 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(rootPath))
340 5ce54458 Panagiotis Kanavos
                throw new ArgumentNullException("rootPath");
341 5ce54458 Panagiotis Kanavos
            if (!Path.IsPathRooted(rootPath))
342 5ce54458 Panagiotis Kanavos
                throw new ArgumentException("rootPath");
343 5ce54458 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(folderName))
344 5ce54458 Panagiotis Kanavos
                throw new ArgumentNullException("folderName");
345 5ce54458 Panagiotis Kanavos
            Contract.EndContractBlock();
346 5ce54458 Panagiotis Kanavos
347 5ce54458 Panagiotis Kanavos
            var folder = Path.Combine(rootPath, folderName);
348 5ce54458 Panagiotis Kanavos
            if (!Directory.Exists(folder))
349 5ce54458 Panagiotis Kanavos
            {
350 5ce54458 Panagiotis Kanavos
                var info = Directory.CreateDirectory(folder);
351 5ce54458 Panagiotis Kanavos
                info.Attributes |= FileAttributes.Hidden;
352 5ce54458 Panagiotis Kanavos
353 77e10b4f Panagiotis Kanavos
                Log.InfoFormat("Created cache Folder: {0}", folder);
354 77e10b4f Panagiotis Kanavos
            }
355 77e10b4f Panagiotis Kanavos
            else
356 77e10b4f Panagiotis Kanavos
            {
357 77e10b4f Panagiotis Kanavos
                var info = new DirectoryInfo(folder);
358 77e10b4f Panagiotis Kanavos
                if ((info.Attributes & FileAttributes.Hidden) == 0)
359 77e10b4f Panagiotis Kanavos
                {
360 77e10b4f Panagiotis Kanavos
                    info.Attributes |= FileAttributes.Hidden;
361 77e10b4f Panagiotis Kanavos
                    Log.InfoFormat("Reset cache folder to hidden: {0}", folder);
362 77e10b4f Panagiotis Kanavos
                }                                
363 5ce54458 Panagiotis Kanavos
            }
364 5ce54458 Panagiotis Kanavos
        }
365 5ce54458 Panagiotis Kanavos
366 b5061ac8 Panagiotis Kanavos
       
367 d78cbf09 Panagiotis Kanavos
368 d78cbf09 Panagiotis Kanavos
369 c28a075a Panagiotis Kanavos
        private void StartWatcherAgent()
370 d78cbf09 Panagiotis Kanavos
        {
371 174bbb6e Panagiotis Kanavos
            if (Log.IsDebugEnabled)
372 174bbb6e Panagiotis Kanavos
                Log.DebugFormat("Start Folder Monitoring [{0}]",RootPath);
373 174bbb6e Panagiotis Kanavos
374 c28a075a Panagiotis Kanavos
            AgentLocator<FileAgent>.Register(FileAgent,RootPath);
375 5d7b20e8 Panagiotis Kanavos
            
376 5d7b20e8 Panagiotis Kanavos
            FileAgent.IdleTimeout = Settings.FileIdleTimeout;
377 5ce54458 Panagiotis Kanavos
            FileAgent.StatusKeeper = StatusKeeper;
378 174bbb6e Panagiotis Kanavos
            FileAgent.StatusNotification = StatusNotification;
379 5ce54458 Panagiotis Kanavos
            FileAgent.Workflow = Workflow;
380 77e10b4f Panagiotis Kanavos
            FileAgent.CachePath = Path.Combine(RootPath, FolderConstants.CacheFolder);
381 c28a075a Panagiotis Kanavos
            FileAgent.Start(_accountInfo, RootPath);
382 d78cbf09 Panagiotis Kanavos
        }
383 d78cbf09 Panagiotis Kanavos
384 d78cbf09 Panagiotis Kanavos
        public void Stop()
385 c28a075a Panagiotis Kanavos
        {
386 c28a075a Panagiotis Kanavos
            AgentLocator<FileAgent>.Remove(RootPath);
387 c28a075a Panagiotis Kanavos
388 c53aa229 Panagiotis Kanavos
            if (FileAgent!=null)
389 c53aa229 Panagiotis Kanavos
                FileAgent.Stop();
390 c53aa229 Panagiotis Kanavos
            FileAgent = null;
391 d78cbf09 Panagiotis Kanavos
        }
392 d78cbf09 Panagiotis Kanavos
393 eeee29e3 Panagiotis Kanavos
394 d78cbf09 Panagiotis Kanavos
        ~PithosMonitor()
395 d78cbf09 Panagiotis Kanavos
        {
396 d78cbf09 Panagiotis Kanavos
            Dispose(false);
397 d78cbf09 Panagiotis Kanavos
        }
398 d78cbf09 Panagiotis Kanavos
399 d78cbf09 Panagiotis Kanavos
        public void Dispose()
400 d78cbf09 Panagiotis Kanavos
        {
401 d78cbf09 Panagiotis Kanavos
            Dispose(true);
402 d78cbf09 Panagiotis Kanavos
            GC.SuppressFinalize(this);
403 d78cbf09 Panagiotis Kanavos
        }
404 d78cbf09 Panagiotis Kanavos
405 d78cbf09 Panagiotis Kanavos
        protected virtual void Dispose(bool disposing)
406 d78cbf09 Panagiotis Kanavos
        {
407 d78cbf09 Panagiotis Kanavos
            if (disposing)
408 d78cbf09 Panagiotis Kanavos
            {
409 d78cbf09 Panagiotis Kanavos
                Stop();
410 d78cbf09 Panagiotis Kanavos
            }
411 d78cbf09 Panagiotis Kanavos
        }
412 d78cbf09 Panagiotis Kanavos
413 d78cbf09 Panagiotis Kanavos
414 5120f3cb Panagiotis Kanavos
        public void MoveFileStates(string oldPath, string newPath)
415 5120f3cb Panagiotis Kanavos
        {
416 5120f3cb Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(oldPath))
417 5120f3cb Panagiotis Kanavos
                throw new ArgumentNullException("oldPath");
418 5120f3cb Panagiotis Kanavos
            if (!Path.IsPathRooted(oldPath))
419 5120f3cb Panagiotis Kanavos
                throw new ArgumentException("oldPath must be an absolute path","oldPath");
420 5120f3cb Panagiotis Kanavos
            if (string.IsNullOrWhiteSpace(newPath))
421 5120f3cb Panagiotis Kanavos
                throw new ArgumentNullException("newPath");
422 5120f3cb Panagiotis Kanavos
            if (!Path.IsPathRooted(newPath))
423 5120f3cb Panagiotis Kanavos
                throw new ArgumentException("newPath must be an absolute path","newPath");
424 5120f3cb Panagiotis Kanavos
            Contract.EndContractBlock();
425 5120f3cb Panagiotis Kanavos
426 5120f3cb Panagiotis Kanavos
            StatusKeeper.ChangeRoots(oldPath, newPath);
427 5120f3cb Panagiotis Kanavos
        }
428 d3a13891 Panagiotis Kanavos
429 fec5da06 Panagiotis Kanavos
        public void SetSelectivePaths(Uri[] uris,Uri[] added, Uri[] removed)
430 d3a13891 Panagiotis Kanavos
        {
431 759bd3c4 Panagiotis Kanavos
            //Convert the uris to paths
432 fec5da06 Panagiotis Kanavos
            var selectivePaths = UrisToFilePaths(uris);
433 fec5da06 Panagiotis Kanavos
            
434 fec5da06 Panagiotis Kanavos
            FileAgent.SelectivePaths=selectivePaths;
435 8f44fd3a pkanavos
            WorkflowAgent.SelectivePaths = selectivePaths;
436 ebc37b0d pkanavos
            PollAgent.SetSyncUris(_accountInfo.AccountKey,uris);
437 4147814e Panagiotis Kanavos
            
438 fec5da06 Panagiotis Kanavos
            var removedPaths = UrisToFilePaths(removed);
439 4147814e Panagiotis Kanavos
            UnversionSelectivePaths(removedPaths);
440 4147814e Panagiotis Kanavos
441 4147814e Panagiotis Kanavos
        }
442 4147814e Panagiotis Kanavos
443 4147814e Panagiotis Kanavos
        /// <summary>
444 4147814e Panagiotis Kanavos
        /// Mark all unselected paths as Unversioned
445 4147814e Panagiotis Kanavos
        /// </summary>
446 4147814e Panagiotis Kanavos
        /// <param name="removed"></param>
447 4147814e Panagiotis Kanavos
        private void UnversionSelectivePaths(List<string> removed)
448 4147814e Panagiotis Kanavos
        {
449 4147814e Panagiotis Kanavos
            if (removed == null)
450 4147814e Panagiotis Kanavos
                return;
451 fec5da06 Panagiotis Kanavos
452 4147814e Panagiotis Kanavos
            //Ensure we remove any file state below the deleted folders
453 4147814e Panagiotis Kanavos
            FileState.UnversionPaths(removed);
454 fec5da06 Panagiotis Kanavos
        }
455 fec5da06 Panagiotis Kanavos
456 4147814e Panagiotis Kanavos
457 fec5da06 Panagiotis Kanavos
        /// <summary>
458 fec5da06 Panagiotis Kanavos
        /// Return a list of absolute filepaths from a list of Uris
459 fec5da06 Panagiotis Kanavos
        /// </summary>
460 fec5da06 Panagiotis Kanavos
        /// <param name="uris"></param>
461 fec5da06 Panagiotis Kanavos
        /// <returns></returns>
462 fec5da06 Panagiotis Kanavos
        private List<string> UrisToFilePaths(IEnumerable<Uri> uris)
463 fec5da06 Panagiotis Kanavos
        {
464 fec5da06 Panagiotis Kanavos
            if (uris == null)
465 fec5da06 Panagiotis Kanavos
                return new List<string>();
466 fec5da06 Panagiotis Kanavos
467 97d149c1 pkanavos
            var own = (from uri in uris
468 97d149c1 pkanavos
                       where uri.ToString().StartsWith(_accountInfo.StorageUri.ToString())
469 97d149c1 pkanavos
                                   let relativePath = _accountInfo.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()
470 97d149c1 pkanavos
                                   //Trim the account name
471 97d149c1 pkanavos
                                   select Path.Combine(RootPath, relativePath.After(_accountInfo.UserName + '\\'))).ToList();
472 97d149c1 pkanavos
            var others= (from uri in uris
473 97d149c1 pkanavos
                         where !uri.ToString().StartsWith(_accountInfo.StorageUri.ToString())
474 97d149c1 pkanavos
                                   let relativePath = _accountInfo.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()
475 97d149c1 pkanavos
                                   //Trim the account name
476 97d149c1 pkanavos
                                   select Path.Combine(RootPath,"others-shared", relativePath)).ToList();
477 97d149c1 pkanavos
            return own.Union(others).ToList();            
478 d3a13891 Panagiotis Kanavos
        }
479 d3a13891 Panagiotis Kanavos
480 7b0a5fec Panagiotis Kanavos
481 7b0a5fec Panagiotis Kanavos
        public ObjectInfo GetObjectInfo(string filePath)
482 7b0a5fec Panagiotis Kanavos
        {
483 7b0a5fec Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(filePath))
484 7b0a5fec Panagiotis Kanavos
                throw new ArgumentNullException("filePath");
485 7b0a5fec Panagiotis Kanavos
            Contract.EndContractBlock();
486 7b0a5fec Panagiotis Kanavos
487 7b0a5fec Panagiotis Kanavos
            var file=new FileInfo(filePath);
488 7b0a5fec Panagiotis Kanavos
            string relativeUrl;//=file.AsRelativeUrlTo(this.RootPath);
489 7b0a5fec Panagiotis Kanavos
            var relativePath = file.AsRelativeTo(RootPath);
490 7b0a5fec Panagiotis Kanavos
            
491 7b0a5fec Panagiotis Kanavos
            string accountName,container;
492 7b0a5fec Panagiotis Kanavos
            
493 7b0a5fec Panagiotis Kanavos
            var parts=relativePath.Split('\\');
494 7b0a5fec Panagiotis Kanavos
495 7b0a5fec Panagiotis Kanavos
            var accountInfo = _accountInfo;
496 7b0a5fec Panagiotis Kanavos
            if (relativePath.StartsWith(FolderConstants.OthersFolder))
497 7b0a5fec Panagiotis Kanavos
            {                
498 7b0a5fec Panagiotis Kanavos
                accountName = parts[1];
499 7b0a5fec Panagiotis Kanavos
                container = parts[2];
500 7b0a5fec Panagiotis Kanavos
                relativeUrl = String.Join("/", parts.Splice(3));
501 7b0a5fec Panagiotis Kanavos
                //Create the root URL for the target account
502 7b0a5fec Panagiotis Kanavos
                var oldName = UserName;
503 7b0a5fec Panagiotis Kanavos
                var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;
504 c636df1f Panagiotis Kanavos
                var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal);
505 7b0a5fec Panagiotis Kanavos
                var root=absoluteUri.Substring(0, nameIndex);
506 7b0a5fec Panagiotis Kanavos
507 7b0a5fec Panagiotis Kanavos
                accountInfo = new AccountInfo
508 7b0a5fec Panagiotis Kanavos
                {
509 7b0a5fec Panagiotis Kanavos
                    UserName = accountName,
510 7b0a5fec Panagiotis Kanavos
                    AccountPath = Path.Combine(accountInfo.AccountPath, parts[0], parts[1]),
511 7b0a5fec Panagiotis Kanavos
                    StorageUri = new Uri(root + accountName),
512 7b0a5fec Panagiotis Kanavos
                    BlockHash=accountInfo.BlockHash,
513 7b0a5fec Panagiotis Kanavos
                    BlockSize=accountInfo.BlockSize,
514 7b0a5fec Panagiotis Kanavos
                    Token=accountInfo.Token
515 7b0a5fec Panagiotis Kanavos
                };
516 7b0a5fec Panagiotis Kanavos
            }
517 7b0a5fec Panagiotis Kanavos
            else
518 7b0a5fec Panagiotis Kanavos
            {
519 c636df1f Panagiotis Kanavos
                accountName = UserName;
520 7b0a5fec Panagiotis Kanavos
                container = parts[0];
521 7b0a5fec Panagiotis Kanavos
                relativeUrl = String.Join("/", parts.Splice(1));
522 7b0a5fec Panagiotis Kanavos
            }
523 42800be8 Panagiotis Kanavos
            
524 7b0a5fec Panagiotis Kanavos
            var client = new CloudFilesClient(accountInfo);
525 7b0a5fec Panagiotis Kanavos
            var objectInfo=client.GetObjectInfo(accountName, container, relativeUrl);
526 7b0a5fec Panagiotis Kanavos
            return objectInfo;
527 7b0a5fec Panagiotis Kanavos
        }
528 42800be8 Panagiotis Kanavos
        
529 c92e02f3 Panagiotis Kanavos
        public Task<ContainerInfo> GetContainerInfo(string filePath)
530 42800be8 Panagiotis Kanavos
        {
531 42800be8 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(filePath))
532 42800be8 Panagiotis Kanavos
                throw new ArgumentNullException("filePath");
533 42800be8 Panagiotis Kanavos
            Contract.EndContractBlock();
534 42800be8 Panagiotis Kanavos
535 42800be8 Panagiotis Kanavos
            var file=new FileInfo(filePath);
536 42800be8 Panagiotis Kanavos
            var relativePath = file.AsRelativeTo(RootPath);
537 42800be8 Panagiotis Kanavos
            
538 42800be8 Panagiotis Kanavos
            string accountName,container;
539 42800be8 Panagiotis Kanavos
            
540 42800be8 Panagiotis Kanavos
            var parts=relativePath.Split('\\');
541 42800be8 Panagiotis Kanavos
542 42800be8 Panagiotis Kanavos
            var accountInfo = _accountInfo;
543 42800be8 Panagiotis Kanavos
            if (relativePath.StartsWith(FolderConstants.OthersFolder))
544 42800be8 Panagiotis Kanavos
            {                
545 42800be8 Panagiotis Kanavos
                accountName = parts[1];
546 42800be8 Panagiotis Kanavos
                container = parts[2];                
547 42800be8 Panagiotis Kanavos
                //Create the root URL for the target account
548 42800be8 Panagiotis Kanavos
                var oldName = UserName;
549 42800be8 Panagiotis Kanavos
                var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;
550 c636df1f Panagiotis Kanavos
                var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal);
551 42800be8 Panagiotis Kanavos
                var root=absoluteUri.Substring(0, nameIndex);
552 42800be8 Panagiotis Kanavos
553 42800be8 Panagiotis Kanavos
                accountInfo = new AccountInfo
554 42800be8 Panagiotis Kanavos
                {
555 42800be8 Panagiotis Kanavos
                    UserName = accountName,
556 42800be8 Panagiotis Kanavos
                    AccountPath = Path.Combine(accountInfo.AccountPath, parts[0], parts[1]),
557 42800be8 Panagiotis Kanavos
                    StorageUri = new Uri(root + accountName),
558 42800be8 Panagiotis Kanavos
                    BlockHash=accountInfo.BlockHash,
559 42800be8 Panagiotis Kanavos
                    BlockSize=accountInfo.BlockSize,
560 42800be8 Panagiotis Kanavos
                    Token=accountInfo.Token
561 42800be8 Panagiotis Kanavos
                };
562 42800be8 Panagiotis Kanavos
            }
563 42800be8 Panagiotis Kanavos
            else
564 42800be8 Panagiotis Kanavos
            {
565 42800be8 Panagiotis Kanavos
                accountName = UserName;
566 42800be8 Panagiotis Kanavos
                container = parts[0];                
567 42800be8 Panagiotis Kanavos
            }
568 c92e02f3 Panagiotis Kanavos
569 c92e02f3 Panagiotis Kanavos
            return Task.Factory.StartNew(() =>
570 c92e02f3 Panagiotis Kanavos
            {
571 c92e02f3 Panagiotis Kanavos
                var client = new CloudFilesClient(accountInfo);
572 c92e02f3 Panagiotis Kanavos
                var containerInfo = client.GetContainerInfo(accountName, container);
573 c92e02f3 Panagiotis Kanavos
                return containerInfo;
574 c92e02f3 Panagiotis Kanavos
            });
575 42800be8 Panagiotis Kanavos
        }
576 d78cbf09 Panagiotis Kanavos
    }
577 d78cbf09 Panagiotis Kanavos
}