Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / WorkflowAgent.cs @ 8f44fd3a

History | View | Annotate | Download (12.5 kB)

1 255f5f86 Panagiotis Kanavos
#region
2 255f5f86 Panagiotis Kanavos
/* -----------------------------------------------------------------------
3 255f5f86 Panagiotis Kanavos
 * <copyright file="WorkflowAgent.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 f3d080df Panagiotis Kanavos
using System;
43 9c4346c9 Panagiotis Kanavos
using System.Collections.Generic;
44 9c4346c9 Panagiotis Kanavos
using System.ComponentModel.Composition;
45 9c4346c9 Panagiotis Kanavos
using System.Diagnostics;
46 9c4346c9 Panagiotis Kanavos
using System.Diagnostics.Contracts;
47 9c4346c9 Panagiotis Kanavos
using System.IO;
48 9c4346c9 Panagiotis Kanavos
using System.Linq;
49 db8a9589 Panagiotis Kanavos
using System.Reflection;
50 9c4346c9 Panagiotis Kanavos
using System.Text;
51 a64c87c8 Panagiotis Kanavos
using System.Threading.Tasks;
52 e81dd1f6 Panagiotis Kanavos
using Castle.ActiveRecord;
53 9c4346c9 Panagiotis Kanavos
using Pithos.Interfaces;
54 c53aa229 Panagiotis Kanavos
using Pithos.Network;
55 5120f3cb Panagiotis Kanavos
using log4net;
56 9c4346c9 Panagiotis Kanavos
57 9c4346c9 Panagiotis Kanavos
namespace Pithos.Core.Agents
58 9c4346c9 Panagiotis Kanavos
{
59 9c4346c9 Panagiotis Kanavos
    [Export]
60 9c4346c9 Panagiotis Kanavos
    public class WorkflowAgent
61 9c4346c9 Panagiotis Kanavos
    {
62 db8a9589 Panagiotis Kanavos
        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
63 db8a9589 Panagiotis Kanavos
64 70f12b36 Panagiotis Kanavos
        readonly Agent<WorkflowState> _agent;
65 9c4346c9 Panagiotis Kanavos
                
66 9c4346c9 Panagiotis Kanavos
        public IStatusNotification StatusNotification { get; set; }
67 e81dd1f6 Panagiotis Kanavos
        [System.ComponentModel.Composition.Import]
68 9c4346c9 Panagiotis Kanavos
        public IStatusKeeper StatusKeeper { get; set; }
69 5ce54458 Panagiotis Kanavos
70 e81dd1f6 Panagiotis Kanavos
        [System.ComponentModel.Composition.Import]
71 9c4346c9 Panagiotis Kanavos
        public NetworkAgent NetworkAgent { get; set; }
72 9c4346c9 Panagiotis Kanavos
73 6bcdd8e2 Panagiotis Kanavos
        [System.ComponentModel.Composition.Import]
74 6bcdd8e2 Panagiotis Kanavos
        public IPithosSettings Settings { get; set; }
75 db8a9589 Panagiotis Kanavos
76 8f44fd3a pkanavos
        private List<string> _selectivePaths = new List<string>();
77 8f44fd3a pkanavos
        public List<string> SelectivePaths
78 8f44fd3a pkanavos
        {
79 8f44fd3a pkanavos
            get { return _selectivePaths; }
80 8f44fd3a pkanavos
            set { _selectivePaths = value; }
81 8f44fd3a pkanavos
        }
82 5120f3cb Panagiotis Kanavos
83 70f12b36 Panagiotis Kanavos
        public WorkflowAgent()
84 9c4346c9 Panagiotis Kanavos
        {
85 4ec636f6 Panagiotis Kanavos
            _agent = Agent<WorkflowState>.Start(inbox =>
86 9c4346c9 Panagiotis Kanavos
            {
87 9c4346c9 Panagiotis Kanavos
                Action loop = null;
88 9c4346c9 Panagiotis Kanavos
                loop = () =>
89 9c4346c9 Panagiotis Kanavos
                {
90 4ec636f6 Panagiotis Kanavos
                    var message = inbox.Receive();
91 a64c87c8 Panagiotis Kanavos
                    var process = message.Then(Process, inbox.CancellationToken);                        
92 a64c87c8 Panagiotis Kanavos
                    inbox.LoopAsync(process,loop,ex=>
93 5120f3cb Panagiotis Kanavos
                            Log.ErrorFormat("[ERROR] Synch for {0}:\r{1}", message.Result.FileName, ex));
94 9c4346c9 Panagiotis Kanavos
                };
95 9c4346c9 Panagiotis Kanavos
                loop();
96 4ec636f6 Panagiotis Kanavos
            });
97 9c4346c9 Panagiotis Kanavos
        }
98 9c4346c9 Panagiotis Kanavos
99 4ec636f6 Panagiotis Kanavos
        private Task<object> Process(WorkflowState state)
100 a64c87c8 Panagiotis Kanavos
        {
101 c53aa229 Panagiotis Kanavos
            var accountInfo = state.AccountInfo;
102 5120f3cb Panagiotis Kanavos
            using (log4net.ThreadContext.Stacks["Workflow"].Push("Process"))
103 a64c87c8 Panagiotis Kanavos
            {
104 a0dcfcc9 Panagiotis Kanavos
                try
105 5120f3cb Panagiotis Kanavos
                {
106 5120f3cb Panagiotis Kanavos
107 a0dcfcc9 Panagiotis Kanavos
                    if (Log.IsDebugEnabled)
108 a0dcfcc9 Panagiotis Kanavos
                        Log.DebugFormat("State {0} {1} {2}", state.FileName, state.Status, state.TriggeringChange);
109 a0dcfcc9 Panagiotis Kanavos
110 a0dcfcc9 Panagiotis Kanavos
                    if (state.Skip)
111 a0dcfcc9 Panagiotis Kanavos
                    {
112 a0dcfcc9 Panagiotis Kanavos
                        if (Log.IsDebugEnabled) Log.DebugFormat("Skipping {0}", state.FileName);
113 a0dcfcc9 Panagiotis Kanavos
114 a0dcfcc9 Panagiotis Kanavos
                        return CompletedTask<object>.Default;
115 3c76f045 Panagiotis Kanavos
                    }                    
116 4f6d51d4 Panagiotis Kanavos
117 3c76f045 Panagiotis Kanavos
                    var info = Directory.Exists(state.Path) ? (FileSystemInfo)new DirectoryInfo(state.Path) : new FileInfo(state.Path);
118 4f6d51d4 Panagiotis Kanavos
119 a0dcfcc9 Panagiotis Kanavos
                    //Bypass deleted files, unless the status is Deleted
120 4f6d51d4 Panagiotis Kanavos
                    if (!info.Exists && state.Status != FileStatus.Deleted)
121 a0dcfcc9 Panagiotis Kanavos
                    {
122 a0dcfcc9 Panagiotis Kanavos
                        state.Skip = true;
123 3c76f045 Panagiotis Kanavos
                        this.StatusKeeper.ClearFileStatus(state.Path);
124 a0dcfcc9 Panagiotis Kanavos
125 a0dcfcc9 Panagiotis Kanavos
                        if (Log.IsDebugEnabled) Log.DebugFormat("Skipped missing {0}", state.FileName);
126 a0dcfcc9 Panagiotis Kanavos
127 a0dcfcc9 Panagiotis Kanavos
                        return CompletedTask<object>.Default;
128 a0dcfcc9 Panagiotis Kanavos
                    }
129 a0dcfcc9 Panagiotis Kanavos
130 e81dd1f6 Panagiotis Kanavos
                    using (new SessionScope(FlushAction.Never))
131 a0dcfcc9 Panagiotis Kanavos
                    {
132 e81dd1f6 Panagiotis Kanavos
133 3c76f045 Panagiotis Kanavos
                        var fileState = StatusKeeper.GetStateByFilePath(state.Path);
134 e81dd1f6 Panagiotis Kanavos
135 e81dd1f6 Panagiotis Kanavos
                        switch (state.Status)
136 e81dd1f6 Panagiotis Kanavos
                        {
137 e81dd1f6 Panagiotis Kanavos
                            case FileStatus.Created:
138 e81dd1f6 Panagiotis Kanavos
                            case FileStatus.Modified:
139 e81dd1f6 Panagiotis Kanavos
                                NetworkAgent.Post(new CloudUploadAction(accountInfo, info, fileState,
140 e81dd1f6 Panagiotis Kanavos
                                                                        accountInfo.BlockSize,
141 e81dd1f6 Panagiotis Kanavos
                                                                        accountInfo.BlockHash));
142 e81dd1f6 Panagiotis Kanavos
                                break;
143 e81dd1f6 Panagiotis Kanavos
                            case FileStatus.Deleted:
144 26d5f45f Panagiotis Kanavos
                                DeleteChildObjects(state, fileState);
145 e81dd1f6 Panagiotis Kanavos
                                NetworkAgent.Post(new CloudDeleteAction(accountInfo, info, fileState));
146 e81dd1f6 Panagiotis Kanavos
                                break;
147 e81dd1f6 Panagiotis Kanavos
                            case FileStatus.Renamed:
148 174bbb6e Panagiotis Kanavos
                                if (state.OldPath == null)
149 174bbb6e Panagiotis Kanavos
                                {
150 174bbb6e Panagiotis Kanavos
                                    //We reach this point only if the app closed before propagating a rename to the server
151 174bbb6e Panagiotis Kanavos
                                    Log.WarnFormat("Unfinished rename [{0}]",state.Path);
152 0a9d4d18 pkanavos
                                    StatusKeeper.SetFileState(state.Path,FileStatus.Conflict,FileOverlayStatus.Conflict, "Rename without old path");
153 174bbb6e Panagiotis Kanavos
                                    break;
154 174bbb6e Panagiotis Kanavos
                                }
155 e81dd1f6 Panagiotis Kanavos
                                FileSystemInfo oldInfo = Directory.Exists(state.OldPath)
156 e81dd1f6 Panagiotis Kanavos
                                                             ? (FileSystemInfo) new DirectoryInfo(state.OldPath)
157 e81dd1f6 Panagiotis Kanavos
                                                             : new FileInfo(state.OldPath);
158 e81dd1f6 Panagiotis Kanavos
                                FileSystemInfo newInfo = Directory.Exists(state.Path)
159 e81dd1f6 Panagiotis Kanavos
                                                             ? (FileSystemInfo) new DirectoryInfo(state.Path)
160 e81dd1f6 Panagiotis Kanavos
                                                             : new FileInfo(state.Path);
161 e81dd1f6 Panagiotis Kanavos
                                NetworkAgent.Post(new CloudMoveAction(accountInfo, CloudActionType.RenameCloud,
162 e81dd1f6 Panagiotis Kanavos
                                                                      oldInfo,
163 26d5f45f Panagiotis Kanavos
                                                                      newInfo));                                
164 26d5f45f Panagiotis Kanavos
                                //TODO: Do I have to move children as well or will Pithos handle this?
165 26d5f45f Panagiotis Kanavos
                               //Need to find all children of the OLD filepath
166 139ac1e8 Panagiotis Kanavos
                                //MoveChildObjects(state);
167 e81dd1f6 Panagiotis Kanavos
                                break;
168 e81dd1f6 Panagiotis Kanavos
                        }
169 a0dcfcc9 Panagiotis Kanavos
                    }
170 5120f3cb Panagiotis Kanavos
171 4ec636f6 Panagiotis Kanavos
                    return CompletedTask<object>.Default;
172 5120f3cb Panagiotis Kanavos
                }
173 a0dcfcc9 Panagiotis Kanavos
                catch (Exception ex)
174 5120f3cb Panagiotis Kanavos
                {
175 a0dcfcc9 Panagiotis Kanavos
                    Log.Error(ex.ToString());
176 a0dcfcc9 Panagiotis Kanavos
                    throw;
177 5120f3cb Panagiotis Kanavos
                }
178 5120f3cb Panagiotis Kanavos
            }
179 a64c87c8 Panagiotis Kanavos
        }
180 a64c87c8 Panagiotis Kanavos
181 139ac1e8 Panagiotis Kanavos
182 26d5f45f Panagiotis Kanavos
        private void DeleteChildObjects(WorkflowState state, FileState fileState)
183 26d5f45f Panagiotis Kanavos
        {
184 26d5f45f Panagiotis Kanavos
            if (fileState != null)
185 26d5f45f Panagiotis Kanavos
            {
186 26d5f45f Panagiotis Kanavos
                var children = StatusKeeper.GetChildren(fileState);
187 26d5f45f Panagiotis Kanavos
                foreach (var child in children)
188 26d5f45f Panagiotis Kanavos
                {
189 26d5f45f Panagiotis Kanavos
                    var childInfo = child.IsFolder
190 26d5f45f Panagiotis Kanavos
                                        ? (FileSystemInfo) new DirectoryInfo(child.FilePath)
191 26d5f45f Panagiotis Kanavos
                                        : new FileInfo(child.FilePath);
192 26d5f45f Panagiotis Kanavos
                    NetworkAgent.Post(new CloudDeleteAction(state.AccountInfo, childInfo, child));
193 26d5f45f Panagiotis Kanavos
                }
194 26d5f45f Panagiotis Kanavos
            }
195 26d5f45f Panagiotis Kanavos
        }
196 26d5f45f Panagiotis Kanavos
197 139ac1e8 Panagiotis Kanavos
        /*private void MoveChildObjects(WorkflowState state)
198 26d5f45f Panagiotis Kanavos
        {
199 26d5f45f Panagiotis Kanavos
            var oldFileState = StatusKeeper.GetStateByFilePath(state.OldPath);
200 26d5f45f Panagiotis Kanavos
            if (oldFileState != null)
201 26d5f45f Panagiotis Kanavos
            {
202 26d5f45f Panagiotis Kanavos
                var children = StatusKeeper.GetChildren(oldFileState);
203 26d5f45f Panagiotis Kanavos
                foreach (var child in children)
204 26d5f45f Panagiotis Kanavos
                {
205 26d5f45f Panagiotis Kanavos
                    var newPath = Path.Combine(state.Path, child.FilePath.Substring(state.OldPath.Length+1));
206 26d5f45f Panagiotis Kanavos
207 26d5f45f Panagiotis Kanavos
                    var oldMoveInfo = child.IsFolder
208 26d5f45f Panagiotis Kanavos
                                          ? (FileSystemInfo) new DirectoryInfo(child.FilePath)
209 26d5f45f Panagiotis Kanavos
                                          : new FileInfo(child.FilePath);
210 26d5f45f Panagiotis Kanavos
                    var newMoveInfo = child.IsFolder
211 26d5f45f Panagiotis Kanavos
                                          ? (FileSystemInfo) new DirectoryInfo(newPath)
212 26d5f45f Panagiotis Kanavos
                                          : new FileInfo(newPath);
213 26d5f45f Panagiotis Kanavos
                    //The new file path will be created by trimming the old root path
214 26d5f45f Panagiotis Kanavos
                    //and substituting the new root path
215 26d5f45f Panagiotis Kanavos
216 26d5f45f Panagiotis Kanavos
                    NetworkAgent.Post(new CloudMoveAction(state.AccountInfo, CloudActionType.RenameCloud,
217 26d5f45f Panagiotis Kanavos
                                                          oldMoveInfo, newMoveInfo));
218 26d5f45f Panagiotis Kanavos
                }
219 26d5f45f Panagiotis Kanavos
            }
220 139ac1e8 Panagiotis Kanavos
        }*/
