public DeferredEval(
     IOperatorEvalStrategyFactory operatorEvalStrategyFactory,
     RulesEngineOptions rulesEngineOptions)
 {
     this.operatorEvalStrategyFactory = operatorEvalStrategyFactory;
     this.rulesEngineOptions          = rulesEngineOptions;
 }
            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();
                }
            }
Exemple #3
0
        public void EnsureValid_GivenOptionsNullReference_ThrowsInvalidRulesEngineOptionsExceptionClaimingNullOptions()
        {
            // Arrange
            RulesEngineOptions rulesEngineOptions = null;

            InvalidRulesEngineOptionsException actual = Assert.Throws <InvalidRulesEngineOptionsException>(() =>
            {
                // Act
                RulesEngineOptionsValidator.EnsureValid(rulesEngineOptions);
            });

            actual.Message.Should().Be("Specified null rulesEngineOptions.");
        }
Exemple #4
0
        public void EnsureValid_GivenOptionsWithInvalidDefaultForDataType_ThrowsInvalidRulesEngineOptionsExceptionClaimingInvalidDefault(DataTypes dataType, object defaultValue)
        {
            // Arrange
            RulesEngineOptions rulesEngineOptions = RulesEngineOptions.NewWithDefaults();

            rulesEngineOptions.DataTypeDefaults[dataType] = defaultValue;

            InvalidRulesEngineOptionsException actual = Assert.Throws <InvalidRulesEngineOptionsException>(() =>
            {
                // Act
                RulesEngineOptionsValidator.EnsureValid(rulesEngineOptions);
            });

            actual.Message.Should().Be($"Specified invalid default value for data type {dataType}: {defaultValue ?? "null"}.");
        }
        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);
                }
            }
        }
Exemple #6
0
        public void GetDeferredEvalFor_GivenStringConditionNodeWithNoConditionSuppliedAndRulesEngineConfiguredToUseDataTypeDefaultWhenMissing_ReturnsFuncThatEvalsFalse()
        {
            // Arrange
            StringConditionNode <ConditionType> conditionNode = new StringConditionNode <ConditionType>(ConditionType.IsoCurrency, Operators.Equal, "EUR");

            Mock <IOperatorEvalStrategy> mockOperatorEvalStrategy = new Mock <IOperatorEvalStrategy>();

            mockOperatorEvalStrategy.Setup(x => x.Eval(It.IsAny <string>(), It.IsAny <string>()))
            .Returns(false);

            Mock <IOperatorEvalStrategyFactory> mockOperatorEvalStrategyFactory = new Mock <IOperatorEvalStrategyFactory>();

            mockOperatorEvalStrategyFactory.Setup(x => x.GetOperatorEvalStrategy(It.IsAny <Operators>()))
            .Returns(mockOperatorEvalStrategy.Object);

            IEnumerable <Condition <ConditionType> > conditions = new Condition <ConditionType>[]
            {
                new Condition <ConditionType>
                {
                    Type  = ConditionType.IsoCountryCode,
                    Value = "PT"
                }
            };

            MatchModes matchMode = MatchModes.Exact;

            RulesEngineOptions rulesEngineOptions = RulesEngineOptions.NewWithDefaults();

            rulesEngineOptions.MissingConditionBehavior = MissingConditionBehaviors.UseDataTypeDefault;

            DeferredEval sut = new DeferredEval(mockOperatorEvalStrategyFactory.Object, rulesEngineOptions);

            // Act
            Func <IEnumerable <Condition <ConditionType> >, bool> actual = sut.GetDeferredEvalFor(conditionNode, matchMode);
            bool actualEvalResult = actual.Invoke(conditions);

            // Assert
            actualEvalResult.Should().BeFalse();

            mockOperatorEvalStrategyFactory.Verify(x => x.GetOperatorEvalStrategy(It.IsAny <Operators>()), Times.Once());
            mockOperatorEvalStrategy.Verify(x => x.Eval(It.IsAny <string>(), It.IsAny <string>()), Times.Once());
        }
