protected override int OnStart(StudyLoaderArgs studyLoaderArgs) { _sops = null; EventResult result = EventResult.Success; var loadedInstances = new AuditedInstances(); try { using (var context = new DataAccessContext()) { IStudy study = context.GetStudyBroker().GetStudy(studyLoaderArgs.StudyInstanceUid); if (study == null) { result = EventResult.MajorFailure; loadedInstances.AddInstance(studyLoaderArgs.StudyInstanceUid); throw new NotFoundLoadStudyException(studyLoaderArgs.StudyInstanceUid); } loadedInstances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid); _sops = study.GetSopInstances().GetEnumerator(); return study.NumberOfStudyRelatedInstances; } } finally { AuditHelper.LogOpenStudies(new[] { AuditHelper.LocalAETitle }, loadedInstances, EventSource.CurrentUser, result); } }
private void ApplyDefaultDeletionRule(RulesEngineOptions context, StudyEntry study) { if (!context.ApplyDeleteActions) return; // TODO (CR Jun 2012): Again, seem to use "work item" mutex for all database updates. Should just pass in a boolean. using (var dac = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var broker = dac.GetStudyBroker(); var dbStudy = broker.GetStudy(study.Study.StudyInstanceUid); var storageConfiguration = StudyStore.GetConfiguration(); var defaultRule = storageConfiguration.DefaultDeletionRule; if (defaultRule.Enabled) { dbStudy.SetDeleteTime(defaultRule.TimeValue, defaultRule.TimeUnit, TimeOrigin.ReceivedDate, false); } else { dbStudy.ClearDeleteTime(); } dac.Commit(); } }
public void Initialize(StudyLocation location) { _location = location; using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var studyBroker = context.GetStudyBroker(); var study = studyBroker.GetStudy(_location.Study.StudyInstanceUid); if (study != null) { _location.Study = study; if (study.NumberOfStudyRelatedInstances.HasValue) NumberOfStudyRelatedInstances = study.NumberOfStudyRelatedInstances.Value; } } }
public bool Process() { // Decided not to use the command processor here, since we're just removing everything and want to be as forgiving as possible. try { DirectoryUtility.DeleteIfExists(_location.StudyFolder); } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unable to delete study folder: {0}", _location.StudyFolder); } try { using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var studyBroker = context.GetStudyBroker(); var study = studyBroker.GetStudy(_location.Study.StudyInstanceUid); if (study != null) { studyBroker.Delete(study); } context.Commit(); } Platform.Log(LogLevel.Info, "Deleted study for: {0}:{1}", _location.Study.PatientsName, _location.Study.PatientId); return true; } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception when {0} deleting Study related database entries for study: {0}", _location.Study.StudyInstanceUid); return false; } }
public WorkItemInsertResponse Insert(WorkItemInsertRequest request) { // TODO (CR Jun 2012): The fact that there is special processing in here for particular types of work items // indicates there is something wrong with the design that may make adding custom work item types difficult. // Maybe the different "processors" need to perform the insert, or at least have some kind of method (rule) // for processing the insert? var response = new WorkItemInsertResponse(); using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { DateTime now = Platform.Time; var broker = context.GetWorkItemBroker(); if (request.Request.WorkItemType.Equals(ReindexRequest.WorkItemTypeString)) { var list = broker.GetWorkItems(request.Request.WorkItemType, null, null); foreach (var workItem in list) { if (workItem.Status == WorkItemStatusEnum.Pending || workItem.Status == WorkItemStatusEnum.InProgress) { response.Item = WorkItemDataHelper.FromWorkItem(workItem); return response; } } } var deleteStudyRequest = request.Request as DeleteStudyRequest; if (deleteStudyRequest != null) { var list = broker.GetWorkItems(request.Request.WorkItemType, null, deleteStudyRequest.Study.StudyInstanceUid); foreach (var workItem in list) { if (workItem.Status == WorkItemStatusEnum.Pending || workItem.Status == WorkItemStatusEnum.InProgress) { // Mark studies to delete as "deleted" in the database. var studyBroker = context.GetStudyBroker(); var study = studyBroker.GetStudy(deleteStudyRequest.Study.StudyInstanceUid); if (study != null) { study.Deleted = true; context.Commit(); } response.Item = WorkItemDataHelper.FromWorkItem(workItem); return response; } } } var item = new WorkItem { Request = request.Request, Progress = request.Progress, Type = request.Request.WorkItemType, Priority = request.Request.Priority, ScheduledTime = now.AddSeconds(WorkItemServiceSettings.Default.InsertDelaySeconds), ProcessTime = now.AddSeconds(WorkItemServiceSettings.Default.InsertDelaySeconds), DeleteTime = now.AddMinutes(WorkItemServiceSettings.Default.DeleteDelayMinutes), ExpirationTime = now.AddSeconds(WorkItemServiceSettings.Default.ExpireDelaySeconds), RequestedTime = now, Status = WorkItemStatusEnum.Pending }; var studyRequest = request.Request as WorkItemStudyRequest; if (studyRequest != null) { item.StudyInstanceUid = studyRequest.Study.StudyInstanceUid; if (request.Request.WorkItemType.Equals(DeleteStudyRequest.WorkItemTypeString)) { // Mark studies to delete as "deleted" in the database. var studyBroker = context.GetStudyBroker(); var study = studyBroker.GetStudy(studyRequest.Study.StudyInstanceUid); if (study != null) study.Deleted = true; } } broker.AddWorkItem(item); context.Commit(); response.Item = WorkItemDataHelper.FromWorkItem(item); } // Cache the UserIdentityContext for later use by the shred if (request.Request.WorkItemType.Equals(ImportFilesRequest.WorkItemTypeString)) UserIdentityCache.Put(response.Item.Identifier,UserIdentityContext.CreateFromCurrentThreadPrincipal()); WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, response.Item); if (WorkItemProcessor.Instance != null) WorkItemProcessor.Instance.SignalThread(); return response; }
private void CheckDeleteStudyCanceled(DataAccessContext context, WorkItem workItem) { // Force the study to be visible again if its a DeleteStudyRequest we're canceling if (workItem.Type.Equals(DeleteStudyRequest.WorkItemTypeString)) { var studyBroker = context.GetStudyBroker(); var study = studyBroker.GetStudy(workItem.StudyInstanceUid); if (study != null) { study.Deleted = false; } } }
/// <summary> /// Called on startup to reset InProgress WorkItems back to Pending. /// </summary> private void ResetInProgressWorkItems() { bool reindexInProgress = false; using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var workItemBroker = context.GetWorkItemBroker(); var list = workItemBroker.GetWorkItems(null, WorkItemStatusEnum.InProgress, null); foreach (var item in list) { item.Status = WorkItemStatusEnum.Pending; if (item.Type.Equals(ReindexRequest.WorkItemTypeString)) reindexInProgress = true; } context.Commit(); } using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var workItemBroker = context.GetWorkItemBroker(); var list = workItemBroker.GetWorkItems(null, WorkItemStatusEnum.DeleteInProgress, null); foreach (var item in list) { item.Status = WorkItemStatusEnum.Deleted; } context.Commit(); } using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var workItemBroker = context.GetWorkItemBroker(); var list = workItemBroker.GetWorkItems(null, WorkItemStatusEnum.Canceling, null); foreach (var item in list) { item.Status = WorkItemStatusEnum.Canceled; if (item.Type.Equals(ReindexRequest.WorkItemTypeString)) reindexInProgress = true; } context.Commit(); } if (reindexInProgress) { using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var studyBroker = context.GetStudyBroker(); var studyList = studyBroker.GetReindexStudies(); foreach (var item in studyList) { item.Reindex = false; } context.Commit(); } } }
/// <summary> /// Initialize the Reapply Rules. Loast a list of studies. /// </summary> public void Initialize() { using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var broker = context.GetStudyBroker(); StudyOidList = broker.GetStudyOids(); } DatabaseStudiesToScan = StudyOidList.Count; }
private void ProcessStudiesInDatabase() { var rulesEngine = RulesEngine.Create(); foreach (var oid in StudyOidList) { try { // TODO (CR Jun 2012): We don't modify any work items - do we need the mutex? using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var broker = context.GetStudyBroker(); var study = broker.GetStudy(oid); var studyEntry = study.ToStoreEntry(); var rulesEngineOptions = new RulesEngineOptions { ApplyDeleteActions = _request.ApplyDeleteActions, ApplyRouteActions = _request.ApplyRouteActions }; if(!string.IsNullOrEmpty(_request.RuleId)) { rulesEngine.ApplyStudyRule(studyEntry, _request.RuleId, rulesEngineOptions); } else { rulesEngine.ApplyStudyRules(studyEntry, rulesEngineOptions); } EventsHelper.Fire(_studyProcessedEvent, this, new StudyEventArgs { StudyInstanceUid = study.StudyInstanceUid }); } } catch (Exception x) { Platform.Log(LogLevel.Warn, "Unexpected exception attempting to reapply rules for StudyOid {0}: {1}", oid, x.Message); } } }
private void ProcessStudiesInDatabase() { foreach (long oid in StudyOidList) { try { using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var broker = context.GetStudyBroker(); var study = broker.GetStudy(oid); var location = new StudyLocation(study.StudyInstanceUid); if (!Directory.Exists(location.StudyFolder)) { broker.Delete(study); context.Commit(); EventsHelper.Fire(_studyDeletedEvent, this, new StudyEventArgs { StudyInstanceUid = study.StudyInstanceUid }); Platform.Log(LogLevel.Info, "Deleted Study that wasn't on disk, but in the database: {0}", study.StudyInstanceUid); } else EventsHelper.Fire(_studyProcessedEvent, this, new StudyEventArgs { StudyInstanceUid = study.StudyInstanceUid }); } } catch (Exception x) { Platform.Log(LogLevel.Warn, "Unexpected exception attempting to reindex StudyOid {0}: {1}", oid, x.Message); } if (_cancelRequested) return; } }
private void ResetReindexStudies() { var resetStudyUids = new List<string>(); using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var studyBroker = context.GetStudyBroker(); var studyList = studyBroker.GetReindexStudies(); foreach (var study in studyList) { if (study.Reindex) { resetStudyUids.Add(study.StudyInstanceUid); study.Reindex = false; } } context.Commit(); } if (resetStudyUids.Count > 0) EventsHelper.Fire(_studiesRestoredEvent, this, new StudiesEventArgs { StudyInstanceUids = resetStudyUids }); }
/// <summary> /// Initialize the Reindex. Determine the number of studies in the database and the number of folders on disk to be used /// for progress. /// </summary> public void Initialize() { // Before scanning the study folders, cleanup any empty directories. CleanupFilestoreDirectory(); try { DirectoryList = new List<string>(Directory.GetDirectories(FilestoreDirectory)); } catch (Exception x) { Platform.Log(LogLevel.Error, x); throw; } StudyFoldersToScan = DirectoryList.Count; // TODO (CR Jun 2012): Seems we're using the "work item" mutex for all updates to the database. // Should we just pass in a boolean specifying whether or not to use a mutex? using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var broker = context.GetStudyBroker(); StudyOidList = new List<long>(); var studyList = broker.GetStudies(); foreach (var study in studyList) { study.Reindex = true; StudyOidList.Add(study.Oid); } context.Commit(); } DatabaseStudiesToScan = StudyOidList.Count; _threadPool.Start(); }
private bool CheckIfStudyExists() { using (var context = new DataAccessContext()) { var broker = context.GetStudyBroker(); var study = broker.GetStudy(Location.Study.StudyInstanceUid); if (study != null) { Location.Study = study; return true; } } return false; }
protected override int OnStart(StudyLoaderArgs studyLoaderArgs) { _sops = null; EventResult result = EventResult.Success; var loadedInstances = new AuditedInstances(); try { using (var context = new DataAccessContext()) { if (!studyLoaderArgs.Options.IgnoreInUse) { var activeUpdateItems = context.GetWorkItemBroker().GetWorkItems(WorkItemConcurrency.StudyUpdate, WorkItemStatusFilter.Active, studyLoaderArgs.StudyInstanceUid); var activeDeleteItems = context.GetWorkItemBroker().GetWorkItems(WorkItemConcurrency.StudyDelete, WorkItemStatusFilter.Active, studyLoaderArgs.StudyInstanceUid); if (activeUpdateItems.Any() || activeDeleteItems.Any()) { var message = string.Format("There are work items actively modifying the study with UID '{0}'.", studyLoaderArgs.StudyInstanceUid); throw new InUseLoadStudyException(studyLoaderArgs.StudyInstanceUid, message); } } IStudy study = context.GetStudyBroker().GetStudy(studyLoaderArgs.StudyInstanceUid); if (study == null) { result = EventResult.MajorFailure; loadedInstances.AddInstance(studyLoaderArgs.StudyInstanceUid); throw new NotFoundLoadStudyException(studyLoaderArgs.StudyInstanceUid); } loadedInstances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid); _sops = study.GetSopInstances().GetEnumerator(); return study.NumberOfStudyRelatedInstances; } } finally { AuditHelper.LogOpenStudies(new[] { AuditHelper.LocalAETitle }, loadedInstances, EventSource.CurrentUser, result); } }