/// <summary>
 /// Updates the specified model.
 /// </summary>
 /// <param name="model">The model.</param>
 /// <param name="isPolling">if set to <c>true</c> [is polling].</param>
 /// <exception cref="System.Exception"></exception>
 public void Update(Enclosure model, bool isPolling)
 {
     try
     {
         HWLogger.GetFdSdkLogger(model.FusionDirectorIp).Debug($"Start UpdateEnclosure.[{model.UnionId}] [isPolling:{isPolling}]");
         var exsitEnclosure = this.GetObject($"UnionId = '{model.UnionId}'", this.EnclosureClass);
         if (exsitEnclosure == null)
         {
             throw new Exception($"Can not find the server:{model.UnionId}");
         }
         var isChange = CompareEnclosure(model, exsitEnclosure);
         if (isChange)
         {
             var discoveryData = new IncrementalDiscoveryData();
             this.UpdateEnclosure(model, exsitEnclosure);
             discoveryData.Add(exsitEnclosure);
             discoveryData.Overwrite(this.MontioringConnector);
             HWLogger.GetFdSdkLogger(model.FusionDirectorIp).Info($"Update enclosure finish.[{model.UnionId}]");
         }
     }
     catch (Exception e)
     {
         HWLogger.GetFdSdkLogger(model.FusionDirectorIp).Error(e, $"Update enclosure error.[{model.UnionId}] [isPolling:{isPolling}]");
     }
 }
        /// <summary>
        /// Deletes the kun lun on synchronize.
        /// </summary>
        /// <param name="fdIp">The e sight ip.</param>
        /// <param name="newIds">The new device ids.</param>
        public void CompareDataOnSync(string fdIp, List <string> newIds)
        {
            try
            {
                MGroup.Instance.CheckConnection();
                HWLogger.GetFdSdkLogger(fdIp).Info($"Check And Removed Enclosure On Polling.[curQueryResult:{string.Join(",", newIds)}]");
                var criteria      = new MonitoringObjectCriteria($"Name like '%{fdIp}%'", EnclosureClass);
                var exsitObjects  = MGroup.Instance.EntityObjects.GetObjectReader <MonitoringObject>(criteria, ObjectQueryOptions.Default).ToList();
                var deleteObjects = exsitObjects.Where(x => newIds.All(newDeviceId => newDeviceId != x[EnclosureKey].Value.ToString())).ToList();
                var newObjects    = newIds.Where(x => exsitObjects.All(y => x != y[EnclosureKey].Value.ToString())).ToList();

                HWLogger.GetFdSdkLogger(fdIp).Info($"Compare Enclosures Result:[new:{newObjects.Count}] [Delete:{deleteObjects.Count}]");

                var discovery = new IncrementalDiscoveryData();
                deleteObjects.ForEach(deleteDevice =>
                {
                    discovery.Remove(deleteDevice);
                });
                discovery.Commit(this.MontioringConnector);
                HWLogger.GetFdSdkLogger(fdIp).Debug($"Remove Enclosure On Polling:[Count:{deleteObjects.Count}].[{string.Join(",", deleteObjects.Select(x => x[EnclosureKey].Value.ToString()))}]");
            }
            catch (Exception e)
            {
                HWLogger.GetFdSdkLogger(fdIp).Error(e, $"Compare Enclosures Data On Sync.");
            }
        }
 /// <summary>
 /// Removes the server from m group.
 /// </summary>
 /// <param name="fdIp">The fd ip.</param>
 public void RemoveEnclosureByFd(string fdIp)
 {
     try
     {
         HWLogger.GetFdSdkLogger(fdIp).Info($"RemoveEnclosureByFd.[{fdIp}]");
         MGroup.Instance.CheckConnection();
         var criteria = new MonitoringObjectCriteria($"Name like '%{fdIp}%'", EnclosureClass);
         var devices  = MGroup.Instance.EntityObjects.GetObjectReader <MonitoringObject>(criteria, ObjectQueryOptions.Default).ToList();
         if (devices.Any())
         {
             var discovery = new IncrementalDiscoveryData();
             devices.ForEach(device => discovery.Remove(device));
             discovery.Commit(this.MontioringConnector);
         }
     }
     catch (Exception ex)
     {
         HWLogger.GetFdSdkLogger(fdIp).Error(ex, "RemoveEnclosureByFd");
     }
 }
        /// <summary>
        /// 插入告警时,等待新增的对象的healthState不再是Not Monitor
        /// </summary>
        /// <param name="mpClass">The mp class.</param>
        /// <param name="obj">The object.</param>
        /// <param name="eventData">The event data.</param>
        /// <returns>PartialMonitoringObject.</returns>
        public bool CheckAndWaitHealthStateReady(ManagementPackClass mpClass, PartialMonitoringObject obj, EventData eventData)
        {
            var logger = HWLogger.GetFdSdkLogger(eventData.FusionDirectorIp);

            if (obj.StateLastModified == null)
            {
                //如果对象添加超过5分钟,仍然没有健康状态,防止阻塞只查询一次
                if ((DateTime.Now - obj.TimeAdded).TotalMinutes > 5)
                {
                    obj = GetObjectByUnionId(mpClass, eventData.UnionId);;
                    if (obj.HealthState != HealthState.Uninitialized)
                    {
                        logger.Info($"{eventData.UnionId} first healthState is {obj.HealthState}.");
                        return(true);
                    }
                    return(false);
                }
                #region 新增对象
                logger.Info($"New Object:{eventData.UnionId}");
                int i = 0;
                while (i < 48)
                {
                    i++;
                    // 重新查询obj状态
                    obj = GetObjectByUnionId(mpClass, eventData.UnionId);;
                    if (obj.HealthState != HealthState.Uninitialized)
                    {
                        logger.Info($"{eventData.UnionId} first healthState is {obj.HealthState}.");
                        Thread.Sleep(TimeSpan.FromSeconds(5));
                        return(true);
                    }
                    logger.Info($"wait {eventData.UnionId} first Initialized...");
                    Thread.Sleep(TimeSpan.FromSeconds(5));
                }
                return(false);

                #endregion
            }
            return(true);
        }
        /// <summary>
        /// Inserts the specified model.
        /// </summary>
        /// <param name="model">The model.</param>
        public void Insert(Enclosure model)
        {
            try
            {
                HWLogger.GetFdSdkLogger(model.FusionDirectorIp).Debug($"Insert Enclosure:{model.UnionId}");
                var discoveryData = new IncrementalDiscoveryData();

                #region Enclosure

                var enclosure = this.CreateEnclosure(model);
                discoveryData.Add(enclosure);

                #endregion

                discoveryData.Commit(this.MontioringConnector);
                HWLogger.GetFdSdkLogger(model.FusionDirectorIp).Debug($"InsertEnclosure finish.[{model.UnionId}]");
            }
            catch (Exception e)
            {
                HWLogger.GetFdSdkLogger(model.FusionDirectorIp).Error(e, $"Insert Enclosure Error:{model.UnionId}");
            }
        }
        /// <summary>
        /// Inserts the specified model.
        /// </summary>
        /// <param name="model">The model.</param>
        private void Insert(Server model)
        {
            try
            {
                HWLogger.GetFdSdkLogger(model.FusionDirectorIp).Debug($"Insert Server:{model.UnionId}");
                var discoveryData = new IncrementalDiscoveryData();

                #region Server

                var server = this.CreateServer(model);
                discoveryData.Add(server);

                #endregion

                discoveryData.Commit(this.MontioringConnector);
                HWLogger.GetFdSdkLogger(model.FusionDirectorIp).Debug($"Insert Server Finish:{model.UnionId}");
            }
            catch (Exception e)
            {
                HWLogger.GetFdSdkLogger(model.FusionDirectorIp).Error(e, $"Insert Server Error:{model.UnionId}");
            }
        }
        /// <summary>
        /// Inserts the event.
        /// </summary>
        /// <param name="mpClass">The mp class.</param>
        /// <param name="eventData">The event data.</param>
        public void InsertEvent(ManagementPackClass mpClass, EventData eventData)
        {
            var logger = HWLogger.GetFdSdkLogger(eventData.FusionDirectorIp);

            try
            {
                var sn = eventData.AlarmSn.ToString();
                MGroup.Instance.CheckConnection();
                var logPre = $"[Sn={sn}] [OptType={eventData.OptType}] [LevelId={eventData.LevelId}] ";
                //logger.Info($"[Sn:{sn}] Start Deal Event.[{JsonConvert.SerializeObject(eventData)}]");
                var obj = GetObjectByUnionId(mpClass, eventData.UnionId);
                if (obj == null)
                {
                    logger.Warn($"{logPre} Can not find the MonitoringObject:{eventData.UnionId}");
                    return;
                }
                var isReady = CheckAndWaitHealthStateReady(mpClass, obj, eventData);
                if (!isReady)
                {
                    logger.Warn($"{logPre} The MonitoringObject state is uninitialized.Drop the event.");
                    return;
                }
                var eventHistory = obj.GetMonitoringEvents().ToList();
                switch (eventData.OptType)
                {
                case "1":
                    #region 告警
                    //如果不存在,则插入
                    //如果上次安装时的事件未清除,本次同步后,一个sn会存在两条数据,需要取最新添加的一条
                    var existEvent = eventHistory.OrderByDescending(x => x.TimeAdded).FirstOrDefault(x => x.GetAlarmData().Sn.ToString() == sn);
                    if (existEvent == null || existEvent.TimeAdded < MGroup.Instance.MpInstallTime)
                    {
                        obj.InsertCustomMonitoringEvent(eventData.ToCustomMonitoringEvent());
                        logger.Info($"{logPre}Insert new Event.");
                        if (eventData.LevelId == EventLogEntryType.Error || eventData.LevelId == EventLogEntryType.Warning)
                        {
                            if (eventData.AlarmData.Status == "Cleared")    //如果告警是清除状态
                            {
                                logger.Info($"{logPre}Need to close Event when insert.");
                                Task.Run(() =>
                                {
                                    int i = 0;
                                    while (i < 10)
                                    {
                                        i++;
                                        Thread.Sleep(TimeSpan.FromMinutes(1));
                                        var alertToClose = obj.GetMonitoringAlerts().FirstOrDefault(x => x.CustomField5 == sn);
                                        if (alertToClose != null)
                                        {
                                            alertToClose.ResolutionState = this.CloseState.ResolutionState;
                                            var comment = !string.IsNullOrEmpty(eventData.AlarmData.ClearType) ? eventData.AlarmData.ClearType : eventData.AlarmData.Additional;
                                            alertToClose.Update(comment);
                                            logger.Info($"{logPre}Close Event success.");
                                            break;
                                        }
                                    }
                                });
                            }
                        }
                    }
                    else
                    {
                        #region 存在则更新
                        var alertHistory  = obj.GetMonitoringAlerts();
                        var alertToUpdate = alertHistory.FirstOrDefault(x => x.CustomField5 == sn);
                        if (alertToUpdate != null)
                        {
                            alertToUpdate.CustomField2  = eventData.AlarmData.AlarmId;
                            alertToUpdate.CustomField3  = eventData.AlarmData.AlarmName.Split('#').Last();
                            alertToUpdate.CustomField4  = eventData.AlarmData.ResourceId;
                            alertToUpdate.CustomField5  = eventData.AlarmData.Sn.ToString();
                            alertToUpdate.CustomField7  = eventData.AlarmData.Additional;
                            alertToUpdate.CustomField8  = eventData.AlarmData.Suggestion;
                            alertToUpdate.CustomField8  = eventData.AlarmData.OccurTime;
                            alertToUpdate.CustomField9  = eventData.AlarmData.PossibleCause;
                            alertToUpdate.CustomField10 = eventData.AlarmData.Effect;

                            alertToUpdate.Update(eventData.AlarmData.Additional);
                            logger.Debug($"{logPre}Update Event.");
                            if (eventData.AlarmData.Status == "Cleared")    //如果告警是清除状态
                            {
                                alertToUpdate.ResolutionState = this.CloseState.ResolutionState;
                                alertToUpdate.Update(eventData.AlarmData.Additional);
                                logger.Info($"{logPre}Close Alert On Update Event.");
                            }
                            else
                            {
                                //如果原来的告警是关闭状态,本次是Open,则重新打开告警
                                if (alertToUpdate.ResolutionState == this.CloseState.ResolutionState)
                                {
                                    alertToUpdate.ResolutionState = this.NewState.ResolutionState;
                                    alertToUpdate.Update(eventData.AlarmData.Additional);
                                    logger.Info($"{logPre}Reopen Alert On Update Event.");
                                }
                            }
                        }
                        else
                        {
                            logger.Warn($"{logPre}Ingore Event.Can not find the alert.");
                        }
                        #endregion
                    }
                    #endregion
                    break;

                case "2":
                    #region 清除告警
                    if (eventData.LevelId == EventLogEntryType.Error || eventData.LevelId == EventLogEntryType.Warning)    //清除告警
                    {
                        var alertHistory = obj.GetMonitoringAlerts();
                        var alertToClose = alertHistory.FirstOrDefault(x => x.CustomField5 == sn);
                        if (alertToClose != null)
                        {
                            alertToClose.ResolutionState = this.CloseState.ResolutionState;
                            var comment = !string.IsNullOrEmpty(eventData.AlarmData.ClearType) ? eventData.AlarmData.ClearType : eventData.AlarmData.Additional;
                            alertToClose.Update(comment);
                            logger.Info($"{logPre}Close Event.");
                        }
                        else
                        {
                            logger.Warn($"{logPre}Ingore Event.Can not find the alert.");
                        }
                    }
                    else
                    {
                        logger.Warn($"{logPre}Ignore Event.");     //忽略事件
                    }
                    #endregion
                    break;

                case "3":    //肯定是事件
                    #region 插入事件
                    if (eventData.LevelId == EventLogEntryType.Information)
                    {
                        var existAlarmDatas = obj.GetMonitoringEvents().Select(x => x.GetAlarmData()).ToList();
                        //插入事件
                        if (existAlarmDatas.All(x => x.Sn.ToString() != sn))
                        {
                            logger.Info($"{logPre}Insert new Event.");
                            obj.InsertCustomMonitoringEvent(eventData.ToCustomMonitoringEvent());
                        }
                        else
                        {
                            logger.Warn($"{logPre}Ignore Event.The event is exist.");     //忽略已存在
                        }
                    }
                    else
                    {
                        logger.Warn($"{logPre}Ignore Event.");     //忽略非事件
                    }
                    #endregion
                    break;

                default:
                    logger.Error($"{logPre}Unknown OptType.");
                    break;
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }