Exemplo n.º 1
0
 internal RetryContext(int currentRetryCount, RequestResult lastRequestResult, StorageLocation nextLocation, LocationMode locationMode)
 {
     this.CurrentRetryCount = currentRetryCount;
     this.LastRequestResult = lastRequestResult;
     this.NextLocation = nextLocation;
     this.LocationMode = locationMode;
 }
        public RandomNumberStream(StorageLocation location, 
            RandomNumberGeneratorType type = RandomNumberGeneratorType.MRG32K3A, int seed = 111)
        {
            _location = location;
            _innerStream = ExecutionContext.Executor.CreateRandomNumberStream(location, type, seed);

            Type = type;
            Seed = seed;
        }
        public StorageLocation GetStorageLocation(string location)
        {
            var locationLowerCase = location.ToLower();
            var storageLocation = _storage.StorageLocations.Where(x => x.Location.ToLower() == locationLowerCase).FirstOrDefault();
            if (storageLocation == null)
            {
                storageLocation = new StorageLocation(location, 0);
                _storage.StorageLocations.Add(storageLocation);
            }
            else
            {
                storageLocation.LastReadTicks = DateTime.Now.Ticks;
            }

            return storageLocation;
        }
        public StorageWindowsShared(StorageLocation storageLocation = StorageLocation.Temp)
        {
            switch(storageLocation)
            {
                case StorageLocation.Local:
                    _baseFolder = ApplicationData.Current.LocalFolder;
                    break;

                case StorageLocation.Roaming:
                    _baseFolder = ApplicationData.Current.RoamingFolder;
                    break;

                case StorageLocation.Temp:
                    _baseFolder = ApplicationData.Current.TemporaryFolder;
                    break;

                default:
                    throw new ArgumentOutOfRangeException("storagelocation");
            }
        }
        private static char Serialize(StorageLocation? location)
        {
            if (!location.HasValue)
            {
                return '*'; // Primary or Secondary
            }
            else
            {
                StorageLocation locationValue = location.Value;

                switch (locationValue)
                {
                    case StorageLocation.Primary:
                        return 'P';
                    case StorageLocation.Secondary:
                        return 'S';
                    default:
                        throw new ArgumentOutOfRangeException("location", "Unknown StorageLocation.");
                }
            }
        }
        public IStorage CreateStorage(StorageLocation storageLocation)
        {
            var storage = new StorageWindowsShared(storageLocation);

            var minDimension = Math.Min(ServiceLocator.SystemInformationService.ScreenHeight,
                ServiceLocator.SystemInformationService.ScreenWidth);

            if (minDimension < 400)
            {
                storage.SetImageMaxThumbnailWidthHeight(200);
            }
            else if (minDimension <= 700)
            {
                storage.SetImageMaxThumbnailWidthHeight(400);
            }
            else
            {
                storage.SetImageMaxThumbnailWidthHeight(600);
            }

            return storage;
        }
Exemplo n.º 7
0
            public MultiLocationTestHelper(StorageUri storageUri, StorageLocation initialLocation, IList<RetryContext> retryContextList, IList<RetryInfo> retryInfoList)
            {
                this.storageUri = storageUri;
                this.initialLocation = initialLocation;
                this.retryContextList = retryContextList;
                this.retryInfoList = retryInfoList;

                this.OperationContext = new OperationContext();
                this.OperationContext.SendingRequest += this.SendingRequest;

                this.RetryPolicy = new AlwaysRetry(this.retryContextList, this.retryInfoList);
            }