Exemple #7
0
        public void GetDeferredEvalFor_GivenUnknownConditionNodeType_ThrowsNotSupportedException()
        {
            // Arrange
            Mock <IValueConditionNode <ConditionType> > mockValueConditionNode = new Mock <IValueConditionNode <ConditionType> >();

            Mock <IOperatorEvalStrategyFactory> mockOperatorEvalStrategyFactory = new Mock <IOperatorEvalStrategyFactory>();

            MatchModes matchMode = MatchModes.Exact;

            RulesEngineOptions rulesEngineOptions = RulesEngineOptions.NewWithDefaults();

            DeferredEval sut = new DeferredEval(mockOperatorEvalStrategyFactory.Object, rulesEngineOptions);

            // Act
            NotSupportedException notSupportedException = Assert.Throws <NotSupportedException>(() => sut.GetDeferredEvalFor(mockValueConditionNode.Object, matchMode));

            // Assert
            notSupportedException.Should().NotBeNull();
            notSupportedException.Message.Should().Be($"Unsupported value condition node: '{mockValueConditionNode.Object.GetType().Name}'.");
        }
Exemple #8
0
        /// <summary>
        /// Reapply specified rule.
        /// </summary>
        /// <param name="ruleId"></param>
        /// <param name="ruleName"></param>
        /// <param name="context"></param>
        public void Reapply(string ruleId, string ruleName, RulesEngineOptions context)
        {
            var request = new ReapplyRulesRequest
            {
                RuleId             = ruleId,
                RuleName           = ruleName,
                ApplyDeleteActions = context.ApplyDeleteActions,
                ApplyRouteActions  = context.ApplyRouteActions
            };

            try
            {
                InsertRequest(request, new ReapplyRulesProgress());
            }
            catch (Exception ex)
            {
                Exception = ex;
                Platform.Log(LogLevel.Error, ex, SR.MessageFailedToStartReapplyRules);
                throw;
            }
        }
Exemple #9
0
        public void GetDeferredEvalFor_GivenDecimalConditionNode_ReturnsFuncToEvalConditionsCollection()
        {
            // Arrange
            DecimalConditionNode <ConditionType> conditionNode = new DecimalConditionNode <ConditionType>(ConditionType.PluviosityRate, Operators.GreaterThan, 50);

            Mock <IOperatorEvalStrategy> mockOperatorEvalStrategy = new Mock <IOperatorEvalStrategy>();

            mockOperatorEvalStrategy.Setup(x => x.Eval(It.IsAny <decimal>(), It.IsAny <decimal>()))
            .Returns(true);

            Mock <IOperatorEvalStrategyFactory> mockOperatorEvalStrategyFactory = new Mock <IOperatorEvalStrategyFactory>();

            mockOperatorEvalStrategyFactory.Setup(x => x.GetOperatorEvalStrategy(It.IsAny <Operators>()))
            .Returns(mockOperatorEvalStrategy.Object);

            IEnumerable <Condition <ConditionType> > conditions = new Condition <ConditionType>[]
            {
                new Condition <ConditionType>
                {
                    Type  = ConditionType.PluviosityRate,
                    Value = 78
                }
            };

            MatchModes matchMode = MatchModes.Exact;

            RulesEngineOptions rulesEngineOptions = RulesEngineOptions.NewWithDefaults();

            DeferredEval sut = new DeferredEval(mockOperatorEvalStrategyFactory.Object, rulesEngineOptions);

            // Act
            Func <IEnumerable <Condition <ConditionType> >, bool> actual = sut.GetDeferredEvalFor(conditionNode, matchMode);
            bool actualEvalResult = actual.Invoke(conditions);

            // Assert
            actualEvalResult.Should().BeTrue();

            mockOperatorEvalStrategyFactory.Verify(x => x.GetOperatorEvalStrategy(It.IsAny <Operators>()), Times.Once());
            mockOperatorEvalStrategy.Verify(x => x.Eval(It.IsAny <decimal>(), It.IsAny <decimal>()), Times.Once());
        }
