private static void UpdateFilesystemKey(Model.ServiceLock item)
        {
            IPersistentStore store = PersistentStoreRegistry.GetDefaultStore();

            using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                ServiceLockUpdateColumns columns = new ServiceLockUpdateColumns();
                columns.FilesystemKey = item.FilesystemKey;

                IServiceLockEntityBroker broker = ctx.GetBroker <IServiceLockEntityBroker>();
                broker.Update(item.Key, columns);
                ctx.Commit();
            }
        }
Example #2
0
		public void EventHandler(object sender, StudyEditedEventArgs e)
		{
			IPersistentStore store = PersistentStoreRegistry.GetDefaultStore();
			using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
			{
				Platform.Log(LogLevel.Info, "Logging study history record...");
				IStudyHistoryEntityBroker broker = ctx.GetBroker<IStudyHistoryEntityBroker>();
				StudyHistoryUpdateColumns recordColumns = CreateStudyHistoryRecord(e);
				StudyHistory entry = broker.Insert(recordColumns);
				if (entry != null)
					ctx.Commit();
				else
					throw new ApplicationException("Unable to log study history record");
			}
		}
Example #3
0
        private void Apply_Click(object sender, EventArgs e)
        {
            var view = dataGridView1.SelectedRows[0].DataBoundItem as DataRowView;

            if (view != null)
            {
                var guid = (Guid)view.Row["GUID"];

                IPersistentStore store = PersistentStoreRegistry.GetDefaultStore();

                using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
                {
                    var         studyBroker = ctx.GetBroker <IStudyEntityBroker>();
                    var         key         = new ServerEntityKey("Study", guid);
                    Model.Study study       = studyBroker.Load(key);

                    var storageBroker = ctx.GetBroker <IStudyStorageEntityBroker>();
                    var parms         = new StudyStorageSelectCriteria();
                    parms.ServerPartitionKey.EqualTo(study.ServerPartitionKey);
                    parms.StudyInstanceUid.EqualTo(study.StudyInstanceUid);

                    Model.StudyStorage storage = storageBroker.Find(parms)[0];


                    var workQueueBroker = ctx.GetBroker <IWorkQueueEntityBroker>();
                    var columns         = new WorkQueueUpdateColumns
                    {
                        ServerPartitionKey    = study.ServerPartitionKey,
                        StudyStorageKey       = storage.GetKey(),
                        ExpirationTime        = DateTime.Now.AddHours(1),
                        ScheduledTime         = DateTime.Now,
                        InsertTime            = DateTime.Now,
                        WorkQueuePriorityEnum = Model.WorkQueuePriorityEnum.Medium,
                        WorkQueueStatusEnum   = Model.WorkQueueStatusEnum.Pending,
                        WorkQueueTypeEnum     = Model.WorkQueueTypeEnum.WebEditStudy
                    };

                    var doc = new XmlDocument();
                    doc.Load(new StringReader(textBox1.Text));

                    columns.Data = doc;

                    workQueueBroker.Insert(columns);

                    ctx.Commit();
                }
            }
        }