Exemplo n.º 8
0
        private static async Task TestTableRetrieveAsync(LocationMode? optionsLocationMode, LocationMode clientLocationMode, StorageLocation initialLocation, IList<RetryContext> retryContextList, IList<RetryInfo> retryInfoList)
        {
            CloudTable table = GenerateCloudTableClient().GetTableReference(TableTestBase.GenerateRandomTableName());
            using (MultiLocationTestHelper helper = new MultiLocationTestHelper(table.ServiceClient.StorageUri, initialLocation, retryContextList, retryInfoList))
            {
                table.ServiceClient.DefaultRequestOptions.LocationMode = clientLocationMode;
                TableRequestOptions options = new TableRequestOptions()
                {
                    LocationMode = optionsLocationMode,
                    RetryPolicy = helper.RetryPolicy,
                };

                await TestHelper.ExpectedExceptionAsync(
                    async () => await table.GetPermissionsAsync(options, helper.OperationContext),
                    helper.OperationContext,
                    "GetPermissions on a non-existing table should fail",
                    HttpStatusCode.NotFound);
            }
        }
Exemplo n.º 9
0
        private static async Task TestQueueFetchAttributesAsync(LocationMode? optionsLocationMode, LocationMode clientLocationMode, StorageLocation initialLocation, IList<RetryContext> retryContextList, IList<RetryInfo> retryInfoList)
        {
            CloudQueue queue = GenerateCloudQueueClient().GetQueueReference(QueueTestBase.GenerateNewQueueName());
            using (MultiLocationTestHelper helper = new MultiLocationTestHelper(queue.ServiceClient.StorageUri, initialLocation, retryContextList, retryInfoList))
            {
                queue.ServiceClient.DefaultRequestOptions.LocationMode = clientLocationMode;
                QueueRequestOptions options = new QueueRequestOptions()
                {
                    LocationMode = optionsLocationMode,
                    RetryPolicy = helper.RetryPolicy,
                };

                await TestHelper.ExpectedExceptionAsync(
                    async () => await queue.FetchAttributesAsync(options, helper.OperationContext),
                    helper.OperationContext,
                    "FetchAttributes on a non-existing queue should fail",
                    HttpStatusCode.NotFound);
            }
        }
Exemplo n.º 10
0
        private static async Task TestContainerFetchAttributesAsync(LocationMode? optionsLocationMode, LocationMode clientLocationMode, StorageLocation initialLocation, IList<RetryContext> retryContextList, IList<RetryInfo> retryInfoList)
        {
            CloudBlobContainer container = BlobTestBase.GetRandomContainerReference();
            using (MultiLocationTestHelper helper = new MultiLocationTestHelper(container.ServiceClient.StorageUri, initialLocation, retryContextList, retryInfoList))
            {
                container.ServiceClient.DefaultRequestOptions.LocationMode = clientLocationMode;
                BlobRequestOptions options = new BlobRequestOptions()
                {
                    LocationMode = optionsLocationMode,
                    RetryPolicy = helper.RetryPolicy,
                };

                await TestHelper.ExpectedExceptionAsync(
                    async () => await container.FetchAttributesAsync(null, options, helper.OperationContext),
                    helper.OperationContext,
                    "FetchAttributes on a non-existing container should fail",
                    HttpStatusCode.NotFound);
            }
        }
        private static StorageLocation GetNextLocation(LocationMode locationMode, StorageLocation currentLocation)
        {
            switch (locationMode)
            {
                case LocationMode.PrimaryOnly:
                    return StorageLocation.Primary;

                case LocationMode.SecondaryOnly:
                    return StorageLocation.Secondary;

                case LocationMode.PrimaryThenSecondary:
                case LocationMode.SecondaryThenPrimary:
                    return currentLocation == StorageLocation.Primary ? StorageLocation.Secondary : StorageLocation.Primary;

                default:
                    throw new ArgumentOutOfRangeException("locationMode");
            }
        }
Exemplo n.º 12
0
 public static IStorage GetStorage(StorageLocation storageLocation = StorageLocation.Local)
 {
     return ServiceLocator.StorageFactory.CreateStorage(storageLocation);
 }