Exemple #10
0
        public static void EnsureValid(RulesEngineOptions rulesEngineOptions)
        {
            if (rulesEngineOptions == null)
            {
                throw new InvalidRulesEngineOptionsException($"Specified null {nameof(rulesEngineOptions)}.");
            }

            EnsureValidDataTypeDefault(
                rulesEngineOptions.DataTypeDefaults,
                DataTypes.Boolean,
                value => value != null && bool.TryParse(value.ToString(), out bool boolRes));
            EnsureValidDataTypeDefault(
                rulesEngineOptions.DataTypeDefaults,
                DataTypes.Decimal,
                value => value != null && decimal.TryParse(value.ToString(), out decimal decimalRes));
            EnsureValidDataTypeDefault(
                rulesEngineOptions.DataTypeDefaults,
                DataTypes.Integer,
                value => value != null && int.TryParse(value.ToString(), out int intRes));
            EnsureValidDataTypeDefault(
                rulesEngineOptions.DataTypeDefaults,
                DataTypes.String,
                value => value is string);
        }
Exemple #11
0
 public ConfiguredRulesEngineBuilder(IRulesDataSource <TContentType, TConditionType> rulesDataSource)
 {
     this.rulesDataSource    = rulesDataSource;
     this.rulesEngineOptions = RulesEngineOptions.NewWithDefaults();
 }