221 26d5f45f Panagiotis Kanavos
222 a64c87c8 Panagiotis Kanavos
223 c53aa229 Panagiotis Kanavos
        //Starts interrupted files for a specific account
224 c53aa229 Panagiotis Kanavos
        public void RestartInterruptedFiles(AccountInfo accountInfo)
225 9c4346c9 Panagiotis Kanavos
        {
226 5ce54458 Panagiotis Kanavos
            
227 026a6c5a Panagiotis Kanavos
            StatusKeeper.CleanupOrphanStates();
228 6bcdd8e2 Panagiotis Kanavos
            using (log4net.ThreadContext.Stacks["Operation"].Push("RestartInterrupted"))
229 5120f3cb Panagiotis Kanavos
            {
230 5120f3cb Panagiotis Kanavos
                if (Log.IsDebugEnabled)
231 5120f3cb Panagiotis Kanavos
                    Log.Debug("Starting interrupted files");
232 c53aa229 Panagiotis Kanavos
233 77e10b4f Panagiotis Kanavos
                var cachePath = Path.Combine(accountInfo.AccountPath, FolderConstants.CacheFolder)
234 c53aa229 Panagiotis Kanavos
                    .ToLower();
235 c53aa229 Panagiotis Kanavos
236 c53aa229 Panagiotis Kanavos
237 6bcdd8e2 Panagiotis Kanavos
                
238 6bcdd8e2 Panagiotis Kanavos
                
239 4ec636f6 Panagiotis Kanavos
                var account = accountInfo;
240 2e3aee00 Panagiotis Kanavos
                var pendingEntries = (from state in FileState.Queryable
241 5120f3cb Panagiotis Kanavos
                                     where state.FileStatus != FileStatus.Unchanged &&
242 0a9d4d18 pkanavos
                                            state.FileStatus != FileStatus.Forbidden &&
243 0a9d4d18 pkanavos
                                            state.FileStatus != FileStatus.Conflict &&
244 77e10b4f Panagiotis Kanavos
                                           !state.FilePath.StartsWith(cachePath) &&
245 c53aa229 Panagiotis Kanavos
                                           !state.FilePath.EndsWith(".ignore") &&
246 6bcdd8e2 Panagiotis Kanavos
                                           state.FilePath.StartsWith(account.AccountPath)                                            
247 2e3aee00 Panagiotis Kanavos
                                     select state).ToList();
248 2e3aee00 Panagiotis Kanavos
                if (pendingEntries.Count>0)
249 2e3aee00 Panagiotis Kanavos
                    StatusNotification.NotifyChange("Restart processing interrupted files", TraceLevel.Verbose);
250 2e3aee00 Panagiotis Kanavos
251 2e3aee00 Panagiotis Kanavos
                var pendingStates = pendingEntries
252 2e3aee00 Panagiotis Kanavos
                    .Select(state => new WorkflowState(account, state))
253 2e3aee00 Panagiotis Kanavos
                    .ToList();
254 8f44fd3a pkanavos
                
255 8f44fd3a pkanavos
                                
256 5120f3cb Panagiotis Kanavos
                if (Log.IsDebugEnabled)
257 4ec636f6 Panagiotis Kanavos
                    Log.DebugFormat("Found {0} interrupted files", pendingStates.Count);
258 4ec636f6 Panagiotis Kanavos
259 2e3aee00 Panagiotis Kanavos
                pendingStates.ForEach(Post);
260 5120f3cb Panagiotis Kanavos
            }
261 4ec636f6 Panagiotis Kanavos
        }