Exemplo n.º 13
0
 /// <summary>
 /// Gets the minute metrics table for the specified storage service for the given location
 /// </summary>
 /// <param name="service"></param>
 /// <param name="location"></param>
 /// <returns></returns>
 public CloudTable GetMinuteMetricsTable(StorageLocation location)
 {
     return analyticsClient.GetMinuteMetricsTable(service, location);
 }
Exemplo n.º 14
0
 public Simulation(StorageLocation location, DateTime closeOfBusinessDate)
 {
 }
 /// <summary>
 /// Creates a <see cref="TableQuery"/> object for querying a minute metrics log table.
 /// </summary>
 /// <param name="service">A <see cref="StorageService"/> enumeration value.</param>
 /// <param name="location">A <see cref="StorageLocation"/> enumeration value.</param>
 /// <returns>A <see cref="TableQuery"/> object.</returns>
 public TableQuery<MetricsEntity> CreateMinuteMetricsQuery(StorageService service, StorageLocation location)
 {
     CloudTable minuteMetricsTable = this.GetMinuteMetricsTable(service, location);
     return minuteMetricsTable.CreateQuery<MetricsEntity>();
 }
Exemplo n.º 16
0
 public SettingStorageAttribute(StorageLocation location)
     : this(location, null)
 {
 }
        /// <summary>
        /// Gets the hourly metrics table for the specified storage service.
        /// </summary>
        /// <param name="service">A <see cref="StorageService"/> enumeration value.</param>
        /// <param name="location">A <see cref="StorageLocation"/> enumeration value.</param>
        /// <returns>A <see cref="CloudTable"/> object.</returns>
        public CloudTable GetHourMetricsTable(StorageService service, StorageLocation location)
        {
            switch (service)
            {
                case StorageService.Blob:
                    if (location == StorageLocation.Primary)
                    {
                        return this.tableClient.GetTableReference(Constants.AnalyticsConstants.MetricsHourPrimaryTransactionsBlob);
                    }
                    else
                    {
                        return this.tableClient.GetTableReference(Constants.AnalyticsConstants.MetricsHourSecondaryTransactionsBlob);
                    }

                case StorageService.Queue:
                    if (location == StorageLocation.Primary)
                    {
                        return this.tableClient.GetTableReference(Constants.AnalyticsConstants.MetricsHourPrimaryTransactionsQueue);
                    }
                    else
                    {
                        return this.tableClient.GetTableReference(Constants.AnalyticsConstants.MetricsHourSecondaryTransactionsQueue);
                    }

                case StorageService.Table:
                    if (location == StorageLocation.Primary)
                    {
                        return this.tableClient.GetTableReference(Constants.AnalyticsConstants.MetricsHourPrimaryTransactionsTable);
                    }
                    else
                    {
                        return this.tableClient.GetTableReference(Constants.AnalyticsConstants.MetricsHourSecondaryTransactionsTable);
                    }

                default:
                    throw new ArgumentException(SR.InvalidStorageService);
            }
        }
Exemplo n.º 18
0
 public SettingStorageAttribute(StorageLocation location, string key)
 {
     this.location = location;
     this.key = key;
 }