Example #4
0
        /// <summary>
        /// Creates a Study Reprocess entry and locks the study in <see cref="QueueStudyStateEnum.ReprocessScheduled"/> state.
        /// </summary>
        /// <param name="reason"></param>
        /// <param name="location"></param>
        /// <param name="scheduleTime"></param>
        /// <returns></returns>
        /// <exception cref="InvalidStudyStateOperationException">Study is in a state that reprocessing is not allowed</exception>
        public WorkQueue ReprocessStudy(String reason, StudyStorageLocation location, DateTime scheduleTime)
        {
            Platform.CheckForNullReference(location, "location");

            IPersistentStore store = PersistentStoreRegistry.GetDefaultStore();

            using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                WorkQueue reprocessEntry = ReprocessStudy(ctx, reason, location, scheduleTime);
                if (reprocessEntry != null)
                {
                    ctx.Commit();
                }

                return(reprocessEntry);
            }
        }
        public bool ResetArchiveQueueItem(IList <ArchiveQueue> items, DateTime time)
        {
            if (items == null || items.Count == 0)
            {
                return(false);
            }

            ArchiveQueueUpdateColumns columns = new ArchiveQueueUpdateColumns();

            columns.ArchiveQueueStatusEnum = ArchiveQueueStatusEnum.Pending;
            columns.ProcessorId            = "";
            columns.ScheduledTime          = time;

            bool             result = true;
            IPersistentStore store  = PersistentStoreRegistry.GetDefaultStore();

            using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                IArchiveQueueEntityBroker archiveQueueBroker = ctx.GetBroker <IArchiveQueueEntityBroker>();

                foreach (ArchiveQueue item in items)
                {
                    // Only do an update if its a failed status currently
                    ArchiveQueueSelectCriteria criteria = new ArchiveQueueSelectCriteria();
                    criteria.ArchiveQueueStatusEnum.EqualTo(ArchiveQueueStatusEnum.Failed);
                    criteria.StudyStorageKey.EqualTo(item.StudyStorageKey);

                    if (!archiveQueueBroker.Update(criteria, columns))
                    {
                        result = false;
                        break;
                    }
                }

                if (result)
                {
                    ctx.Commit();
                }
            }

            return(result);
        }
        private void LogHistory(ImageSetDetails details)
        {
            IPersistentStore store = PersistentStoreRegistry.GetDefaultStore();

            using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                Platform.Log(LogLevel.Info, "Logging study history record...");
                IStudyHistoryEntityBroker broker        = ctx.GetBroker <IStudyHistoryEntityBroker>();
                StudyHistoryUpdateColumns recordColumns = CreateStudyHistoryRecord(details);
                StudyHistory entry = broker.Insert(recordColumns);
                if (entry != null)
                {
                    ctx.Commit();
                }
                else
                {
                    throw new ApplicationException("Unable to log study history record");
                }
            }

            HistoryLogged = true;
        }
        /// <summary>
        /// Reschedule a list of <see cref="WorkQueue"/> items
        /// </summary>
        /// <param name="items">List of <see cref="WorkQueue"/> items to be rescheduled</param>
        /// <param name="newScheduledTime">New schedule start date/time</param>
        /// <param name="expirationTime">New expiration date/time</param>
        /// <param name="priority">New priority</param>
        /// <returns>A value indicating whether all <see cref="WorkQueue"/> items in <paramref name="items"/> are updated successfully.</returns>
        /// <remarks>
        /// If one or more <see cref="WorkQueue"/> in <paramref name="items"/> cannot be rescheduled, all changes will be
        /// reverted and <b>false</b> will be returned.
        /// </remarks>
        public bool RescheduleWorkQueueItems(IList <WorkQueue> items, DateTime newScheduledTime, DateTime expirationTime, WorkQueuePriorityEnum priority)
        {
            if (items == null || items.Count == 0)
            {
                return(false);
            }

            WorkQueueUpdateColumns updatedColumns = new WorkQueueUpdateColumns();

            updatedColumns.WorkQueuePriorityEnum = priority;
            updatedColumns.ScheduledTime         = newScheduledTime;
            updatedColumns.ExpirationTime        = expirationTime;
            updatedColumns.FailureCount          = 0;
            updatedColumns.FailureDescription    = String.Empty;
            updatedColumns.LastUpdatedTime       = Platform.Time;

            bool             result = false;
            IPersistentStore store  = PersistentStoreRegistry.GetDefaultStore();

            using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                IWorkQueueEntityBroker workQueueBroker = ctx.GetBroker <IWorkQueueEntityBroker>();
                foreach (WorkQueue item in items)
                {
                    result = workQueueBroker.Update(item.Key, updatedColumns);
                    if (!result)
                    {
                        break;
                    }
                }
                if (result)
                {
                    ctx.Commit();
                }
            }

            return(result);
        }
        /// <summary>
        /// Deletes a list of <see cref="WorkQueue"/> items from the system.
        /// </summary>
        /// <param name="items">The list of <see cref="WorkQueue"/> items to be deleted</param>
        /// <returns>A value indicating whether all items have been successfully deleted.</returns>
        ///
        /// <remarks>
        /// If one or more <see cref="WorkQueue"/> in <paramref name="items"/> cannot be deleted, the method will return <b>false</b>
        /// and the deletion will be undone (i.e., All of the <see cref="WorkQueue"/> items will remain in the database)
        /// </remarks>
        public bool DeleteWorkQueueItems(IList <WorkQueue> items)
        {
            if (items == null || items.Count == 0)
            {
                return(false);
            }

            bool result = true;

            IPersistentStore store = PersistentStoreRegistry.GetDefaultStore();

            using (IUpdateContext uctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                IDeleteWorkQueue delete = uctx.GetBroker <IDeleteWorkQueue>();

                foreach (WorkQueue item in items)
                {
                    WorkQueueDeleteParameters parms = new WorkQueueDeleteParameters();
                    parms.ServerPartitionKey = item.ServerPartitionKey;
                    parms.StudyStorageKey    = item.StudyStorageKey;
                    parms.WorkQueueKey       = item.Key;
                    parms.WorkQueueTypeEnum  = item.WorkQueueTypeEnum;
                    // NOTE: QueueStudyState is reset by the stored procedure
                    if (!delete.Execute(parms))
                    {
                        Platform.Log(LogLevel.Error, "Unexpected error trying to delete WorkQueue entry");
                        result = false;
                    }
                }

                if (result)
                {
                    uctx.Commit();
                }
            }

            return(result);
        }
