Ejemplo n.º 1
0
        protected void LoadImportContext(ServerAssociationParameters association)
        {
            _importContext = new DicomReceiveImportContext(association.CallingAE, GetRemoteHostName(association), StudyStore.GetConfiguration(), EventSource.CurrentProcess);

            // Publish new WorkItems as they're added to the context
            lock (_importContext.StudyWorkItemsSyncLock)
            {
                _importContext.StudyWorkItems.ItemAdded += (sender, args) =>
                {
                    _importContext.PublishWorkItemActivity(WorkItemDataHelper.FromWorkItem(args.Item));

                    var auditedInstances = new AuditedInstances();
                    var request          = args.Item.Request as DicomReceiveRequest;
                    if (request != null)
                    {
                        auditedInstances.AddInstance(request.Patient.PatientId, request.Patient.PatientsName, request.Study.StudyInstanceUid);
                    }

                    AuditHelper.LogReceivedInstances(
                        association.CallingAE, GetRemoteHostName(association),
                        auditedInstances, EventSource.CurrentProcess,
                        EventResult.Success, EventReceiptAction.ActionUnknown);
                };

                _importContext.StudyWorkItems.ItemChanged += (sender, args) =>
                                                             _importContext.PublishWorkItemActivity(WorkItemDataHelper.FromWorkItem(args.Item));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Method for getting next <see cref="WorkItem"/> entry.
        /// </summary>
        /// <param name="count">The count.</param>
        /// <param name="priority">Search for stat items.</param>
        /// <remarks>
        /// </remarks>
        /// <returns>
        /// A <see cref="WorkItem"/> entry if found, or else null;
        /// </returns>
        private List <WorkItem> InternalGetWorkItems(int count, WorkItemPriorityEnum priority)
        {
            _nowRunningWorkItems.Clear();
            _postponedWorkItems.Clear();

            var itemsToPublish = new List <WorkItemData>();

            try
            {
                var             workItemBroker = _context.GetWorkItemBroker();
                List <WorkItem> workItems      = workItemBroker.GetWorkItemsForProcessing(count * 4, priority);
                foreach (var item in workItems)
                {
                    string reason;
                    if (CanStart(item, out reason))
                    {
                        item.Status = WorkItemStatusEnum.InProgress;
                        _nowRunningWorkItems.Add(item);
                    }
                    else
                    {
                        Postpone(item);
                        _postponedWorkItems.Add(item);
                        WorkItemProgress progress = item.Progress;
                        if (progress != null)
                        {
                            progress.StatusDetails = reason;
                            item.Progress          = progress;
                            itemsToPublish.Add(WorkItemDataHelper.FromWorkItem(item));
                        }
                    }

                    if (_nowRunningWorkItems.Count >= count)
                    {
                        break;
                    }
                }

                _context.Commit();

                return(new List <WorkItem>(_nowRunningWorkItems));
            }
            catch (Exception x)
            {
                Platform.Log(LogLevel.Warn, x, "Unexpected error querying for {0} {1} priority WorkItems", count, priority.GetDescription());
                return(null);
            }
            finally
            {
                if (itemsToPublish.Count > 0)
                {
                    WorkItemPublishSubscribeHelper.PublishWorkItemsChanged(WorkItemsChangedEventType.Update, itemsToPublish);
                }
            }
        }
Ejemplo n.º 3
0
        public WorkItemQueryResponse Query(WorkItemQueryRequest request)
        {
            var response = new WorkItemQueryResponse();

            using (var context = new DataAccessContext())
            {
                var broker = context.GetWorkItemBroker();

                var dbList = broker.GetWorkItems(request.Type, request.Status, request.StudyInstanceUid);

                var results = new List <WorkItemData>();

                foreach (var dbItem in dbList)
                {
                    results.Add(WorkItemDataHelper.FromWorkItem(dbItem));
                }

                response.Items = results.ToArray();
            }
            return(response);
        }
Ejemplo n.º 4
0
        private void Publish(bool saveToDatabase)
        {
            if (saveToDatabase)
            {
                try
                {
                    using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex))
                    {
                        var broker = context.GetWorkItemBroker();

                        Item = broker.GetWorkItem(Item.Oid);

                        Item.Progress = Progress;

                        context.Commit();
                    }
                }
                catch (Exception)
                {
                    // Saw ChangeCOnflictException here a few times
                }
            }
            else
            {
                Item.Progress = Progress;
            }

            WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, WorkItemDataHelper.FromWorkItem(Item));
        }