Exemplo n.º 19
0
 public Context(StorageLocation location, DateTime closeOfBusinessDate)
 {
     Factory = new NArrayFactory(location);
     Settings = new SimulationSettings(closeOfBusinessDate);
 }
        protected override void ProcessItem(Model.WorkQueue item)
        {
            Platform.CheckForNullReference(item, "item");
            Platform.CheckForNullReference(item.StudyStorageKey, "item.StudyStorageKey");

            bool   successful         = true;
            string failureDescription = null;

            // The processor stores its state in the Data column
            ReadQueueData(item);


            if (_queueData.State == null || !_queueData.State.ExecuteAtLeastOnce)
            {
                // Added for ticket #9673:
                // If the study folder does not exist and the study has been archived, trigger a restore and we're done
                if (!Directory.Exists(StorageLocation.GetStudyPath()))
                {
                    if (StorageLocation.ArchiveLocations.Count > 0)
                    {
                        Platform.Log(LogLevel.Info,
                                     "Reprocessing archived study {0} for Patient {1} (PatientId:{2} A#:{3}) on Partition {4} without study data on the filesystem.  Inserting Restore Request.",
                                     Study.StudyInstanceUid, Study.PatientsName, Study.PatientId,
                                     Study.AccessionNumber, ServerPartition.Description);

                        PostProcessing(item, WorkQueueProcessorStatus.Complete, WorkQueueProcessorDatabaseUpdate.ResetQueueState);

                        // Post process had to be done first so the study is unlocked so the RestoreRequest can be inserted.
                        ServerHelper.InsertRestoreRequest(StorageLocation);

                        RaiseAlert(WorkQueueItem, AlertLevel.Warning,
                                   string.Format(
                                       "Found study {0} for Patient {1} (A#:{2})on Partition {3} without storage folder, restoring study.",
                                       Study.StudyInstanceUid, Study.PatientsName, Study.AccessionNumber, ServerPartition.Description));
                        return;
                    }
                }

                if (Study == null)
                {
                    Platform.Log(LogLevel.Info,
                                 "Reprocessing study {0} on Partition {1}", StorageLocation.StudyInstanceUid,
                                 ServerPartition.Description);
                }
                else
                {
                    Platform.Log(LogLevel.Info,
                                 "Reprocessing study {0} for Patient {1} (PatientId:{2} A#:{3}) on Partition {4}",
                                 Study.StudyInstanceUid, Study.PatientsName, Study.PatientId,
                                 Study.AccessionNumber, ServerPartition.Description);
                }

                CleanupDatabase();
            }
            else
            {
                if (_queueData.State.Completed)
                {
                    #region SAFE-GUARD CODE: PREVENT INFINITE LOOP

                    // The processor indicated it had completed reprocessing in previous run. The entry should have been removed and this block of code should never be called.
                    // However, we have seen ReprocessStudy entries that mysterously contain rows in the WorkQueueUid table.
                    // The rows prevent the entry from being removed from the database and the ReprocessStudy keeps repeating itself.


                    // update the state first, increment the CompleteAttemptCount
                    _queueData.State.ExecuteAtLeastOnce = true;
                    _queueData.State.Completed          = true;
                    _queueData.State.CompleteAttemptCount++;
                    SaveState(item, _queueData);

                    if (_queueData.State.CompleteAttemptCount < 10)
                    {
                        // maybe there was db error in previous attempt to remove the entry. Let's try again.
                        Platform.Log(LogLevel.Info, "Resuming Reprocessing study {0} but it was already completed!!!", StorageLocation.StudyInstanceUid);
                        PostProcessing(item, WorkQueueProcessorStatus.Complete, WorkQueueProcessorDatabaseUpdate.ResetQueueState);
                    }
                    else
                    {
                        // we are definitely stuck.
                        Platform.Log(LogLevel.Error, "ReprocessStudy {0} for study {1} appears stuck. Aborting it.", item.Key, StorageLocation.StudyInstanceUid);
                        item.FailureDescription = "This entry had completed but could not be removed.";
                        PostProcessingFailure(item, WorkQueueProcessorFailureType.Fatal);
                    }

                    return;

                    #endregion
                }

                if (Study == null)
                {
                    Platform.Log(LogLevel.Info,
                                 "Resuming Reprocessing study {0} on Partition {1}", StorageLocation.StudyInstanceUid,
                                 ServerPartition.Description);
                }
                else
                {
                    Platform.Log(LogLevel.Info,
                                 "Resuming Reprocessing study {0} for Patient {1} (PatientId:{2} A#:{3}) on Partition {4}",
                                 Study.StudyInstanceUid, Study.PatientsName, Study.PatientId,
                                 Study.AccessionNumber, ServerPartition.Description);
                }
            }

            // As per #12583, Creation of the SopInstanceProcessor should occur after the CleanupDatabase() call.
            var context = new StudyProcessorContext(StorageLocation, WorkQueueItem);

            // TODO: Should we enforce the patient's name rule?
            // If we do, the Study record will have the new patient's name
            // but how should we handle the name in the Patient record?
            const bool enforceNameRules = false;
            var        processor        = new SopInstanceProcessor(context)
            {
                EnforceNameRules = enforceNameRules
            };

            var seriesMap = new Dictionary <string, List <string> >();

            StudyXml studyXml = LoadStudyXml();

            var reprocessedCounter = 0;
            var skippedCount       = 0;
            var removedFiles       = new List <FileInfo>();
            try
            {
                // Traverse the directories, process 500 files at a time
                var isCancelled = FileProcessor.Process(StorageLocation.GetStudyPath(), "*.*",
                                                        delegate(string path, out bool cancel)
                {
                    #region Reprocess File

                    var file = new FileInfo(path);

                    // ignore all files except those ending ".dcm"
                    // ignore "bad(0).dcm" files too
                    if (Regex.IsMatch(file.Name.ToUpper(), "[0-9]+\\.DCM$"))
                    {
                        try
                        {
                            var dicomFile = new DicomFile(path);
                            dicomFile.Load(DicomReadOptions.StorePixelDataReferences | DicomReadOptions.Default);

                            string seriesUid   = dicomFile.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty);
                            string instanceUid = dicomFile.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty);
                            if (studyXml.Contains(seriesUid, instanceUid))
                            {
                                if (!seriesMap.ContainsKey(seriesUid))
                                {
                                    seriesMap.Add(seriesUid, new List <string>());
                                }
                                if (!seriesMap[seriesUid].Contains(instanceUid))
                                {
                                    seriesMap[seriesUid].Add(instanceUid);
                                }
                                else
                                {
                                    Platform.Log(LogLevel.Warn, "SOP Instance UID in {0} appears more than once in the study.", path);
                                }

                                skippedCount++;
                            }
                            else
                            {
                                Platform.Log(ServerPlatform.InstanceLogLevel, "Reprocessing SOP {0} for study {1}", instanceUid, StorageLocation.StudyInstanceUid);
                                string groupId          = ServerHelper.GetUidGroup(dicomFile, StorageLocation.ServerPartition, WorkQueueItem.InsertTime);
                                ProcessingResult result = processor.ProcessFile(groupId, dicomFile, studyXml, true, false, null, null, SopInstanceProcessorSopType.ReprocessedSop);
                                switch (result.Status)
                                {
                                case ProcessingStatus.Success:
                                    reprocessedCounter++;
                                    if (!seriesMap.ContainsKey(seriesUid))
                                    {
                                        seriesMap.Add(seriesUid, new List <string>());
                                    }

                                    if (!seriesMap[seriesUid].Contains(instanceUid))
                                    {
                                        seriesMap[seriesUid].Add(instanceUid);
                                    }
                                    else
                                    {
                                        Platform.Log(LogLevel.Warn, "SOP Instance UID in {0} appears more than once in the study.", path);
                                    }
                                    break;

                                case ProcessingStatus.Reconciled:
                                    Platform.Log(LogLevel.Warn, "SOP was unexpectedly reconciled on reprocess SOP {0} for study {1}. It will be removed from the folder.", instanceUid, StorageLocation.StudyInstanceUid);
                                    failureDescription = String.Format("SOP Was reconciled: {0}", instanceUid);

                                    // Added for #10620 (Previously we didn't do anything here)
                                    // Because we are reprocessing files in the study folder, when file needs to be reconciled it is copied to the reconcile folder
                                    // Therefore, we need to delete the one in the study folder. Otherwise, there will be problem when the SIQ entry is reconciled.
                                    // InstanceAlreadyExistsException will also be thrown by the SOpInstanceProcessor if this ReprocessStudy WQI
                                    // resumes and reprocesses the same file again.
                                    // Note: we are sure that the file has been copied to the Reconcile folder and there's no way back.
                                    // We must get rid of this file in the study folder.
                                    FileUtils.Delete(path);

                                    // Special handling: if the file is one which we're supposed to reprocess at the end (see ProcessAdditionalFiles), we must remove the file from the list
                                    if (_additionalFilesToProcess != null && _additionalFilesToProcess.Contains(path))
                                    {
                                        _additionalFilesToProcess.Remove(path);
                                    }

                                    break;
                                }
                            }
                        }
                        catch (DicomException ex)
                        {
                            // TODO : should we fail the reprocess instead? Deleting an dicom file can lead to incomplete study.
                            removedFiles.Add(file);
                            Platform.Log(LogLevel.Warn, "Skip reprocessing and delete {0}: Not readable.", path);
                            FileUtils.Delete(path);
                            failureDescription = ex.Message;
                        }
                    }
                    else if (!file.Extension.Equals(".xml") && !file.Extension.Equals(".gz"))
                    {
                        // not a ".dcm" or header file, delete it
                        removedFiles.Add(file);
                        FileUtils.Delete(path);
                    }

                    #endregion

                    if (reprocessedCounter > 0 && reprocessedCounter % 200 == 0)
                    {
                        Platform.Log(LogLevel.Info, "Reprocessed {0} files for study {1}", reprocessedCounter + skippedCount, StorageLocation.StudyInstanceUid);
                    }

                    cancel = reprocessedCounter >= 5000;
                }, true);

                if (studyXml != null)
                {
                    EnsureConsistentObjectCount(studyXml, seriesMap);
                    SaveStudyXml(studyXml);
                }

                // Completed if either all files have been reprocessed
                // or no more dicom files left that can be reprocessed.
                _completed = reprocessedCounter == 0 || !isCancelled;
            }
            catch (Exception e)
            {
                successful         = false;
                failureDescription = e.Message;
                Platform.Log(LogLevel.Error, e, "Unexpected exception when reprocessing study: {0}", StorageLocation.StudyInstanceUid);
                Platform.Log(LogLevel.Error, "Study may be in invalid unprocessed state.  Study location: {0}", StorageLocation.GetStudyPath());
                throw;
            }
            finally
            {
                LogRemovedFiles(removedFiles);

                // Update the state
                _queueData.State.ExecuteAtLeastOnce = true;
                _queueData.State.Completed          = _completed;
                _queueData.State.CompleteAttemptCount++;
                SaveState(item, _queueData);

                if (!successful)
                {
                    FailQueueItem(item, failureDescription);
                }
                else
                {
                    if (!_completed)
                    {
                        // Put it back to Pending
                        PostProcessing(item, WorkQueueProcessorStatus.Pending, WorkQueueProcessorDatabaseUpdate.None);
                    }
                    else
                    {
                        // Reload the record from the database because referenced entities have been modified since the beginning.
                        // Need to reload because we are passing the location to the rule engine.
                        StorageLocation = CollectionUtils.FirstElement <StudyStorageLocation>(StudyStorageLocation.FindStorageLocations(item.ServerPartitionKey, StorageLocation.StudyInstanceUid), null);

                        LogHistory();

                        // Run Study / Series Rules Engine.
                        var engine = new StudyRulesEngine(StorageLocation, ServerPartition);
                        engine.Apply(ServerRuleApplyTimeEnum.StudyProcessed);

                        // Log the FilesystemQueue related entries
                        StorageLocation.LogFilesystemQueue();

                        PostProcessing(item, WorkQueueProcessorStatus.Complete, WorkQueueProcessorDatabaseUpdate.ResetQueueState);

                        Platform.Log(LogLevel.Info, "Completed reprocessing of study {0} on partition {1}", StorageLocation.StudyInstanceUid, ServerPartition.Description);
                    }
                }
            }
        }