Exemple #12
0
 /// <summary>
 /// Reapply all rules.
 /// </summary>
 /// <param name="context"></param>
 public void ReapplyAll(RulesEngineOptions context)
 {
     Reapply(null, null, context);
 }
        private void ReprocessFolder()
        {
            try
            {
                var studyXml = Location.LoadStudyXml();
                var fileList = new List <ProcessStudyUtility.ProcessorFile>();

                // This code will cleanup a folder and move images around to the proper location.
                // It in essence allows you to just copy a bunch of files into the filestore, and reindex will clean them up and organize them.
                FileProcessor.Process(Location.StudyFolder, "*.dcm",
                                      delegate(string file, out bool cancel)
                {
                    cancel = _cancelRequested;
                    try
                    {
                        var dicomFile = new DicomFile(file);

                        dicomFile.Load(DicomReadOptions.StorePixelDataReferences | DicomReadOptions.Default);
                        String studyInstanceUid = dicomFile.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty);

                        if (!Location.Study.StudyInstanceUid.Equals(studyInstanceUid))
                        {
                            Platform.Log(LogLevel.Warn, "Importing file that was in the wrong study folder: {0}", file);
                            var context  = new ImportStudyContext(dicomFile.SourceApplicationEntityTitle, StudyStore.GetConfiguration(), EventSource.CurrentProcess);
                            var importer = new ImportFilesUtility(context);
                            var result   = importer.Import(dicomFile, BadFileBehaviourEnum.Delete, FileImportBehaviourEnum.Move);
                            if (!result.DicomStatus.Equals(DicomStatuses.Success))
                            {
                                try
                                {
                                    Platform.Log(LogLevel.Error, "Unable to import file: {0}, deleting: {1}", result.ErrorMessage, file);
                                    FileUtils.Delete(file);
                                }
                                catch (Exception x)
                                {
                                    Platform.Log(LogLevel.Warn, x, "Unexpected exception deleting file: {0}", file);
                                    Failed         = true;
                                    FailureMessage = x.Message;
                                }
                            }
                        }
                        else
                        {
                            fileList.Add(new ProcessStudyUtility.ProcessorFile(dicomFile, null));

                            if (fileList.Count > 19)
                            {
                                var p = new ProcessStudyUtility(Location)
                                {
                                    IsReprocess = true
                                };

                                p.ProcessBatch(fileList, studyXml);

                                fileList.Clear();
                            }
                        }
                    }
                    catch (Exception x)
                    {
                        Platform.Log(LogLevel.Error, "Exception when reindexing {0} files, last file: {1}: {2}", fileList.Count, file, x.Message);
                        fileList.Clear();                                                 // Clear out the failed entries
                        Failed         = true;
                        FailureMessage = x.Message;
                    }
                }, true);
                if (fileList.Count > 0)
                {
                    var p = new ProcessStudyUtility(Location)
                    {
                        IsReprocess = true
                    };

                    p.ProcessBatch(fileList, studyXml);

                    // Now apply Deletion rules

                    var ruleContext = new RulesEngineOptions
                    {
                        ApplyDeleteActions = true,
                        ApplyRouteActions  = false
                    };
                    RulesEngine.Create().ApplyStudyRules(p.StudyLocation.Study.ToStoreEntry(), ruleContext);
                }
            }
            catch (Exception x)
            {
                Platform.Log(LogLevel.Error, x, "Unexpected exception reindexing folder: {0}", Location.StudyFolder);
                Failed         = true;
                FailureMessage = x.Message;
            }

            if (_cancelRequested)
            {
                Platform.Log(LogLevel.Info, "Cancel requested while reprocessing folder: {0}", Location.StudyFolder);
            }
            else
            {
                Platform.Log(LogLevel.Info, "Completed reprocessing study folder: {0}", Location.Study.StudyInstanceUid);
            }
        }
        public async Task MatchManyAsync_GivenContentTypeDateAndConditions_FetchesRulesForDayEvalsAndReturnsAllMatches()
        {
            // Arrange
            DateTime    matchDateTime = new DateTime(2018, 07, 01, 18, 19, 30);
            ContentType contentType   = ContentType.Type1;
            IEnumerable <Condition <ConditionType> > conditions = new[]
            {
                new Condition <ConditionType>
                {
                    Type  = ConditionType.IsoCountryCode,
                    Value = "USA"
                },
                new Condition <ConditionType>
                {
                    Type  = ConditionType.IsoCurrency,
                    Value = "USD"
                }
            };

            Rule <ContentType, ConditionType> expected1 = new Rule <ContentType, ConditionType>
            {
                ContentContainer = new ContentContainer <ContentType>(contentType, (t) => new object()),
                DateBegin        = new DateTime(2018, 01, 01),
                DateEnd          = new DateTime(2019, 01, 01),
                Name             = "Expected rule 1",
                Priority         = 3,
                RootCondition    = new StringConditionNode <ConditionType>(ConditionType.IsoCountryCode, Operators.Equal, "USA")
            };

            Rule <ContentType, ConditionType> expected2 = new Rule <ContentType, ConditionType>
            {
                ContentContainer = new ContentContainer <ContentType>(contentType, (t) => new object()),
                DateBegin        = new DateTime(2010, 01, 01),
                DateEnd          = new DateTime(2021, 01, 01),
                Name             = "Expected rule 2",
                Priority         = 200,
                RootCondition    = new StringConditionNode <ConditionType>(ConditionType.IsoCountryCode, Operators.Equal, "USA")
            };

            Rule <ContentType, ConditionType> notExpected = new Rule <ContentType, ConditionType>
            {
                ContentContainer = new ContentContainer <ContentType>(contentType, (t) => new object()),
                DateBegin        = new DateTime(2018, 01, 01),
                DateEnd          = new DateTime(2019, 01, 01),
                Name             = "Not expected rule",
                Priority         = 1, // Topmost rule, should be the one that wins if options are set to topmost wins.
                RootCondition    = new StringConditionNode <ConditionType>(ConditionType.IsoCountryCode, Operators.Equal, "CHE")
            };

            IEnumerable <Rule <ContentType, ConditionType> > rules = new[]
            {
                expected1,
                expected2,
                notExpected
            };

            EvaluationOptions evaluationOptions = new EvaluationOptions
            {
                MatchMode = MatchModes.Exact
            };
            Mock <IRulesDataSource <ContentType, ConditionType> > mockRulesDataSource      = SetupMockForRulesDataSource(rules);
            Mock <IConditionsEvalEngine <ConditionType> >         mockConditionsEvalEngine = SetupMockForConditionsEvalEngine((rootConditionNode, inputConditions, evalOptions) =>
            {
                switch (rootConditionNode)
                {
                case StringConditionNode <ConditionType> stringConditionNode:
                    return(stringConditionNode.Operand == "USA");

                default:
                    return(false);
                }
            }, evaluationOptions);
            RulesEngineOptions rulesEngineOptions = RulesEngineOptions.NewWithDefaults();

            RulesEngine <ContentType, ConditionType> sut = new RulesEngine <ContentType, ConditionType>(mockConditionsEvalEngine.Object, mockRulesDataSource.Object, rulesEngineOptions);

            // Act
            IEnumerable <Rule <ContentType, ConditionType> > actual = await sut.MatchManyAsync(contentType, matchDateTime, conditions);

            // Assert
            actual.Should().Contain(expected1)
            .And.Contain(expected2)
            .And.NotContain(notExpected);
            mockRulesDataSource.Verify(x => x.GetRulesAsync(It.IsAny <ContentType>(), It.IsAny <DateTime>(), It.IsAny <DateTime>()), Times.Once());
            mockConditionsEvalEngine.Verify(x => x.Eval(
                                                It.IsAny <IConditionNode <ConditionType> >(),
                                                It.IsAny <IEnumerable <Condition <ConditionType> > >(),
                                                It.Is <EvaluationOptions>(eo => eo == evaluationOptions)), Times.AtLeastOnce());
        }