Ejemplo n.º 5
0
        private bool ImportFiles(IList <string> filePaths,
                                 IEnumerable <string> fileExtensions,
                                 bool recursive)
        {
            var configuration = GetServerConfiguration();

            var context = new ImportStudyContext(configuration.AETitle, StudyStore.GetConfiguration(), string.IsNullOrEmpty(Request.UserName) ? EventSource.CurrentProcess : EventSource.GetUserEventSource(Request.UserName));

            // Publish the creation of the StudyImport WorkItems
            lock (context.StudyWorkItemsSyncLock)
            {
                context.StudyWorkItems.ItemAdded += (sender, args) => Platform.GetService(
                    (IWorkItemActivityMonitorService service) =>
                    service.Publish(new WorkItemPublishRequest {
                    Item = WorkItemDataHelper.FromWorkItem(args.Item)
                }));
                context.StudyWorkItems.ItemChanged += (sender, args) => Platform.GetService(
                    (IWorkItemActivityMonitorService service) =>
                    service.Publish(new WorkItemPublishRequest {
                    Item = WorkItemDataHelper.FromWorkItem(args.Item)
                }));
            }

            var extensions = new List <string>();

            if (fileExtensions != null)
            {
                foreach (string extension in fileExtensions)
                {
                    if (String.IsNullOrEmpty(extension))
                    {
                        continue;
                    }

                    extensions.Add(extension);
                }
            }

            Progress.PathsToImport = filePaths.Count;

            bool completedEnumeration = true;

            foreach (string path in filePaths)
            {
                FileProcessor.Process(path, string.Empty,
                                      delegate(string file, out bool cancel)
                {
                    cancel = false;

                    if (CancelPending || StopPending || context.FatalError)
                    {
                        cancel = true;
                        return;
                    }

                    bool enqueue = false;
                    foreach (string extension in extensions)
                    {
                        if (file.EndsWith(extension))
                        {
                            enqueue = true;
                            break;
                        }
                    }

                    enqueue = enqueue || extensions.Count == 0;

                    if (enqueue)
                    {
                        ++Progress.TotalFilesToImport;

                        Proxy.UpdateProgress();

                        ImportFile(file, context);
                    }
                }, recursive);

                Progress.PathsImported++;
                Proxy.UpdateProgress();

                if (CancelPending || StopPending || context.FatalError)
                {
                    completedEnumeration = false;
                }
            }

            Progress.CompletedEnumeration = completedEnumeration;

            return(context.FatalError);
        }
Ejemplo n.º 6
0
        protected override void ProcessItem(Study study)
        {
            var result = EventResult.Success;

            try
            {
                WorkItem item;
                using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex))
                {
                    item = ProcessStudy(study.Oid, context);
                    context.Commit();
                }
                if (item != null)
                {
                    WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, WorkItemDataHelper.FromWorkItem(item));
                }
            }
            catch (Exception)
            {
                result = EventResult.MajorFailure;
                throw;
            }
            finally
            {
                var instances = new AuditedInstances();
                instances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid);

                AuditHelper.LogDeleteStudies(AuditHelper.LocalAETitle, instances, EventSource.CurrentUser, result);
            }
        }