262 4ec636f6 Panagiotis Kanavos
263 9c4346c9 Panagiotis Kanavos
264 9c4346c9 Panagiotis Kanavos
265 9c4346c9 Panagiotis Kanavos
        public void Post(WorkflowState workflowState)
266 9c4346c9 Panagiotis Kanavos
        {
267 5120f3cb Panagiotis Kanavos
            if (Log.IsDebugEnabled)
268 5120f3cb Panagiotis Kanavos
                Log.DebugFormat("Posted {0} {1} {2}", workflowState.Path, workflowState.Status, workflowState.TriggeringChange);
269 4ec636f6 Panagiotis Kanavos
270 4ec636f6 Panagiotis Kanavos
            //Remove invalid state            
271 4f6d51d4 Panagiotis Kanavos
            //For now, ignore paths
272 4f6d51d4 Panagiotis Kanavos
           /* if (Directory.Exists(workflowState.Path))
273 4f6d51d4 Panagiotis Kanavos
                return;*/
274 4f6d51d4 Panagiotis Kanavos
            //TODO: Need to handle folder renames            
275 4ec636f6 Panagiotis Kanavos
276 8f44fd3a pkanavos
            //If there are selective sync paths defined
277 8f44fd3a pkanavos
            if (SelectivePaths.Count > 0
278 8f44fd3a pkanavos
                //And the target file is not below any of the selective paths
279 8f44fd3a pkanavos
                && !SelectivePaths.Any(workflowState.Path.IsAtOrDirectlyBelow))
280 8f44fd3a pkanavos
            //abort the post
281 8f44fd3a pkanavos
            {
282 8f44fd3a pkanavos
                Log.InfoFormat("File skipped, not under a selected folder [{0}] ",workflowState.Path);
283 8f44fd3a pkanavos
                return;
284 8f44fd3a pkanavos
            }
285 8f44fd3a pkanavos
286 8f44fd3a pkanavos
287 4ec636f6 Panagiotis Kanavos
            Debug.Assert(workflowState.Path.StartsWith(workflowState.AccountInfo.AccountPath, StringComparison.InvariantCultureIgnoreCase), "File from wrong account posted");
288 4ec636f6 Panagiotis Kanavos
289 4ec636f6 Panagiotis Kanavos
            _agent.Post(workflowState);
290 4ec636f6 Panagiotis Kanavos
        }     
291 4ec636f6 Panagiotis Kanavos
292 9c4346c9 Panagiotis Kanavos
    }
293 9c4346c9 Panagiotis Kanavos
}