PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/src/ServiceManagement/Compute/Commands.ServiceManagement/Model/PSSyncOutputEvents.cs

https://gitlab.com/jslee1/azure-powershell
C# | 295 lines | 241 code | 41 blank | 13 comment | 7 complexity | ff1eb316751104e8f00339d13964f9db MD5 | raw file
  1. // ----------------------------------------------------------------------------------
  2. //
  3. // Copyright Microsoft Corporation
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. // ----------------------------------------------------------------------------------
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Globalization;
  17. using System.Management.Automation;
  18. using System.Management.Automation.Runspaces;
  19. using Microsoft.WindowsAzure.Commands.ServiceManagement.Properties;
  20. using Microsoft.WindowsAzure.Commands.Sync;
  21. using Microsoft.WindowsAzure.Commands.Sync.Upload;
  22. using Microsoft.WindowsAzure.Commands.Tools.Vhd.Model;
  23. using Microsoft.WindowsAzure.Storage;
  24. using ProgressRecord = Microsoft.WindowsAzure.Commands.Sync.ProgressRecord;
  25. namespace Microsoft.WindowsAzure.Commands.ServiceManagement.Model
  26. {
  27. public class PSSyncOutputEvents : ISyncOutputEvents, IDisposable
  28. {
  29. private readonly PSCmdlet cmdlet;
  30. private Runspace runspace;
  31. private bool disposed;
  32. public PSSyncOutputEvents(PSCmdlet cmdlet)
  33. {
  34. this.cmdlet = cmdlet;
  35. this.runspace = RunspaceFactory.CreateRunspace(this.cmdlet.Host);
  36. this.runspace.Open();
  37. }
  38. private static string FormatDuration(TimeSpan ts)
  39. {
  40. if (ts.Days == 0)
  41. {
  42. return String.Format("{0:00}:{1:00}:{2:00}", ts.Hours, ts.Minutes, ts.Seconds);
  43. }
  44. return String.Format(Resources.PSSyncOutputEventsFormatDuration, ts.Days, ts.Hours, ts.Minutes, ts.Seconds);
  45. }
  46. public void ProgressCopyStatus(ProgressRecord record)
  47. {
  48. ProgressCopyStatus(record.PercentComplete, record.AvgThroughputMbPerSecond, record.RemainingTime);
  49. }
  50. public void ProgressCopyStatus(double precentComplete, double avgThroughputMbps, TimeSpan remainingTime)
  51. {
  52. LogProgress(0, Resources.PSSyncOutputEventsCopying, precentComplete, remainingTime, avgThroughputMbps);
  53. }
  54. public void ProgressCopyComplete(TimeSpan elapsed)
  55. {
  56. LogProgressComplete(0, Resources.PSSyncOutputEventsCopying);
  57. LogMessage(Resources.PSSyncOutputEventsElapsedTimeForCopy, FormatDuration(elapsed));
  58. }
  59. public void ProgressUploadStatus(ProgressRecord record)
  60. {
  61. ProgressUploadStatus(record.PercentComplete, record.AvgThroughputMbPerSecond, record.RemainingTime);
  62. }
  63. public void ProgressUploadStatus(double precentComplete, double avgThroughputMbps, TimeSpan remainingTime)
  64. {
  65. LogProgress(0, Resources.PSSyncOutputEventsUploading, precentComplete, remainingTime, avgThroughputMbps);
  66. }
  67. private void LogProgress(int activityId, string activity, double precentComplete, TimeSpan remainingTime, double avgThroughputMbps)
  68. {
  69. var message = String.Format(Resources.PSSyncOutputEventsLogProgress,
  70. precentComplete,
  71. FormatDuration(remainingTime),
  72. avgThroughputMbps);
  73. var progressCommand = String.Format(@"Write-Progress -Id {0} -Activity '{1}' -Status '{2}' -SecondsRemaining {3} -PercentComplete {4}", activityId, activity, message, (int) remainingTime.TotalSeconds, (int) precentComplete);
  74. using(var ps = System.Management.Automation.PowerShell.Create())
  75. {
  76. ps.Runspace = runspace;
  77. ps.AddScript(progressCommand);
  78. ps.Invoke();
  79. }
  80. }
  81. private void LogProgressComplete(int activityId, string activity)
  82. {
  83. var progressCommand = String.Format(@"Write-Progress -Id {0} -Activity '{1}' -Status '{2}' -Completed", activityId, activity, Resources.PSSyncOutputEventsLogProgressCompleteCompleted);
  84. using(var ps = System.Management.Automation.PowerShell.Create())
  85. {
  86. ps.Runspace = runspace;
  87. ps.AddScript(progressCommand);
  88. ps.Invoke();
  89. }
  90. }
  91. public void MessageCreatingNewPageBlob(long pageBlobSize)
  92. {
  93. LogMessage(Resources.PSSyncOutputEventsCreatingNewPageBlob, pageBlobSize);
  94. }
  95. private void LogMessage(string format, params object[] parameters)
  96. {
  97. var message = String.Format(format, parameters);
  98. var verboseMessage = String.Format("Write-Host '{0}'", message);
  99. using (var ps = System.Management.Automation.PowerShell.Create())
  100. {
  101. ps.Runspace = runspace;
  102. ps.AddScript(verboseMessage);
  103. ps.Invoke();
  104. }
  105. }
  106. private void LogError(Exception e)
  107. {
  108. using (var ps = System.Management.Automation.PowerShell.Create())
  109. {
  110. ps.Runspace = runspace;
  111. ps.AddCommand("Write-Error");
  112. ps.AddParameter("ErrorRecord", new ErrorRecord(e, String.Empty, ErrorCategory.NotSpecified, null));
  113. ps.Invoke();
  114. }
  115. }
  116. public void MessageResumingUpload()
  117. {
  118. LogMessage(Resources.PSSyncOutputEventsResumingUpload);
  119. }
  120. public void ProgressUploadComplete(TimeSpan elapsed)
  121. {
  122. LogProgressComplete(0, Resources.PSSyncOutputEventsUploading);
  123. LogMessage(Resources.PSSyncOutputEventsElapsedTimeForUpload, FormatDuration(elapsed));
  124. }
  125. public void ProgressDownloadStatus(ProgressRecord record)
  126. {
  127. ProgressDownloadStatus(record.PercentComplete, record.AvgThroughputMbPerSecond, record.RemainingTime);
  128. }
  129. public void ProgressDownloadStatus(double precentComplete, double avgThroughputMbps, TimeSpan remainingTime)
  130. {
  131. LogProgress(0, Resources.PSSyncOutputEventsDownloading, precentComplete, remainingTime, avgThroughputMbps);
  132. }
  133. public void ProgressDownloadComplete(TimeSpan elapsed)
  134. {
  135. LogProgressComplete(0, Resources.PSSyncOutputEventsDownloading);
  136. LogMessage(Resources.PSSyncOutputEventsElapsedTimeForDownload, FormatDuration(elapsed));
  137. }
  138. public void ProgressOperationStatus(ProgressRecord record)
  139. {
  140. ProgressOperationStatus(record.PercentComplete, record.AvgThroughputMbPerSecond, record.RemainingTime);
  141. }
  142. public void ProgressOperationStatus(double percentComplete, double avgThroughputMbps, TimeSpan remainingTime)
  143. {
  144. LogProgress(1, Resources.PSSyncOutputEventsCalculatingMD5Hash, percentComplete, remainingTime, avgThroughputMbps);
  145. }
  146. public void ProgressOperationComplete(TimeSpan elapsed)
  147. {
  148. LogProgressComplete(1, Resources.PSSyncOutputEventsCalculatingMD5Hash);
  149. LogMessage(Resources.PSSyncOutputEventsElapsedTimeForOperation, FormatDuration(elapsed));
  150. }
  151. public void ErrorUploadFailedWithExceptions(IList<Exception> exceptions)
  152. {
  153. LogMessage(Resources.PSSyncOutputEventsUploadFailedWithException);
  154. foreach (var exception in exceptions)
  155. {
  156. LogError(exception);
  157. }
  158. }
  159. public void MessageCalculatingMD5Hash(string filePath)
  160. {
  161. LogMessage(Resources.PSSyncOutputEventsCalculatingMD5HashForFile, filePath);
  162. }
  163. public void MessageMD5HashCalculationFinished()
  164. {
  165. LogMessage(Resources.PSSyncOutputEventsMD5HashCalculationFinished);
  166. }
  167. public void MessageRetryingAfterANetworkDisruption()
  168. {
  169. LogMessage(Resources.PSSyncOutputEventsRetryingAfterANetworkDisruption);
  170. }
  171. public void DebugRetryingAfterException(Exception lastException)
  172. {
  173. LogDebug(lastException.ToString());
  174. var storageException = lastException as StorageException;
  175. var message = ExceptionUtil.DumpStorageExceptionErrorDetails(storageException);
  176. if (message != String.Empty)
  177. {
  178. LogDebug(message);
  179. }
  180. }
  181. public void MessageDetectingActualDataBlocks()
  182. {
  183. LogMessage(Resources.PSSyncOutputEventsDetectingActualDataBlocks);
  184. }
  185. public void MessageDetectingActualDataBlocksCompleted()
  186. {
  187. LogMessage(Resources.PSSyncOutputEventsDetectingActualDataBlocksCompleted);
  188. }
  189. public void MessagePrintBlockRange(IndexRange range)
  190. {
  191. LogMessage(Resources.PSSyncOutputEventsPrintBlockRange, range, range.Length);
  192. }
  193. public void DebugEmptyBlockDetected(IndexRange range)
  194. {
  195. LogDebug(Resources.PSSyncOutputEventsEmptyBlockDetected, range.ToString());
  196. }
  197. private void LogDebug(string format, params object[] parameters)
  198. {
  199. var message = String.Format(format, parameters);
  200. var debugMessage = String.Format("Write-Debug -Message '{0}'", message);
  201. using (var ps = System.Management.Automation.PowerShell.Create())
  202. {
  203. ps.Runspace = runspace;
  204. ps.AddScript(debugMessage);
  205. ps.Invoke();
  206. }
  207. }
  208. public void ProgressEmptyBlockDetection(int processedRangeCount, int totalRangeCount)
  209. {
  210. using(var ps = System.Management.Automation.PowerShell.Create())
  211. {
  212. if (processedRangeCount >= totalRangeCount)
  213. {
  214. var progressCommand1 = String.Format(@"Write-Progress -Id {0} -Activity '{1}' -Status '{2}' -Completed", 2, Resources.PSSyncOutputEventsProgressEmptyBlockDetection, Resources.PSSyncOutputEventsEmptyBlockDetectionCompleted);
  215. ps.Runspace = runspace;
  216. ps.AddScript(progressCommand1);
  217. ps.Invoke();
  218. return;
  219. }
  220. var progressCommand = String.Format(@"Write-Progress -Id {0} -Activity '{1}' -Status '{2}' -SecondsRemaining {3} -PercentComplete {4}", 2, Resources.PSSyncOutputEventsProgressEmptyBlockDetection, Resources.PSSyncOutputEventsEmptyBlockDetectionDetecting, -1, ((double)processedRangeCount / totalRangeCount) * 100);
  221. ps.Runspace = runspace;
  222. ps.AddScript(progressCommand);
  223. ps.Invoke();
  224. }
  225. }
  226. public void WriteVerboseWithTimestamp(string message, params object[] args)
  227. {
  228. var messageWithTimeStamp = string.Format(CultureInfo.CurrentCulture, "{0:T} - {1}", DateTime.Now, string.Format(message, args));
  229. var progressCommand = String.Format(@"Write-Verbose -Message {0}", messageWithTimeStamp);
  230. using (var ps = System.Management.Automation.PowerShell.Create())
  231. {
  232. ps.Runspace = runspace;
  233. ps.AddScript(progressCommand);
  234. ps.Invoke();
  235. }
  236. }
  237. public void Dispose()
  238. {
  239. Dispose(true);
  240. GC.SuppressFinalize(this);
  241. }
  242. protected virtual void Dispose(bool disposing)
  243. {
  244. if(!disposed)
  245. {
  246. if (disposing)
  247. {
  248. runspace.Dispose();
  249. }
  250. this.disposed = true;
  251. }
  252. }
  253. }
  254. }