protected void StudyStorageView_DataBound(object sender, EventArgs e) { StudyStorageLocation ssl = (StudyStorageViewControl.DataItem) as StudyStorageLocation; if (ssl != null) { Label statusLabel = StudyStorageViewControl.FindControl("Status") as Label; if (statusLabel != null) { statusLabel.Text = ServerEnumDescription.GetLocalizedDescription(ssl.StudyStatusEnum); } Label queueStateLable = StudyStorageViewControl.FindControl("QueueState") as Label; if (queueStateLable != null) { queueStateLable.Text = ServerEnumDescription.GetLocalizedDescription(ssl.QueueStudyStateEnum); } Label studyFolder = StudyStorageViewControl.FindControl("StudyFolder") as Label; if (studyFolder != null) { studyFolder.Text = ssl.GetStudyPath(); } Label transferSyntaxUID = StudyStorageViewControl.FindControl("TransferSyntaxUID") as Label; if (transferSyntaxUID != null) { transferSyntaxUID.Text = TransferSyntax.GetTransferSyntax(ssl.TransferSyntaxUid).Name; } Label tier = StudyStorageViewControl.FindControl("Tier") as Label; if (tier != null) { tier.Text = ServerEnumDescription.GetLocalizedDescription(ssl.FilesystemTierEnum); } Label studySize = StudyStorageViewControl.FindControl("StudySize") as Label; if (studySize != null) { ulong sizeInBytes = (ulong)(ssl.Study.StudySizeInKB * 1024); studySize.Text = ByteCountFormatter.Format(sizeInBytes); } } }
public void GetStudy(string studyInstanceUid, Uri baseUri, string serverAE, bool singleImage) { Console.WriteLine("[{0}] : Loading {1}", _id, studyInstanceUid); string uri = String.Format("http://{0}:{1}/HeaderStreaming/HeaderStreaming", "localhost", 50221); EndpointAddress endpoint = new EndpointAddress(uri); BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None); binding.TransferMode = TransferMode.Streamed; binding.MessageEncoding = WSMessageEncoding.Mtom; binding.MaxReceivedMessageSize = Int32.MaxValue; binding.TextEncoding = Encoding.UTF8; HeaderStreamingServiceClient headerClient = new HeaderStreamingServiceClient(binding, endpoint); using (headerClient) { HeaderStreamingParameters parms = new HeaderStreamingParameters(); parms.StudyInstanceUID = studyInstanceUid; parms.ReferenceID = Guid.NewGuid().ToString(); parms.ServerAETitle = "ImageServer"; Stream stream = headerClient.GetStudyHeader("TEST", parms); XmlDocument doc = new XmlDocument(); StudyXmlIo.ReadGzip(doc, stream); _studyXml = new StudyXml(studyInstanceUid); _studyXml.SetMemento(doc); stream.Close(); headerClient.Close(); } if (singleImage) { ulong size = 0; StreamingClient client = new StreamingClient(baseUri); foreach (SeriesXml series in _studyXml) { foreach (InstanceXml instance in series) { do { Stream image = client.RetrieveImage(serverAE, studyInstanceUid, series.SeriesInstanceUid, instance.SopInstanceUid); byte[] buffer = new byte[image.Length]; image.Read(buffer, 0, buffer.Length); image.Close(); Console.Write("."); } while (true); } Console.WriteLine("\n[{0}] : Finish Loading {1} [{2}]", _id, studyInstanceUid, ByteCountFormatter.Format(size)); } } else { Random ran = new Random(); do { ulong size = 0; StreamingClient client = new StreamingClient(baseUri); foreach (SeriesXml series in _studyXml) { foreach (InstanceXml instance in series) { Stream image = client.RetrieveImage(serverAE, studyInstanceUid, series.SeriesInstanceUid, instance.SopInstanceUid); byte[] buffer = new byte[image.Length]; image.Read(buffer, 0, buffer.Length); image.Close(); size += (ulong)buffer.Length; Console.Write("."); } Console.WriteLine("\n[{0}] : Finish Loading {1} [{2}]", _id, studyInstanceUid, ByteCountFormatter.Format(size)); } Thread.Sleep(ran.Next(1000, 5000)); } while (true); } }
private void Retrieve_Click(object sender, EventArgs e) { try { Uri baseUri = new Uri(String.Format("{0}/{1}", BaseUri.Text, ServerAE.Text)); StringBuilder url = new StringBuilder(); url.AppendFormat("{0}?requesttype=WADO&studyUID={1}&seriesUID={2}&objectUID={3}", baseUri, StudyUid.Text, SeriesUid.Text, ObjectUid.Text); if (UseFrame.Checked) { url.AppendFormat("&frameNumber={0}", int.Parse(Frame.Text)); } ContentTypes type = (ContentTypes)ContentTypes.SelectedItem; switch (type) { case ImageStreaming.ContentTypes.Dicom: url.AppendFormat("&ContentType={0}", "application/dicom"); break; case ImageStreaming.ContentTypes.RawPixel: url.AppendFormat("&ContentType={0}", "application/clearcanvas"); break; case ImageStreaming.ContentTypes.NotSpecified: break; } RateStatistics speed = new RateStatistics("Speed", RateType.BYTES); speed.Start(); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url.ToString()); request.Accept = "application/dicom,application/clearcanvas"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode != HttpStatusCode.OK) { throw new Exception(String.Format("Server responded with an error: {0}", HttpUtility.HtmlDecode(response.StatusDescription))); } byte[] buffer = new byte[response.ContentLength]; Stream stream = response.GetResponseStream(); int offset = 0; do { int readSize = stream.Read(buffer, offset, buffer.Length - offset); if (readSize <= 0) { break; } offset += readSize; } while (true); stream.Close(); speed.SetData(buffer.Length); speed.End(); String msg = String.Format("Mime:\t{0}\nSize:\t{1}\nSpeed:\t{2}", response.ContentType, ByteCountFormatter.Format((ulong)buffer.Length), speed.FormattedValue); MessageBox.Show(msg); } catch (WebException ex) { HttpWebResponse rsp = (ex.Response as HttpWebResponse); if (rsp != null) { string msg = String.Format("Error: {0}\n{1}", rsp.StatusCode, HttpUtility.HtmlDecode(rsp.StatusDescription) ); MessageBox.Show(msg); } } }
/// <summary> /// Migrates the study to new tier /// </summary> /// <param name="storage"></param> /// <param name="newFilesystem"></param> private void DoMigrateStudy(StudyStorageLocation storage, ServerFilesystemInfo newFilesystem) { Platform.CheckForNullReference(storage, "storage"); Platform.CheckForNullReference(newFilesystem, "newFilesystem"); TierMigrationStatistics stat = new TierMigrationStatistics { StudyInstanceUid = storage.StudyInstanceUid }; stat.ProcessSpeed.Start(); StudyXml studyXml = storage.LoadStudyXml(); stat.StudySize = (ulong)studyXml.GetStudySize(); Platform.Log(LogLevel.Info, "About to migrate study {0} from {1} to {2}", storage.StudyInstanceUid, storage.FilesystemTierEnum, newFilesystem.Filesystem.Description); string newPath = Path.Combine(newFilesystem.Filesystem.FilesystemPath, storage.PartitionFolder); DateTime startTime = Platform.Time; DateTime lastLog = Platform.Time; int fileCounter = 0; ulong bytesCopied = 0; long instanceCountInXml = studyXml.NumberOfStudyRelatedInstances; using (ServerCommandProcessor processor = new ServerCommandProcessor("Migrate Study")) { TierMigrationContext context = new TierMigrationContext { OriginalStudyLocation = storage, Destination = newFilesystem }; // The multiple CreateDirectoryCommands are done so that rollback of the directories being created happens properly if either of the directories already exist. var origFolder = context.OriginalStudyLocation.GetStudyPath(); processor.AddCommand(new CreateDirectoryCommand(newPath)); newPath = Path.Combine(newPath, context.OriginalStudyLocation.StudyFolder); processor.AddCommand(new CreateDirectoryCommand(newPath)); newPath = Path.Combine(newPath, context.OriginalStudyLocation.StudyInstanceUid); // don't create this directory so that it won't be backed up by MoveDirectoryCommand var copyDirCommand = new CopyDirectoryCommand(origFolder, newPath, delegate(string path) { // Update the progress. This is useful if the migration takes long time to complete. FileInfo file = new FileInfo(path); bytesCopied += (ulong)file.Length; fileCounter++; if (file.Extension != null && file.Extension.Equals(ServerPlatform.DicomFileExtension, StringComparison.InvariantCultureIgnoreCase)) { TimeSpan elapsed = Platform.Time - lastLog; TimeSpan totalElapsed = Platform.Time - startTime; double speedInMBPerSecond = 0; if (totalElapsed.TotalSeconds > 0) { speedInMBPerSecond = (bytesCopied / 1024f / 1024f) / totalElapsed.TotalSeconds; } if (elapsed > TimeSpan.FromSeconds(WorkQueueSettings.Instance.TierMigrationProgressUpdateInSeconds)) { #region Log Progress StringBuilder stats = new StringBuilder(); if (instanceCountInXml != 0) { float pct = (float)fileCounter / instanceCountInXml; stats.AppendFormat("{0} files moved [{1:0.0}MB] since {2} ({3:0}% completed). Speed={4:0.00}MB/s", fileCounter, bytesCopied / 1024f / 1024f, startTime, pct * 100, speedInMBPerSecond); } else { stats.AppendFormat("{0} files moved [{1:0.0}MB] since {2}. Speed={3:0.00}MB/s", fileCounter, bytesCopied / 1024f / 1024f, startTime, speedInMBPerSecond); } Platform.Log(LogLevel.Info, "Tier migration for study {0}: {1}", storage.StudyInstanceUid, stats.ToString()); try { using (IUpdateContext ctx = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush)) { IWorkQueueEntityBroker broker = ctx.GetBroker <IWorkQueueEntityBroker>(); WorkQueueUpdateColumns parameters = new WorkQueueUpdateColumns { FailureDescription = stats.ToString() }; broker.Update(WorkQueueItem.GetKey(), parameters); ctx.Commit(); } } catch { // can't log the progress so far... just ignore it } finally { lastLog = DateTime.Now; } #endregion } } }); processor.AddCommand(copyDirCommand); DeleteDirectoryCommand delDirCommand = new DeleteDirectoryCommand(origFolder, false) { RequiresRollback = false }; processor.AddCommand(delDirCommand); TierMigrateDatabaseUpdateCommand updateDbCommand = new TierMigrateDatabaseUpdateCommand(context); processor.AddCommand(updateDbCommand); Platform.Log(LogLevel.Info, "Start migrating study {0}.. expecting {1} to be moved", storage.StudyInstanceUid, ByteCountFormatter.Format(stat.StudySize)); if (!processor.Execute()) { if (processor.FailureException != null) { throw processor.FailureException; } throw new ApplicationException(processor.FailureReason); } stat.DBUpdate = updateDbCommand.Statistics; stat.CopyFiles = copyDirCommand.CopySpeed; stat.DeleteDirTime = delDirCommand.Statistics; } stat.ProcessSpeed.SetData(bytesCopied); stat.ProcessSpeed.End(); Platform.Log(LogLevel.Info, "Successfully migrated study {0} from {1} to {2} in {3} [ {4} files, {5} @ {6}, DB Update={7}, Remove Dir={8}]", storage.StudyInstanceUid, storage.FilesystemTierEnum, newFilesystem.Filesystem.FilesystemTierEnum, TimeSpanFormatter.Format(stat.ProcessSpeed.ElapsedTime), fileCounter, ByteCountFormatter.Format(bytesCopied), stat.CopyFiles.FormattedValue, stat.DBUpdate.FormattedValue, stat.DeleteDirTime.FormattedValue); string originalPath = storage.GetStudyPath(); if (Directory.Exists(storage.GetStudyPath())) { Platform.Log(LogLevel.Info, "Original study folder could not be deleted. It must be cleaned up manually: {0}", originalPath); ServerPlatform.Alert(AlertCategory.Application, AlertLevel.Warning, WorkQueueItem.WorkQueueTypeEnum.ToString(), 1000, GetWorkQueueContextData(WorkQueueItem), TimeSpan.Zero, "Study has been migrated to a new tier. Original study folder must be cleaned up manually: {0}", originalPath); } UpdateAverageStatistics(stat); }
private static void RetrieveImages(string serverAE, string studyPath) { Console.WriteLine("server={0}", serverAE); string baseUri = String.Format("http://{0}:{1}", serverHost, serverPort); StreamingClient client = new StreamingClient(new Uri(baseUri)); int totalFrameCount = 0; DirectoryInfo directoryInfo = new DirectoryInfo(studyPath); string studyUid = directoryInfo.Name; RateStatistics frameRate = new RateStatistics("Speed", "frame"); RateStatistics speed = new RateStatistics("Speed", RateType.BYTES); AverageRateStatistics averageSpeed = new AverageRateStatistics(RateType.BYTES); ByteCountStatistics totalSize = new ByteCountStatistics("Size"); frameRate.Start(); speed.Start(); Console.WriteLine("\n------------------------------------------------------------------------------------------------------------------------"); string[] seriesDirs = Directory.GetDirectories(studyPath); foreach (string seriesPath in seriesDirs) { DirectoryInfo dirInfo = new DirectoryInfo(seriesPath); string seriesUid = dirInfo.Name; string[] objectUidPath = Directory.GetFiles(seriesPath, "*.dcm"); foreach (string uidPath in objectUidPath) { FileInfo fileInfo = new FileInfo(uidPath); string uid = fileInfo.Name.Replace(".dcm", ""); Console.Write("{0,-64}... ", uid); try { Stream imageStream; StreamingResultMetaData imageMetaData; FrameStreamingResultMetaData frameMetaData; switch (type) { case ContentTypes.Dicom: imageStream = client.RetrieveImage(serverAE, studyUid, seriesUid, uid, out imageMetaData); totalFrameCount++; averageSpeed.AddSample(imageMetaData.Speed); totalSize.Value += (ulong)imageMetaData.ContentLength; Console.WriteLine("1 dicom sop [{0,10}] in {1,12}\t[mime={2}]", ByteCountFormatter.Format((ulong)imageStream.Length), TimeSpanFormatter.Format(imageMetaData.Speed.ElapsedTime), imageMetaData.ResponseMimeType); break; case ContentTypes.RawPixel: TimeSpanStatistics elapsedTime = new TimeSpanStatistics(); elapsedTime.Start(); ulong instanceSize = 0; int frameCount = 0; do { RetrievePixelDataResult result = client.RetrievePixelData(serverAE, studyUid, seriesUid, uid, frameCount); frameMetaData = result.MetaData; totalFrameCount++; frameCount++; averageSpeed.AddSample(frameMetaData.Speed); totalSize.Value += (ulong)frameMetaData.ContentLength; instanceSize += (ulong)frameMetaData.ContentLength; } while (!frameMetaData.IsLast); elapsedTime.End(); Console.WriteLine("{0,3} frame(s) [{1,10}] in {2,12}\t[mime={3}]", frameCount, ByteCountFormatter.Format(instanceSize), elapsedTime.FormattedValue, frameMetaData.ResponseMimeType); break; default: imageStream = client.RetrieveImage(serverAE, studyUid, seriesUid, uid, out imageMetaData); totalFrameCount++; averageSpeed.AddSample(imageMetaData.Speed); totalSize.Value += (ulong)imageMetaData.ContentLength; Console.WriteLine("1 object [{0,10}] in {1,12}\t[mime={2}]", ByteCountFormatter.Format((ulong)imageStream.Length), TimeSpanFormatter.Format(imageMetaData.Speed.ElapsedTime), imageMetaData.ResponseMimeType); break; } } catch (Exception ex) { if (ex is WebException) { HttpWebResponse rsp = ((ex as WebException).Response as HttpWebResponse); string msg = String.Format("Error: {0} : {1}", rsp.StatusCode, HttpUtility.HtmlDecode(rsp.StatusDescription) ); Console.WriteLine(msg); } else { Console.WriteLine(ex.Message); } } } } frameRate.SetData(totalFrameCount); frameRate.End(); speed.SetData(totalSize.Value); speed.End(); Console.WriteLine("\nTotal {0,3} image(s)/frame(s) [{1,10}] in {2,12} ==> [ Speed: {3,12} or {4,12}]", totalFrameCount, totalSize.FormattedValue, TimeSpanFormatter.Format(frameRate.ElapsedTime), frameRate.FormattedValue, speed.FormattedValue ); }