Ejemplo n.º 7
0
        public override bool OnReceiveRequest(ClearCanvas.Dicom.Network.DicomServer server,
                                              ServerAssociationParameters association, byte presentationID, DicomMessage message)
        {
            string   studyInstanceUid;
            string   seriesInstanceUid;
            DicomUid sopInstanceUid;

            bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid);

            if (ok)
            {
                ok = message.DataSet[DicomTags.SeriesInstanceUid].TryGetString(0, out seriesInstanceUid);
            }
            if (ok)
            {
                ok = message.DataSet[DicomTags.StudyInstanceUid].TryGetString(0, out studyInstanceUid);
            }

            if (!ok)
            {
                Platform.Log(LogLevel.Error, "Unable to retrieve UIDs from request message, sending failure status.");

                server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID,
                                          DicomStatuses.ProcessingFailure);

                return(true);
            }

            if (_importContext == null)
            {
                _importContext = new DicomReceiveImportContext(association.CallingAE, GetRemoteHostName(association), StudyStore.GetConfiguration(), EventSource.CurrentProcess);

                // Publish new WorkItems as they're added to the context
                lock (_importContext.StudyWorkItemsSyncLock)
                {
                    _importContext.StudyWorkItems.ItemAdded += delegate(object sender, DictionaryEventArgs <string, WorkItem> args)
                    {
                        Platform.GetService(
                            (IWorkItemActivityMonitorService service) =>
                            service.Publish(new WorkItemPublishRequest
                        {
                            Item =
                                WorkItemDataHelper
                                .FromWorkItem(
                                    args.Item)
                        }));


                        var auditedInstances = new AuditedInstances();
                        var request          =
                            args.Item.Request as DicomReceiveRequest;
                        if (request != null)
                        {
                            auditedInstances.AddInstance(request.Patient.PatientId, request.Patient.PatientsName,
                                                         request.Study.StudyInstanceUid);
                        }

                        AuditHelper.LogReceivedInstances(
                            association.CallingAE, GetRemoteHostName(association),
                            auditedInstances, EventSource.CurrentProcess,
                            EventResult.Success, EventReceiptAction.ActionUnknown);
                    }
                    ;

                    _importContext.StudyWorkItems.ItemChanged += (sender, args) => Platform.GetService(
                        (IWorkItemActivityMonitorService service) =>
                        service.Publish(new WorkItemPublishRequest {
                        Item = WorkItemDataHelper.FromWorkItem(args.Item)
                    }));
                }
            }

            var importer = new ImportFilesUtility(_importContext);

            var result = importer.Import(message, BadFileBehaviourEnum.Ignore, FileImportBehaviourEnum.Save);

            if (result.Successful)
            {
                if (!String.IsNullOrEmpty(result.AccessionNumber))
                {
                    Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (A#:{3} StudyUid:{4})",
                                 result.SopInstanceUid, association.CallingAE, association.CalledAE, result.AccessionNumber,
                                 result.StudyInstanceUid);
                }
                else
                {
                    Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (StudyUid:{3})",
                                 result.SopInstanceUid, association.CallingAE, association.CalledAE,
                                 result.StudyInstanceUid);
                }
                server.SendCStoreResponse(presentationID, message.MessageId, message.AffectedSopInstanceUid, result.DicomStatus);
            }
            else
            {
                if (result.DicomStatus == DicomStatuses.ProcessingFailure)
                {
                    Platform.Log(LogLevel.Error, "Failure importing sop: {0}", result.ErrorMessage);
                }

                //OnReceiveError(message, result.ErrorMessage, association.CallingAE);
                server.SendCStoreResponse(presentationID, message.MessageId, message.AffectedSopInstanceUid,
                                          result.DicomStatus, result.ErrorMessage);
            }

            return(true);
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        public WorkItemUpdateResponse Update(WorkItemUpdateRequest request)
        {
            var response = new WorkItemUpdateResponse();

            using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex))
            {
                var broker   = context.GetWorkItemBroker();
                var workItem = broker.GetWorkItem(request.Identifier);
                if (workItem == null)
                {
                    response.Item = null;
                    return(response);
                }

                bool deleted = false;

                if (request.Delete.HasValue && request.Delete.Value)
                {
                    if (workItem.Status != WorkItemStatusEnum.InProgress)
                    {
                        workItem.Status = WorkItemStatusEnum.Deleted;
                        deleted         = true;

                        // If StudyDelete we're removing, "undelete" the study
                        CheckDeleteStudyCanceled(context, workItem);
                    }
                }
                if (!deleted)
                {
                    if (request.ExpirationTime.HasValue)
                    {
                        workItem.ExpirationTime = request.ExpirationTime.Value;
                    }
                    if (request.Priority.HasValue)
                    {
                        workItem.Priority = request.Priority.Value;
                    }
                    if (request.Status.HasValue && workItem.Status != WorkItemStatusEnum.InProgress)
                    {
                        workItem.Status = request.Status.Value;
                        if (request.Status.Value == WorkItemStatusEnum.Canceled)
                        {
                            workItem.DeleteTime = Platform.Time.AddMinutes(WorkItemServiceSettings.Default.DeleteDelayMinutes);
                        }
                        else if (request.Status.Value == WorkItemStatusEnum.Pending)
                        {
                            workItem.ScheduledTime = Platform.Time;
                            workItem.FailureCount  = 0;
                        }

                        // Cache the UserIdentityContext for later use by the shred
                        if (workItem.Request.WorkItemType.Equals(ImportFilesRequest.WorkItemTypeString) && request.Status.Value == WorkItemStatusEnum.Pending)
                        {
                            UserIdentityCache.Put(workItem.Oid, UserIdentityContext.CreateFromCurrentThreadPrincipal());
                        }
                    }
                    if (request.ProcessTime.HasValue)
                    {
                        workItem.ProcessTime = request.ProcessTime.Value;
                    }

                    if (request.Cancel.HasValue && request.Cancel.Value)
                    {
                        if (workItem.Progress == null || workItem.Progress.IsCancelable)
                        {
                            if (workItem.Status.Equals(WorkItemStatusEnum.Idle) ||
                                workItem.Status.Equals(WorkItemStatusEnum.Pending))
                            {
                                workItem.Status = WorkItemStatusEnum.Canceled;

                                // If StudyDelete we're removing, "undelete" the study
                                CheckDeleteStudyCanceled(context, workItem);
                            }
                            else if (workItem.Status.Equals(WorkItemStatusEnum.InProgress))
                            {
                                // Abort the WorkItem
                                WorkItemProcessor.Instance.Cancel(workItem.Oid);
                            }
                        }
                    }
                }

                context.Commit();

                response.Item = WorkItemDataHelper.FromWorkItem(workItem);
            }

            WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, response.Item);

            return(response);
        }