public void AddRule(RuleDto ruleDto)
        {
            var rule = new Rule
            {
                vchName = ruleDto.Name,
                bEnabled = ruleDto.Enabled,
                vchAction = ruleDto.Action,
                tPoolActiveTime = ruleDto.PoolActiveTime,
                iPoolMaxMessages = ruleDto.PoolMaxMessages,
                iOrder = ruleDto.Order,
                vchCustomSubject = ruleDto.CustomSubject ?? "",
                vchApplicationName = ruleDto.ApplicationName ?? "",
                vchMachineName = ruleDto.MachineName ?? "",
                vchHelpText = ruleDto.HelpText ?? "",
                vchCommandLineArgs = ruleDto.CommandLineArgs ?? "",
                vchStackTrace = ruleDto.StackTrace ?? "",
                vchExceptionType = ruleDto.ExceptionType ?? "",
                vchExceptionMessage = ruleDto.ExceptionMessage ?? "",
                iApplicationGroupID = ruleDto.ApplicationGroupId != 0 ? ruleDto.ApplicationGroupId : null,
                iMachineGroupID = ruleDto.MachineGroupId != 0 ? ruleDto.MachineGroupId : null,
                iPriorityID = ruleDto.PriorityId != 0 ? ruleDto.PriorityId : null,
                bContinueProcessing = ruleDto.ContinueProcessing
            };

            Uow.Rules.Add(rule);
            Uow.Commit();
        }
        public List<RuleDto> GetRuleConflicts(RuleDto ruleToCheck)
        {
            var rules = GetEnabledRulesWhereContinueIsFalse();

            return (from rule in rules
                    let conflict = ruleToCheck.ConflictsWith(rule) || rule.ConflictsWith(ruleToCheck)
                    where conflict
                    select rule).ToList();
        }
        public void AddRule_AddsAndCommits()
        {
            // arrange
            var rule = new RuleDto()
            {
                ApplicationName = "Test"
            };

            // act
            RuleService.AddRule(rule);

            // assert
            MockRepoRule.Verify(x => x.Add(It.Is<Rule>(r => r.vchApplicationName == rule.ApplicationName)));
            MockUow.Verify(x => x.Commit());
        }
        public void UpdateRule(RuleDto ruleDto)
        {
            var r = Uow.Rules.GetById(ruleDto.Id);
            r.vchName = ruleDto.Name;
            r.bEnabled = ruleDto.Enabled;
            r.vchAction = ruleDto.Action;
            r.tPoolActiveTime = ruleDto.PoolActiveTime;
            r.iPoolMaxMessages = ruleDto.PoolMaxMessages;
            r.vchCustomSubject = ruleDto.CustomSubject;
            r.vchApplicationName = ruleDto.ApplicationName;
            r.vchMachineName = ruleDto.MachineName;
            r.vchHelpText = ruleDto.HelpText;
            r.vchCommandLineArgs = ruleDto.CommandLineArgs;
            r.vchStackTrace = ruleDto.StackTrace;
            r.vchExceptionType = ruleDto.ExceptionType;
            r.vchExceptionMessage = ruleDto.ExceptionMessage;
            r.iApplicationGroupID = ruleDto.ApplicationGroupId != 0 ? ruleDto.ApplicationGroupId : null;
            r.iMachineGroupID = ruleDto.MachineGroupId != 0 ? ruleDto.MachineGroupId : null;
            r.iPriorityID = ruleDto.PriorityId != 0 ? ruleDto.PriorityId : null;
            r.bContinueProcessing = ruleDto.ContinueProcessing;

            // The order changed, so we have to update all rules
            if (ruleDto.Order != r.iOrder)
            {
                // If the new order has higher precedence, bump everything from its new spot to its old one by 1
                if (ruleDto.Order < r.iOrder)
                {
                    var rules = Uow.Rules.GetAll().Where(x => x.iOrder >= ruleDto.Order && x.iOrder <= r.iOrder).ToList();
                    foreach (var x in rules)
                    {
                        x.iOrder = x.iOrder + 1;
                        Uow.Rules.Update(x);
                    }
                }
                else
                {
                    var rules = Uow.Rules.GetAll().Where(x => x.iOrder <= ruleDto.Order && x.iOrder >= r.iOrder).ToList();
                    foreach (var x in rules)
                    {
                        x.iOrder = x.iOrder - 1;
                        Uow.Rules.Update(x);
                    }
                }
            }

            r.iOrder = ruleDto.Order;
            Uow.Rules.Update(r);
            Uow.Commit();
        }
        public bool ConflictsWith(RuleDto rule)
        {
            if (!Enabled || !rule.Enabled) return false;
            if (Order > rule.Order || Id == rule.Id) return false;

            var conflict = true;

            if (ApplicationGroupId != null)
                conflict &= ApplicationGroupId == rule.ApplicationGroupId;

            if (MachineGroupId != null)
                conflict &= MachineGroupId == rule.MachineGroupId;

            if (!string.IsNullOrEmpty(ApplicationName))
                conflict &= ApplicationName == rule.ApplicationName;

            if (!string.IsNullOrEmpty(MachineName))
                conflict &= MachineName == rule.MachineName;

            if (!string.IsNullOrEmpty(HelpText))
                conflict &= HelpText == rule.HelpText;

            if (!string.IsNullOrEmpty(CommandLineArgs))
                conflict &= CommandLineArgs == rule.CommandLineArgs;

            if (!string.IsNullOrEmpty(ExceptionType))
                conflict &= ExceptionType == rule.ExceptionType;

            if (!string.IsNullOrEmpty(ExceptionMessage))
                conflict &= ExceptionMessage == rule.ExceptionMessage;

            if (!string.IsNullOrEmpty(StackTrace))
                conflict &= StackTrace == rule.StackTrace;

            return conflict;
        }
        public void GetRuleConflicts_WithRuleOfHigherOrderAndConflict_ReturnsConflict()
        {
            // arrange
            var rules = new List<Rule>
            {
                new Rule {iRuleID = 1, iOrder = 1, vchExceptionMessage = "Exception Message 1", vchExceptionType = "Exception Type 1", bEnabled = true},
                new Rule {iRuleID = 2, iOrder = 2, vchExceptionMessage = "Exception Message 2", vchExceptionType = "Exception Type 2", bEnabled = true}
            };

            var ruleToCheckForConflicts = new RuleDto
            {
                Id = 3,
                Order = 3,
                ExceptionMessage = "Exception Message 1",
                ExceptionType = "Exception Type 1",
                CommandLineArgs = "Command line args",
                Enabled = true
            };

            MockRepoRule.Setup(x => x.GetEnabledRulesWhereContinueIsFalse()).Returns(rules);

            // act
            var results = RuleService.GetRuleConflicts(ruleToCheckForConflicts);

            // assert
            Assert.IsNotNull(results);
            Assert.IsTrue(results.Count == 1);
        }
        public void UpdateRule()
        {
            // arrange
            var ruleDto = new RuleDto()
            {
                Id = 1,
                Order = 4
            };

            var rule = new Rule()
            {
                iRuleID = 1,
                iOrder = 2
            };

            MockRepoRule.Setup(x => x.GetById(ruleDto.Id)).Returns(rule);

            // act
            RuleService.UpdateRule(ruleDto);

            // assert
            MockRepoRule.Verify(x => x.Update(rule));
            MockUow.Verify(x => x.Commit());
        }
        public void GetRuleConflicts_WithRuleOfLowerOrderAndNoConflict_ReturnsEmptyList()
        {
            // arrange
            var rules = new List<Rule>
            {
                new Rule {iOrder = 1, vchExceptionMessage = "Exception Message 1", vchExceptionType = "Exception Type 1"},
                new Rule {iOrder = 2, vchExceptionMessage = "Exception Message 2", vchExceptionType = "Exception Type 2"}
            };

            var ruleToCheckForConflicts = new RuleDto
            {
                Order = 0,
                ExceptionMessage = "Exception Message 1",
                ExceptionType = "Exception Type 1",
                CommandLineArgs = "Command line args"
            };

            MockRepoRule.Setup(x => x.GetEnabledRulesWhereContinueIsFalse()).Returns(rules);

            // act
            var results = RuleService.GetRuleConflicts(ruleToCheckForConflicts);

            // assert
            Assert.IsNotNull(results);
            Assert.IsTrue(results.Count == 0);
        }
        /// <summary>
        /// Pool a message for a specific rule
        /// </summary>
        /// <param name="rule"></param>
        /// <param name="messageId"></param>
        /// <returns>If the message should be delivered to the recipient</returns>
        private bool PoolMessage(RuleDto rule, int messageId)
        {
            var pool = _poolService.GetActivePoolByRuleId(rule.Id);
            var deliver = true;

            // check if a pool is sill active for the matched rule. if it is, just add the message to the pool
            if (pool != null)
            {
                // Make sure this pool should remain active or not
                var active = DateTime.Now - pool.StartTime <= rule.PoolActiveTime &&
                             _messagePoolService.GetMessagePoolsByPoolId(pool.Id).Count + 1 < rule.PoolMaxMessages;

                var messagePool = new MessagePoolDto
                {
                    MessageId = messageId,
                    PoolId = pool.Id
                };

                if (active)
                {
                    // pool message
                    _messagePoolService.AddMessagePool(messagePool);
                    deliver = false;
                }
                else
                {
                    // close pool and perform action
                    _messagePoolService.AddMessagePool(messagePool);
                    _poolService.DeactivatePool(pool.Id);
                }
            }
            else
            {
                // Create a new pool for this rule, and add the message and pool to the MassgePool table
                var poolId = _poolService.AddPool(rule.Id);
                var messagePool = new MessagePoolDto
                {
                    MessageId = messageId,
                    PoolId = poolId
                };
                _messagePoolService.AddMessagePool(messagePool);
                deliver = false;
            }

            return deliver;
        }
 /// <summary>
 /// Check if a rule matches a message
 /// </summary>
 /// <param name="rule"></param>
 /// <param name="message"></param>
 /// <returns></returns>
 public bool IsMatch(RuleDto rule, MessageRoutingSystemError message)
 {
     return CheckApplicationGroupMatch(rule.ApplicationGroupId, message.ApplicationName) &&
            CheckMachineGroupMatch(rule.MachineGroupId, message.MachineName) &&
            CheckRuleMatch(rule.ApplicationName, message.ApplicationName) &&
            CheckRuleMatch(rule.MachineName, message.MachineName) &&
            CheckRuleMatch(rule.HelpText, message.HelpText) &&
            CheckRuleMatch(rule.CommandLineArgs, message.CommandLineArgs) &&
            CheckRuleMatch(rule.ExceptionType, message.ExceptionType) &&
            CheckRuleMatch(rule.ExceptionMessage, message.ExceptionMessage) &&
            CheckRuleMatch(rule.StackTrace, message.StackTrace);
 }
        /// <summary>
        /// Either create a new rule, or update an existing one.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOK_Click(object sender, EventArgs e)
        {
            var ruleName = txtRuleName.Text;
            var enabled = chkEnabled.Checked;
            var action = txtSendTo.Text;
            var priority = cbPriority.Text;
            var applicationGroupName = cbApplicationGroup.Text;
            var machineGroupName = cbMachineGroup.Text;
            var poolTime = TimeSpan.FromMinutes((double)nudPoolTime.Value);
            var poolMaxMessages = decimal.ToInt32(nudPoolMaxMessages.Value);
            var customSubject = txtSubject.Text;
            var order = (int)nudOrder.Value;

            var rule = new RuleDto
            {
                Id = _selectedRuleId > 0 ? _selectedRuleId : 0,
                Name = ruleName,
                Action = action,
                Enabled = enabled,
                PoolActiveTime = poolTime,
                PoolMaxMessages = poolMaxMessages,
                CustomSubject = customSubject,
                Order = order,
                ApplicationName = cbApplicationName.Text,
                MachineName = cbMachineName.Text,
                HelpText = txtHelpText.Text,
                CommandLineArgs = txtCommandLineArgs.Text,
                ExceptionType = txtExceptionType.Text,
                ExceptionMessage = txtExceptionMessage.Text,
                StackTrace = txtStackTrace.Text,
                ContinueProcessing = chkContinueProcessing.Checked
            };

            if (!string.IsNullOrEmpty(applicationGroupName))
                rule.ApplicationGroupId = _applicationService.GetApplicationGroupByName(applicationGroupName).ID;

            if (!string.IsNullOrEmpty(machineGroupName))
                rule.MachineGroupId = _machineService.GetMachineGroupByName(machineGroupName).ID;

            if (!string.IsNullOrEmpty(priority))
                rule.PriorityId = _priorityService.GetPriorityByName(priority).Id;

            if (CheckRuleConflicts(rule))
            {
                if (_selectedRuleId == 0)
                {
                    _ruleService.AddRule(rule);
                }
                else
                {
                    _ruleService.UpdateRule(rule);
                }

                dgvRules.DataSource = _ruleService.GetRules().OrderBy(x => x.Order).ToList();
            }
        }
        private bool CheckRuleConflicts(RuleDto rule)
        {
            // Alert user of any rule conflicts
            var conflicts = _ruleService.GetRuleConflicts(rule);
            var continueProcessing = true;
            if (conflicts.Any())
            {
                var sb = new StringBuilder();
                var ruleNames = string.Join(Environment.NewLine, conflicts.Select(c => c.Name));
                sb.AppendLine("Conflicts were detected with the following rules:");
                sb.AppendLine(ruleNames);
                sb.AppendLine();
                sb.AppendLine("Are you sure you want to save this rule?");
                var result = MessageBox.Show(sb.ToString(), "Confirm", MessageBoxButtons.YesNo);

                continueProcessing = result == DialogResult.Yes;
            }

            return continueProcessing;
        }