Example #9
0
        private static void WriteToDatabase(ImageServer.Common.Alert alert)
        {
            XmlDocument doc = CreateXmlContent(alert);

            AlertUpdateColumns columns = new AlertUpdateColumns();

            columns.AlertCategoryEnum = AlertCategoryEnum.GetEnum(alert.Category.ToString());
            columns.AlertLevelEnum    = AlertLevelEnum.GetEnum(alert.Level.ToString());
            columns.Component         = alert.Source.Name;
            columns.Content           = doc;
            columns.InsertTime        = Platform.Time;
            columns.Source            = alert.Source.Host;
            columns.TypeCode          = alert.Code;

            IPersistentStore store = PersistentStoreRegistry.GetDefaultStore();

            using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                IAlertEntityBroker alertBroker = ctx.GetBroker <IAlertEntityBroker>();
                alertBroker.Insert(columns);
                ctx.Commit();
            }
        }
        public bool ReprocessWorkQueueItem(WorkQueue item)
        {
            // #10620: Get a list of remaining WorkQueueUids which need to be reprocess
            // Note: currently only WorkQueueUIDs in failed StudyProcess will be reprocessed
            var remainingWorkQueueUidPaths = item.GetAllWorkQueueUidPaths();

            IPersistentStore store = PersistentStoreRegistry.GetDefaultStore();

            using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                // delete current workqueue
                IWorkQueueUidEntityBroker  uidBroker = ctx.GetBroker <IWorkQueueUidEntityBroker>();
                WorkQueueUidSelectCriteria criteria  = new WorkQueueUidSelectCriteria();
                criteria.WorkQueueKey.EqualTo(item.GetKey());

                if (uidBroker.Delete(criteria) >= 0)
                {
                    IWorkQueueEntityBroker workQueueBroker = ctx.GetBroker <IWorkQueueEntityBroker>();
                    if (workQueueBroker.Delete(item.GetKey()))
                    {
                        IList <StudyStorageLocation> locations = item.LoadStudyLocations(ctx);
                        if (locations != null && locations.Count > 0)
                        {
                            StudyReprocessor reprocessor    = new StudyReprocessor();
                            String           reason         = String.Format("User reprocesses failed {0}", item.WorkQueueTypeEnum);
                            WorkQueue        reprocessEntry = reprocessor.ReprocessStudy(ctx, reason, locations[0], remainingWorkQueueUidPaths, Platform.Time);
                            if (reprocessEntry != null)
                            {
                                ctx.Commit();
                            }
                            return(reprocessEntry != null);
                        }
                    }
                }
            }
            return(false);
        }
        /// <summary>
        /// The processing thread.
        /// </summary>
        /// <remarks>
        /// This method queries the database for ServiceLock entries to work on, and then uses
        /// a thread pool to process the entries.
        /// </remarks>
        public void Run()
        {
            // Start the thread pool
            if (!_threadPool.Active)
            {
                _threadPool.Start();
            }

            // Reset any queue items related to this service that are have the Lock bit set.
            try
            {
                ResetLocked();
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Fatal, e,
                             "Unable to reset ServiceLock items on startup.  There may be ServiceLock items orphaned in the queue.");
            }

            Platform.Log(LogLevel.Info, "ServiceLock Processor is running");
            while (true)
            {
                try
                {
                    if (_threadPool.CanQueueItem)
                    {
                        Model.ServiceLock queueListItem;

                        using (IUpdateContext updateContext = _store.OpenUpdateContext(UpdateContextSyncMode.Flush))
                        {
                            IQueryServiceLock          select = updateContext.GetBroker <IQueryServiceLock>();
                            ServiceLockQueryParameters parms  = new ServiceLockQueryParameters();
                            parms.ProcessorId = ServerPlatform.ProcessorId;

                            queueListItem = select.FindOne(parms);
                            updateContext.Commit();
                        }

                        if (queueListItem == null)
                        {
                            WaitHandle.WaitAny(new WaitHandle[] { _terminationEvent, _threadStop }, TimeSpan.FromSeconds(30), false);
                            _threadStop.Reset();
                        }
                        else
                        {
                            if (!_extensions.ContainsKey(queueListItem.ServiceLockTypeEnum))
                            {
                                Platform.Log(LogLevel.Error,
                                             "No extensions loaded for ServiceLockTypeEnum item type: {0}.  Failing item.",
                                             queueListItem.ServiceLockTypeEnum);

                                //Just fail the ServiceLock item, not much else we can do
                                ResetServiceLock(queueListItem);
                                continue;
                            }

                            IServiceLockProcessorFactory factory = _extensions[queueListItem.ServiceLockTypeEnum];

                            IServiceLockItemProcessor processor;
                            try
                            {
                                processor = factory.GetItemProcessor();
                            }
                            catch (Exception e)
                            {
                                Platform.Log(LogLevel.Error, e, "Unexpected exception creating ServiceLock processor.");
                                ResetServiceLock(queueListItem);
                                continue;
                            }

                            _threadPool.Enqueue(processor, queueListItem, delegate(IServiceLockItemProcessor queueProcessor, Model.ServiceLock queueItem)
                            {
                                try
                                {
                                    queueProcessor.Process(queueItem);
                                }
                                catch (Exception e)
                                {
                                    Platform.Log(LogLevel.Error, e,
                                                 "Unexpected exception when processing ServiceLock item of type {0}.  Failing Queue item. (GUID: {1})",
                                                 queueItem.ServiceLockTypeEnum,
                                                 queueItem.GetKey());

                                    ServerPlatform.Alert(AlertCategory.Application, AlertLevel.Error, "ServiceLockProcessor",
                                                         AlertTypeCodes.UnableToProcess,
                                                         null, TimeSpan.Zero,
                                                         "Exception thrown when processing {0} ServiceLock item : {1}",
                                                         queueItem.ServiceLockTypeEnum.Description, e.Message);
                                    ResetServiceLock(queueItem);
                                }

                                // Cleanup the processor
                                queueProcessor.Dispose();

                                // Signal the thread to come out of sleep mode
                                _threadStop.Set();
                            });
                        }
                    }
                    else
                    {
                        // Wait for only 5 seconds when the thread pool is all in use.
                        WaitHandle.WaitAny(new WaitHandle[] { _terminationEvent, _threadStop }, TimeSpan.FromSeconds(5), false);
                        _threadStop.Reset();
                    }
                }
                catch (Exception ex)
                {
                    Platform.Log(LogLevel.Error, ex, "Exception has occurred : {0}. Retry later.", ex.Message);
                    WaitHandle.WaitAny(new WaitHandle[] { _terminationEvent, _threadStop }, TimeSpan.FromSeconds(5), false);
                    _threadStop.Reset();
                }

                if (_stop)
                {
                    return;
                }
            }
        }