Exemple #15
0
		/// <summary>
		/// Reapply all rules.
		/// </summary>
		/// <param name="context"></param>
		public void ReapplyAll(RulesEngineOptions context)
		{
			Reapply(null, null, context);
		}
Exemple #16
0
		/// <summary>
		/// Reapply specified rule.
		/// </summary>
		/// <param name="ruleId"></param>
		/// <param name="ruleName"></param>
		/// <param name="context"></param>
		public void Reapply(string ruleId, string ruleName, RulesEngineOptions context)
		{
			var request = new ReapplyRulesRequest
			{
				RuleId = ruleId,
				RuleName = ruleName,
				ApplyDeleteActions = context.ApplyDeleteActions,
				ApplyRouteActions = context.ApplyRouteActions
			};

			try
			{
				InsertRequest(request, new ReapplyRulesProgress());
			}
			catch (Exception ex)
			{
				Exception = ex;
				Platform.Log(LogLevel.Error, ex, SR.MessageFailedToStartReapplyRules);
				throw;
			}
		}
        public async Task MatchOneAsync_GivenContentTypeDateAndConditions_FetchesRulesForDayFailsEvalsAndReturnsNull()
        {
            // Arrange
            DateTime    matchDateTime = new DateTime(2018, 07, 01, 18, 19, 30);
            ContentType contentType   = ContentType.Type1;
            IEnumerable <Condition <ConditionType> > conditions = new[]
            {
                new Condition <ConditionType>
                {
                    Type  = ConditionType.IsoCountryCode,
                    Value = "BRZ"
                },
                new Condition <ConditionType>
                {
                    Type  = ConditionType.IsoCurrency,
                    Value = "USD"
                }
            };

            IEnumerable <Rule <ContentType, ConditionType> > rules = new[]
            {
                new Rule <ContentType, ConditionType>
                {
                    ContentContainer = new ContentContainer <ContentType>(contentType, (t) => new object()),
                    DateBegin        = new DateTime(2018, 01, 01),
                    DateEnd          = new DateTime(2019, 01, 01),
                    Name             = "Expected rule",
                    Priority         = 3,
                    RootCondition    = new StringConditionNode <ConditionType>(ConditionType.IsoCountryCode, Operators.Equal, "USA")
                },
                new Rule <ContentType, ConditionType>
                {
                    ContentContainer = new ContentContainer <ContentType>(contentType, (t) => new object()),
                    DateBegin        = new DateTime(2010, 01, 01),
                    DateEnd          = new DateTime(2021, 01, 01),
                    Name             = "Expected rule",
                    Priority         = 200,
                    RootCondition    = new StringConditionNode <ConditionType>(ConditionType.IsoCountryCode, Operators.Equal, "USA")
                }
            };

            EvaluationOptions evaluationOptions = new EvaluationOptions
            {
                MatchMode = MatchModes.Exact
            };
            Mock <IRulesDataSource <ContentType, ConditionType> > mockRulesDataSource      = SetupMockForRulesDataSource(rules);
            Mock <IConditionsEvalEngine <ConditionType> >         mockConditionsEvalEngine = SetupMockForConditionsEvalEngine(false, evaluationOptions);
            RulesEngineOptions rulesEngineOptions = RulesEngineOptions.NewWithDefaults();

            RulesEngine <ContentType, ConditionType> sut = new RulesEngine <ContentType, ConditionType>(mockConditionsEvalEngine.Object, mockRulesDataSource.Object, rulesEngineOptions);

            // Act
            Rule <ContentType, ConditionType> actual = await sut.MatchOneAsync(contentType, matchDateTime, conditions);

            // Assert
            actual.Should().BeNull();
            mockRulesDataSource.Verify(x => x.GetRulesAsync(It.IsAny <ContentType>(), It.IsAny <DateTime>(), It.IsAny <DateTime>()), Times.Once());
            mockConditionsEvalEngine.Verify(x => x.Eval(
                                                It.IsAny <IConditionNode <ConditionType> >(),
                                                It.IsAny <IEnumerable <Condition <ConditionType> > >(),
                                                It.Is <EvaluationOptions>(eo => eo == evaluationOptions)), Times.AtLeastOnce());
        }
 public void ApplyStudyRule(StudyEntry study, string ruleId, RulesEngineOptions options)
 {
     ApplyDefaultDeletionRule(options, study);
 }
