Esempio n. 1
0
        public IList <FilesystemQueue> GetFileSystemQueueItems(Study study)
        {
            Platform.CheckForNullReference(study, "Study");

            FileSystemQueueAdaptor        adaptor = new FileSystemQueueAdaptor();
            FilesystemQueueSelectCriteria fileSystemQueueCriteria = new FilesystemQueueSelectCriteria();

            fileSystemQueueCriteria.StudyStorageKey.EqualTo(study.StudyStorageKey);
            fileSystemQueueCriteria.ScheduledTime.SortAsc(0);
            return(adaptor.Get(fileSystemQueueCriteria));
        }
        protected override void OnExecute(CommandProcessor theProcessor, IUpdateContext updateContext)
        {
            var filesystemQueueBroker = updateContext.GetBroker <IFilesystemQueueEntityBroker>();
            var criteria = new FilesystemQueueSelectCriteria();

            criteria.StudyStorageKey.EqualTo(_storageLocationKey);
            IList <FilesystemQueue> filesystemQueueItems = filesystemQueueBroker.Find(criteria);

            var workQueueBroker   = updateContext.GetBroker <IWorkQueueEntityBroker>();
            var workQueueCriteria = new WorkQueueSelectCriteria();

            workQueueCriteria.StudyStorageKey.EqualTo(_storageLocationKey);
            workQueueCriteria.WorkQueueTypeEnum.In(new[] { WorkQueueTypeEnum.PurgeStudy, WorkQueueTypeEnum.DeleteStudy, WorkQueueTypeEnum.CompressStudy, WorkQueueTypeEnum.MigrateStudy });
            IList <WorkQueue> workQueueItems = workQueueBroker.Find(workQueueCriteria);

            foreach (FilesystemQueue queue in filesystemQueueItems)
            {
                bool delete = false;
                if (_applyTime.Equals(ServerRuleApplyTimeEnum.StudyArchived))
                {
                    if (queue.FilesystemQueueTypeEnum.Equals(FilesystemQueueTypeEnum.PurgeStudy))
                    {
                        delete = true;
                    }
                }
                else
                {
                    delete = true;
                }

                if (delete)
                {
                    if (!filesystemQueueBroker.Delete(queue.GetKey()))
                    {
                        throw new ApplicationException("Unable to delete items in the filesystem queue");
                    }
                }
            }

            if (!_applyTime.Equals(ServerRuleApplyTimeEnum.StudyArchived))
            {
                // delete work queue
                foreach (Model.WorkQueue item in workQueueItems)
                {
                    if (!item.Delete(updateContext))
                    {
                        throw new ApplicationException("Unable to delete items in the work queue");
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Log FilesystemQueue related entries.
        /// </summary>
        public void LogFilesystemQueue()
        {
            var criteria = new FilesystemQueueSelectCriteria();

            criteria.StudyStorageKey.EqualTo(Key);

            using (var context = new ServerExecutionContext())
            {
                var broker = context.ReadContext.GetBroker <IFilesystemQueueEntityBroker>();

                IList <FilesystemQueue> list = broker.Find(criteria);
                foreach (FilesystemQueue queueItem in list)
                {
                    if (queueItem.FilesystemQueueTypeEnum.Equals(FilesystemQueueTypeEnum.LosslessCompress) ||
                        queueItem.FilesystemQueueTypeEnum.Equals(FilesystemQueueTypeEnum.LossyCompress))
                    {
                        XmlElement element = queueItem.QueueXml.DocumentElement;

                        string syntax = element.Attributes["syntax"].Value;

                        TransferSyntax compressSyntax = TransferSyntax.GetTransferSyntax(syntax);
                        if (compressSyntax != null)
                        {
                            Platform.Log(LogLevel.Info, "{0}: Study {1} on partition {2} scheduled for {3} compression at {4}",
                                         queueItem.FilesystemQueueTypeEnum.Description, StudyInstanceUid, ServerPartition.AeTitle,
                                         compressSyntax.Name, queueItem.ScheduledTime);
                        }
                        else
                        {
                            Platform.Log(LogLevel.Info, "{0}: Study {1} on partition {2} scheduled for {3} compression at {4}",
                                         queueItem.FilesystemQueueTypeEnum.Description, StudyInstanceUid, ServerPartition.AeTitle,
                                         syntax, queueItem.ScheduledTime);
                        }
                    }
                    else
                    {
                        Platform.Log(LogLevel.Info, "{0}: Study {1} on partition {2} scheduled for {3}",
                                     queueItem.FilesystemQueueTypeEnum.Description, StudyInstanceUid, ServerPartition.AeTitle,
                                     queueItem.ScheduledTime);
                    }
                }
            }
        }
        protected override void OnExecute(CommandProcessor theProcessor, IUpdateContext updateContext)
        {
            // update FilesystemStudyStorage
            if (Context != null)
            {
                Platform.Log(LogLevel.Info, "Updating database...");
                IFilesystemStudyStorageEntityBroker broker = updateContext.GetBroker <IFilesystemStudyStorageEntityBroker>();

                FilesystemStudyStorageSelectCriteria searchCriteria = new FilesystemStudyStorageSelectCriteria();
                searchCriteria.StudyStorageKey.EqualTo(Context.OriginalStudyLocation.GetKey());
                searchCriteria.FilesystemKey.EqualTo(Context.OriginalStudyLocation.FilesystemKey);
                FilesystemStudyStorage filesystemStudyStorage = broker.FindOne(searchCriteria);
                Debug.Assert(filesystemStudyStorage != null);

                // Update Filesystem for the StudyStorage entry
                filesystemStudyStorage.FilesystemKey = Context.Destination.Filesystem.GetKey();
                broker.Update(filesystemStudyStorage);


                // Update Filesystem for the remaining FilesystemQueue entries
                IFilesystemQueueEntityBroker  fsQueueBroker         = updateContext.GetBroker <IFilesystemQueueEntityBroker>();
                FilesystemQueueSelectCriteria fsQueueSearchCriteria = new FilesystemQueueSelectCriteria();
                fsQueueSearchCriteria.StudyStorageKey.EqualTo(Context.OriginalStudyLocation.GetKey());
                fsQueueSearchCriteria.FilesystemKey.EqualTo(Context.OriginalStudyLocation.FilesystemKey);

                FilesystemQueueUpdateColumns fsQueueUpdateColumns = new FilesystemQueueUpdateColumns();
                fsQueueUpdateColumns.FilesystemKey = Context.Destination.Filesystem.GetKey();
                fsQueueBroker.Update(fsQueueSearchCriteria, fsQueueUpdateColumns);

                // Insert or update Filesystem Queue table.
                IInsertFilesystemQueue          insertFilesystemQueueBroker = updateContext.GetBroker <IInsertFilesystemQueue>();
                FilesystemQueueInsertParameters parms = new FilesystemQueueInsertParameters();
                parms.FilesystemKey           = Context.Destination.Filesystem.GetKey();
                parms.FilesystemQueueTypeEnum = FilesystemQueueTypeEnum.TierMigrate;
                parms.ScheduledTime           = Platform.Time;
                parms.StudyStorageKey         = Context.OriginalStudyLocation.GetKey();
                insertFilesystemQueueBroker.Execute(parms);

                Platform.Log(LogLevel.Info, "Database is updated.");
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Get a list of candidates from the <see cref="FilesystemQueue"/>.
        /// </summary>
        /// <param name="item">The ServiceLock item.</param>
        /// <param name="scheduledTime">The scheduled time to query against</param>
        /// <param name="type">The type of FilesystemQueue entry.</param>
        /// <param name="statusCheck">If true, check for specific status value WorkQueue entries already existing, otherwise check for any WorkQueue entry.</param>
        /// <returns>The list of queue entries.</returns>
        protected IList <FilesystemQueue> GetFilesystemQueueCandidates(Model.ServiceLock item, DateTime scheduledTime, FilesystemQueueTypeEnum type, bool statusCheck)
        {
            using (ServerExecutionContext context = new ServerExecutionContext())
            {
                IFilesystemQueueEntityBroker  broker          = context.ReadContext.GetBroker <IFilesystemQueueEntityBroker>();
                FilesystemQueueSelectCriteria fsQueueCriteria = new FilesystemQueueSelectCriteria();

                fsQueueCriteria.FilesystemKey.EqualTo(item.FilesystemKey);
                fsQueueCriteria.ScheduledTime.LessThanOrEqualTo(scheduledTime);
                fsQueueCriteria.FilesystemQueueTypeEnum.EqualTo(type);

                // Do the select based on the QueueStudyState (used to be based on a link to the WorkQueue table)
                StudyStorageSelectCriteria studyStorageSearchCriteria = new StudyStorageSelectCriteria();
                studyStorageSearchCriteria.QueueStudyStateEnum.EqualTo(QueueStudyStateEnum.Idle);
                fsQueueCriteria.StudyStorage.Exists(studyStorageSearchCriteria);

                fsQueueCriteria.ScheduledTime.SortAsc(0);

                IList <FilesystemQueue> list = broker.Find(fsQueueCriteria, 0, ServiceLockSettings.Default.FilesystemQueueResultCount);

                return(list);
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Reprocess a specific study.
        /// </summary>
        /// <param name="partition">The ServerPartition the study is on.</param>
        /// <param name="location">The storage location of the study to process.</param>
        /// <param name="engine">The rules engine to use when processing the study.</param>
        /// <param name="postArchivalEngine">The rules engine used for studies that have been archived.</param>
        /// <param name="dataAccessEngine">The rules engine strictly used for setting data acess.</param>
        protected static void ProcessStudy(ServerPartition partition, StudyStorageLocation location, ServerRulesEngine engine, ServerRulesEngine postArchivalEngine, ServerRulesEngine dataAccessEngine)
        {
            if (!location.QueueStudyStateEnum.Equals(QueueStudyStateEnum.Idle) || !location.AcquireWriteLock())
            {
                Platform.Log(LogLevel.Error, "Unable to lock study {0}. The study is being processed. (Queue State: {1})", location.StudyInstanceUid, location.QueueStudyStateEnum.Description);
            }
            else
            {
                try
                {
                    DicomFile msg = LoadInstance(location);
                    if (msg == null)
                    {
                        Platform.Log(LogLevel.Error, "Unable to load file for study {0}", location.StudyInstanceUid);
                        return;
                    }

                    bool archiveQueueExists;
                    bool archiveStudyStorageExists;
                    bool filesystemDeleteExists;
                    using (IReadContext read = PersistentStoreRegistry.GetDefaultStore().OpenReadContext())
                    {
                        // Check for existing archive queue entries
                        var archiveQueueBroker   = read.GetBroker <IArchiveQueueEntityBroker>();
                        var archiveQueueCriteria = new ArchiveQueueSelectCriteria();
                        archiveQueueCriteria.StudyStorageKey.EqualTo(location.Key);
                        archiveQueueExists = archiveQueueBroker.Count(archiveQueueCriteria) > 0;


                        var archiveStorageBroker        = read.GetBroker <IArchiveStudyStorageEntityBroker>();
                        var archiveStudyStorageCriteria = new ArchiveStudyStorageSelectCriteria();
                        archiveStudyStorageCriteria.StudyStorageKey.EqualTo(location.Key);
                        archiveStudyStorageExists = archiveStorageBroker.Count(archiveStudyStorageCriteria) > 0;

                        var filesystemQueueBroker   = read.GetBroker <IFilesystemQueueEntityBroker>();
                        var filesystemQueueCriteria = new FilesystemQueueSelectCriteria();
                        filesystemQueueCriteria.StudyStorageKey.EqualTo(location.Key);
                        filesystemQueueCriteria.FilesystemQueueTypeEnum.EqualTo(FilesystemQueueTypeEnum.DeleteStudy);
                        filesystemDeleteExists = filesystemQueueBroker.Count(filesystemQueueCriteria) > 0;
                    }

                    using (var commandProcessor = new ServerCommandProcessor("Study Rule Processor")
                    {
                        PrimaryServerPartitionKey = partition.GetKey(),
                        PrimaryStudyKey = location.Study.GetKey()
                    })
                    {
                        var context = new ServerActionContext(msg, location.FilesystemKey, partition, location.Key, commandProcessor);

                        // Check if the Study has been archived
                        if (archiveStudyStorageExists && !archiveQueueExists && !filesystemDeleteExists)
                        {
                            // Add a command to delete the current filesystemQueue entries, so that they can
                            // be reinserted by the rules engine.
                            context.CommandProcessor.AddCommand(new DeleteFilesystemQueueCommand(location.Key, ServerRuleApplyTimeEnum.StudyArchived));

                            // How to deal with exiting FilesystemQueue entries is problematic here.  If the study
                            // has been migrated off tier 1, we probably don't want to modify the tier migration
                            // entries.  Compression entries may have been entered when the Study was initially
                            // processed, we don't want to delete them, because they might still be valid.
                            // We just re-run the rules engine at this point, and delete only the StudyPurge entries,
                            // since those we know at least would only be applied for archived studies.
                            var studyRulesEngine = new StudyRulesEngine(postArchivalEngine, location, location.ServerPartition, location.LoadStudyXml());
                            studyRulesEngine.Apply(ServerRuleApplyTimeEnum.StudyArchived, commandProcessor);

                            // Post Archive doesn't allow data access rules.  Force Data Access rules to be reapplied
                            // to these studies also.
                            dataAccessEngine.Execute(context);
                        }
                        else
                        {
                            // Add a command to delete the current filesystemQueue entries, so that they can
                            // be reinserted by the rules engine.
                            context.CommandProcessor.AddCommand(new DeleteFilesystemQueueCommand(location.Key, ServerRuleApplyTimeEnum.StudyProcessed));

                            // Execute the rules engine, insert commands to update the database into the command processor.
                            // Due to ticket #11673, we create a new rules engine instance for each study, since the Study QC rules
                            // don't work right now with a single rules engine.
                            //TODO CR (Jan 2014) - Check if we can go back to caching the rules engine to reduce database hits on the rules
                            var studyRulesEngine = new StudyRulesEngine(location, location.ServerPartition, location.LoadStudyXml());
                            studyRulesEngine.Apply(ServerRuleApplyTimeEnum.StudyProcessed, commandProcessor);
                        }

                        // Do the actual database updates.
                        if (false == context.CommandProcessor.Execute())
                        {
                            Platform.Log(LogLevel.Error, "Unexpected failure processing Study level rules for study {0}", location.StudyInstanceUid);
                        }

                        // Log the FilesystemQueue related entries
                        location.LogFilesystemQueue();
                    }
                }
                finally
                {
                    location.ReleaseWriteLock();
                }
            }
        }