Example #12
0
        /// <summary>
        /// Updates the 'State' of the filesystem associated with the 'FilesystemDelete' <see cref="ServiceLock"/> item
        /// </summary>
        /// <param name="item"></param>
        /// <param name="fs"></param>
        private static void UpdateState(Model.ServiceLock item, ServerFilesystemInfo fs)
        {
            FilesystemState state = null;

            if (item.State != null && item.State.DocumentElement != null)
            {
                //load from datatabase
                state = XmlUtils.Deserialize <FilesystemState>(item.State.DocumentElement);
            }

            if (state == null)
            {
                state = new FilesystemState();
            }

            if (fs.AboveHighWatermark)
            {
                // we don't want to generate alert if the filesystem is offline or not accessible.
                if (fs.Online && (fs.Readable || fs.Writeable))
                {
                    TimeSpan ALERT_INTERVAL = TimeSpan.FromMinutes(ServiceLockSettings.Default.HighWatermarkAlertInterval);

                    if (state.AboveHighWatermarkTimestamp == null)
                    {
                        state.AboveHighWatermarkTimestamp = Platform.Time;
                    }

                    TimeSpan elapse = (state.LastHighWatermarkAlertTimestamp != null) ? Platform.Time - state.LastHighWatermarkAlertTimestamp.Value : Platform.Time - state.AboveHighWatermarkTimestamp.Value;

                    if (elapse.Duration() >= ALERT_INTERVAL)
                    {
                        ServerPlatform.Alert(AlertCategory.System, AlertLevel.Warning, "Filesystem",
                                             AlertTypeCodes.LowResources, null, TimeSpan.Zero,
                                             SR.AlertFilesystemAboveHW,
                                             fs.Filesystem.Description,
                                             TimeSpanFormatter.Format(Platform.Time - state.AboveHighWatermarkTimestamp.Value, true));


                        state.LastHighWatermarkAlertTimestamp = Platform.Time;
                    }
                }
                else
                {
                    state.AboveHighWatermarkTimestamp     = null;
                    state.LastHighWatermarkAlertTimestamp = null;
                }
            }
            else
            {
                state.AboveHighWatermarkTimestamp     = null;
                state.LastHighWatermarkAlertTimestamp = null;
            }


            XmlDocument stateXml = new XmlDocument();

            stateXml.AppendChild(stateXml.ImportNode(XmlUtils.Serialize(state), true));

            IPersistentStore store = PersistentStoreRegistry.GetDefaultStore();

            using (IUpdateContext ctx = store.OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                ServiceLockUpdateColumns columns = new ServiceLockUpdateColumns();
                columns.State = stateXml;

                IServiceLockEntityBroker broker = ctx.GetBroker <IServiceLockEntityBroker>();
                broker.Update(item.GetKey(), columns);
                ctx.Commit();
            }
        }
