internal FileShareTrimmer( string folderName, string destinationPath, FolderTrimmer.DestinationOperationPerformer destinationOperationPerformer, string localMap, TimeSpan fileDeletionAge) { // Initialization this.traceSource = new FabricEvents.ExtensionsEvents(FabricEvents.Tasks.FabricDCA); this.logSourceId = string.Concat(TraceType, "-", Guid.NewGuid().ToString("P")); this.destinationPath = destinationPath; this.destinationOperationPerformer = destinationOperationPerformer; this.localMap = localMap; this.localMapTrimmingHelper = new LocalMapTrimmingHelper(folderName); this.folderTrimmer = new FolderTrimmer( this.traceSource, this.logSourceId, fileDeletionAge); this.perfHelper = new FileSharePerformance(this.traceSource, this.logSourceId); // File deletion is done one at a time, so the // concurrency count is 1. this.perfHelper.ExternalOperationInitialize( ExternalOperationTime.ExternalOperationType.FileShareDeletion, 1); // Create a timer to delete old logs string timerId = string.Concat( this.logSourceId, OldLogDeletionTimerIdSuffix); var oldLogDeletionInterval = (fileDeletionAge < TimeSpan.FromDays(1)) ? FileShareUploaderConstants.OldLogDeletionIntervalForTest : FileShareUploaderConstants.OldLogDeletionInterval; this.oldLogDeletionTimer = new DcaTimer( timerId, this.DeleteOldFilesHandler, oldLogDeletionInterval); this.oldLogDeletionTimer.Start(); }
internal FileShareUploader( FabricEvents.ExtensionsEvents traceSource, string logSourceId, bool runningOnBehalfOfApplication, string folderName, string destinationPath, AccessInformation accessInfo, string workFolder, TimeSpan uploadInterval, TimeSpan fileSyncInterval, TimeSpan fileDeletionAge, bool destinationIsLocalAppFolder, string fabricNodeId) : base( traceSource, logSourceId, folderName, destinationPath, workFolder, uploadInterval, fileSyncInterval) { // Initialization this.destinationPath = destinationPath; this.accessInfo = accessInfo; var impersonationRequiredForAppStoreAccess = Utility.IsImpersonationRequiredForAppDiagnosticStoreAccess(); if (runningOnBehalfOfApplication && (false == destinationIsLocalAppFolder) && impersonationRequiredForAppStoreAccess && (FileShareAccessAccountType.None == this.accessInfo.AccountType)) { const string Message = "Impersonation is required to access the file share, but credentials for impersonation have not been provided."; this.TraceSource.WriteError( this.LogSourceId, Message); throw new InvalidOperationException(Message); } // Create the staging folder where we copy the files temporarily before impersonating // and copying it to the final destination. try { Utility.PerformIOWithRetries( () => { if (IsStagingFolderNeededForCopy(folderName)) { CreateStagingFolderForCopy(workFolder); } }); } catch (Exception e) { throw new IOException(string.Format("Unable to create staging directory for work directory {0}.", workFolder), e); } // Check that the destination folder exists or can be created. try { Utility.PerformIOWithRetries( () => this.PerformDestinationOperation( ctx => { var destPath = (string)ctx; if (FabricDirectory.Exists(destPath)) { return true; } FabricDirectory.CreateDirectory(destPath); return true; }, this.destinationPath)); } catch (Exception e) { throw new IOException(string.Format("Unable to create destination directory {0}.", this.destinationPath), e); } this.perfHelper = new FileSharePerformance(this.TraceSource, this.LogSourceId); // File copy is done one at a time, so the concurrency count is 1. this.perfHelper.ExternalOperationInitialize( ExternalOperationTime.ExternalOperationType.FileShareCopy, 1); // Check if a trimmer already exists to delete old files from this destination lock (Trimmers) { if (Trimmers.ContainsKey(this.destinationPath)) { // Trimmer already exists. Increment its reference count. TrimmerInfo trimmerInfo = Trimmers[this.destinationPath]; trimmerInfo.RefCount++; } else { // Trimmer does not exist. Create it. FileShareTrimmer trimmer = new FileShareTrimmer( folderName, this.destinationPath, this.PerformDestinationOperation, LocalMapFolderPath, fileDeletionAge); TrimmerInfo trimmerInfo = new TrimmerInfo { RefCount = 1, Trimmer = trimmer }; Trimmers[this.destinationPath] = trimmerInfo; } } }