Exemple #19
0
        /// <summary>
        /// Main Processing routine.
        /// </summary>
        public override void Process()
        {
            bool stillProcessing = ProcessUidList();

            if (CancelPending)
            {
                Proxy.Cancel();
                return;
            }

            if (StopPending)
            {
                Proxy.Idle();
                return;
            }

            if (!stillProcessing)
            {
                bool failed       = false;
                bool complete     = true;
                bool filesMissing = false;
                foreach (WorkItemUid sop in WorkQueueUidList)
                {
                    if (sop.Failed)
                    {
                        //If any items failed simply because the file doesn't exist, then fail outright.
                        if (!File.Exists(GetFilePath(sop)))
                        {
                            filesMissing = true;
                        }

                        failed = true;
                        break;
                    }

                    if (!sop.Complete)
                    {
                        complete = false;
                        break;
                    }
                }

                DateTime now = Platform.Time;

                if (failed)
                {
                    var failureType = filesMissing ? WorkItemFailureType.Fatal : WorkItemFailureType.NonFatal;
                    Proxy.Fail(failureType);

                    if (Proxy.Item.Status == WorkItemStatusEnum.Failed)
                    {
                        var auditedInstances = new AuditedInstances();

                        auditedInstances.AddInstance(Request.Patient.PatientId, Request.Patient.PatientsName, Request.Study.StudyInstanceUid);

                        AuditHelper.LogImportStudies(auditedInstances,
                                                     string.IsNullOrEmpty(Request.UserName)
                                                         ? EventSource.CurrentProcess
                                                         : EventSource.GetUserEventSource(Request.UserName),
                                                     EventResult.MajorFailure);
                    }
                }
                else if (!complete)
                {
                    Proxy.Idle();
                }
                else if (now > Proxy.Item.ExpirationTime)
                {
                    if (Study == null)
                    {
                        Study = LoadRelatedStudy();
                    }

                    var ruleOptions = new RulesEngineOptions
                    {
                        ApplyDeleteActions = true,
                        ApplyRouteActions  = true
                    };
                    RulesEngine.Create().ApplyStudyRules(Study.ToStoreEntry(), ruleOptions);

                    Proxy.Complete();

                    var auditedInstances = new AuditedInstances();

                    auditedInstances.AddInstance(Request.Patient.PatientId, Request.Patient.PatientsName,
                                                 Request.Study.StudyInstanceUid);

                    AuditHelper.LogImportStudies(auditedInstances,
                                                 string.IsNullOrEmpty(Request.UserName)
                                                     ? EventSource.CurrentProcess
                                                     : EventSource.GetUserEventSource(Request.UserName),
                                                 EventResult.Success);
                }
                else
                {
                    Proxy.Idle();
                }
            }
            else
            {
                Proxy.Idle();
            }
        }