Example #13
0
        /// <summary>
        /// Simple routine for failing a work queue item.
        /// </summary>
        /// <param name="item">The item to fail.</param>
        /// <param name="failureDescription">The reason for the failure.</param>
        private void FailQueueItem(Model.WorkQueue item, string failureDescription)
        {
            // Must retry to reset the status of the entry in case of db error
            // Failure to do so will create stale work queue entry (stuck in "In Progress" state)
            // which can only be recovered by restarting the service.
            while (true)
            {
                try
                {
                    WorkQueueTypeProperties prop = _propertiesDictionary[item.WorkQueueTypeEnum];
                    using (IUpdateContext updateContext = _store.OpenUpdateContext(UpdateContextSyncMode.Flush))
                    {
                        IUpdateWorkQueue          update = updateContext.GetBroker <IUpdateWorkQueue>();
                        UpdateWorkQueueParameters parms  = new UpdateWorkQueueParameters
                        {
                            ProcessorID        = ServerPlatform.ProcessorId,
                            WorkQueueKey       = item.GetKey(),
                            StudyStorageKey    = item.StudyStorageKey,
                            FailureCount       = item.FailureCount + 1,
                            FailureDescription = failureDescription
                        };

                        var settings = WorkQueueSettings.Instance;
                        if ((item.FailureCount + 1) > prop.MaxFailureCount)
                        {
                            Platform.Log(LogLevel.Error,
                                         "Failing {0} WorkQueue entry ({1}), reached max retry count of {2}. Failure Reason: {3}",
                                         item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1, failureDescription);
                            parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Failed;
                            parms.ScheduledTime       = Platform.Time;
                            parms.ExpirationTime      = Platform.Time.AddDays(1);

                            OnWorkQueueEntryFailed(item, failureDescription);
                        }
                        else
                        {
                            Platform.Log(LogLevel.Error,
                                         "Resetting {0} WorkQueue entry ({1}) to Pending, current retry count {2}. Failure Reason: {3}",
                                         item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1, failureDescription);
                            parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Pending;
                            parms.ScheduledTime       = Platform.Time.AddMilliseconds(settings.WorkQueueQueryDelay);
                            parms.ExpirationTime      =
                                Platform.Time.AddSeconds((prop.MaxFailureCount - item.FailureCount) *
                                                         prop.FailureDelaySeconds);
                        }

                        if (false == update.Execute(parms))
                        {
                            Platform.Log(LogLevel.Error, "Unable to update {0} WorkQueue GUID: {1}", item.WorkQueueTypeEnum,
                                         item.GetKey().ToString());
                        }
                        else
                        {
                            updateContext.Commit();
                            break; // done
                        }
                    }
                }
                catch (Exception ex)
                {
                    Platform.Log(LogLevel.Error, "Error occurred when calling FailQueueItem. Retry later. {0}", ex.Message);
                    _terminateEvent.WaitOne(2000, false);
                    if (_stop)
                    {
                        Platform.Log(LogLevel.Warn, "Service is stopping. Retry to fail the entry is terminated.");
                        break;
                    }
                }
            }
        }
Example #14
0
        private void ReinventoryFilesystem(Filesystem filesystem)
        {
            ServerPartition partition;

            DirectoryInfo filesystemDir = new DirectoryInfo(filesystem.FilesystemPath);

            foreach (DirectoryInfo partitionDir in filesystemDir.GetDirectories())
            {
                if (GetServerPartition(partitionDir.Name, out partition) == false)
                {
                    continue;
                }

                foreach (DirectoryInfo dateDir in partitionDir.GetDirectories())
                {
                    if (dateDir.FullName.EndsWith("Deleted", StringComparison.InvariantCultureIgnoreCase) ||
                        dateDir.FullName.EndsWith(ServerPlatform.ReconcileStorageFolder, StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }
                    List <FileInfo> fileList;

                    foreach (DirectoryInfo studyDir in dateDir.GetDirectories())
                    {
                        if (studyDir.FullName.EndsWith("Deleted", StringComparison.InvariantCultureIgnoreCase))
                        {
                            continue;
                        }

                        // Check for Cancel message
                        if (CancelPending)
                        {
                            return;
                        }

                        String studyInstanceUid = studyDir.Name;

                        StudyStorageLocation location;
                        if (GetStudyStorageLocation(partition.Key, studyInstanceUid, out location))
                        {
                            #region Study record exists in db

                            int   integrityQueueCount;
                            int   workQueueCount;
                            Study theStudy = GetStudyAndQueues(location, out integrityQueueCount, out workQueueCount);
                            if (theStudy != null)
                            {
                                continue;
                            }

                            if (integrityQueueCount != 0 && workQueueCount != 0)
                            {
                                continue;
                            }

                            fileList = LoadSopFiles(studyDir, false);

                            if (fileList.Count == 0)
                            {
                                Platform.Log(LogLevel.Warn, "Found empty study folder with StorageLocation, deleteing StorageLocation: {0}\\{1}",
                                             dateDir.Name, studyDir.Name);
                                studyDir.Delete(true);

                                RemoveStudyStorage(location);
                                continue;
                            }

                            // WriteLock the new study storage for study processing
                            if (!location.QueueStudyStateEnum.Equals(QueueStudyStateEnum.ProcessingScheduled))
                            {
                                string failureReason;
                                if (!ServerHelper.LockStudy(location.Key, QueueStudyStateEnum.ProcessingScheduled, out failureReason))
                                {
                                    Platform.Log(LogLevel.Error, "Unable to lock study {0} for Study Processing", location.StudyInstanceUid);
                                }
                            }
                            #endregion
                        }
                        else
                        {
                            #region Directory not in DB,

                            fileList = LoadSopFiles(studyDir, true);

                            if (fileList.Count == 0)
                            {
                                Platform.Log(LogLevel.Warn, "Found empty study folder: {0}\\{1}", dateDir.Name, studyDir.Name);
                                continue;
                            }

                            DicomFile file = LoadFileFromList(fileList);

                            if (file == null)
                            {
                                Platform.Log(LogLevel.Warn, "Found directory with no readable files: {0}\\{1}", dateDir.Name, studyDir.Name);
                                continue;
                            }

                            // Do a second check, using the study instance uid from a file in the directory.
                            // had an issue with trailing periods on uids causing us to not find the
                            // study storage, and insert a new record into the database.
                            studyInstanceUid = file.DataSet[DicomTags.StudyInstanceUid].ToString();
                            if (GetStudyStorageLocation(partition.Key, studyInstanceUid, out location))
                            {
                                continue;
                            }

                            StudyStorage storage;
                            if (GetStudyStorage(partition, studyInstanceUid, out storage))
                            {
                                Platform.Log(LogLevel.Warn, "Study {0} on filesystem partition {1} is offline {2}", studyInstanceUid,
                                             partition.Description, studyDir.ToString());
                                continue;
                            }

                            Platform.Log(LogLevel.Info, "Reinventory inserting study storage location for {0} on partition {1}", studyInstanceUid,
                                         partition.Description);

                            // Insert StudyStorage
                            using (IUpdateContext update = _store.OpenUpdateContext(UpdateContextSyncMode.Flush))
                            {
                                IInsertStudyStorage          studyInsert = update.GetBroker <IInsertStudyStorage>();
                                InsertStudyStorageParameters insertParms = new InsertStudyStorageParameters
                                {
                                    ServerPartitionKey  = partition.GetKey(),
                                    StudyInstanceUid    = studyInstanceUid,
                                    Folder              = dateDir.Name,
                                    FilesystemKey       = filesystem.GetKey(),
                                    QueueStudyStateEnum =
                                        QueueStudyStateEnum.Idle
                                };
                                if (file.TransferSyntax.LosslessCompressed)
                                {
                                    insertParms.TransferSyntaxUid = file.TransferSyntax.UidString;
                                    insertParms.StudyStatusEnum   = StudyStatusEnum.OnlineLossless;
                                }
                                else if (file.TransferSyntax.LossyCompressed)
                                {
                                    insertParms.TransferSyntaxUid = file.TransferSyntax.UidString;
                                    insertParms.StudyStatusEnum   = StudyStatusEnum.OnlineLossy;
                                }
                                else
                                {
                                    insertParms.TransferSyntaxUid = file.TransferSyntax.UidString;
                                    insertParms.StudyStatusEnum   = StudyStatusEnum.Online;
                                }

                                location = studyInsert.FindOne(insertParms);

                                // WriteLock the new study storage for study processing
                                ILockStudy          lockStudy = update.GetBroker <ILockStudy>();
                                LockStudyParameters lockParms = new LockStudyParameters
                                {
                                    StudyStorageKey     = location.Key,
                                    QueueStudyStateEnum =
                                        QueueStudyStateEnum.ProcessingScheduled
                                };
                                if (!lockStudy.Execute(lockParms) || !lockParms.Successful)
                                {
                                    Platform.Log(LogLevel.Error, "Unable to lock study {0} for Study Processing", location.StudyInstanceUid);
                                }

                                update.Commit();
                            }
                            #endregion
                        }

                        string studyXml = location.GetStudyXmlPath();
                        if (File.Exists(studyXml))
                        {
                            FileUtils.Delete(studyXml);
                        }

                        string studyGZipXml = location.GetCompressedStudyXmlPath();
                        if (File.Exists(studyGZipXml))
                        {
                            FileUtils.Delete(studyGZipXml);
                        }


                        foreach (FileInfo sopFile in fileList)
                        {
                            String sopInstanceUid = sopFile.Name.Replace(sopFile.Extension, string.Empty);

                            using (ServerExecutionContext context = new ServerExecutionContext())
                            {
                                // Just use a read context here, in hopes of improving
                                // performance.  Every other place in the code should use
                                // Update contexts when doing transactions.
                                IInsertWorkQueue workQueueInsert =
                                    context.ReadContext.GetBroker <IInsertWorkQueue>();

                                InsertWorkQueueParameters queueInsertParms =
                                    new InsertWorkQueueParameters
                                {
                                    WorkQueueTypeEnum  = WorkQueueTypeEnum.StudyProcess,
                                    StudyStorageKey    = location.GetKey(),
                                    ServerPartitionKey = partition.GetKey(),
                                    SeriesInstanceUid  = sopFile.Directory.Name,
                                    SopInstanceUid     = sopInstanceUid,
                                    ScheduledTime      = Platform.Time
                                };

                                if (workQueueInsert.FindOne(queueInsertParms) == null)
                                {
                                    Platform.Log(LogLevel.Error,
                                                 "Failure attempting to insert SOP Instance into WorkQueue during Reinventory.");
                                }
                            }
                        }
                    }

                    // Cleanup the date directory, if its empty.
                    DirectoryUtility.DeleteIfEmpty(dateDir.FullName);
                }
            }
        }