Beispiel #1
0
        public bool Save(string senderName = null, string serializeData = null, bool throwException = false)
        {
            var resultOperation   = true;
            var syncLogItemToSave = new SyncLogItem
            {
                Created   = DateTime.Now,
                Direction = tSyncDirection.In,
                DataSet   = string.IsNullOrEmpty(serializeData)
                    ? Serialize(throwException)
                    : serializeData,
                Description = NameForESB,
                Status      = tSyncStatus.Prepared,
                DataSource  = senderName
            };

            try
            {
                DataServiceFactory.SyncDataService.UpdateObject(syncLogItemToSave);
            }
            catch (Exception ex)
            {
                if (throwException)
                {
                    throw;
                }

                LogService.LogError(
                    $"Произошла ошибка при попытке сохранить SyncLogItem для сообщения: {nameof(ToMsrFromReestrMspCatalogDataChanges)}. Ошибка - {ex.Message}");
                resultOperation = false;
            }

            return(resultOperation);
        }
        /// <summary>
        /// Обработать сообщение.
        /// </summary>
        /// <param name="message">Сообщение из шины.</param>
        public void HandleMessage(SyncLogItem logItem)
        {
            if (!string.IsNullOrEmpty(logItem.DataSet))
            {
                var ds = DataServiceProvider.DataService;
                List <DataObject> toUpdate = new List <DataObject>();
                var viewGruppa             = new View {
                    DefineClassType = typeof(GruppaDublei)
                };
                viewGruppa.AddProperties(
                    nameof(GruppaDublei.idReestrZapisi),
                    nameof(GruppaDublei.FullValue)
                    );
                var viewLichnost = new View {
                    DefineClassType = typeof(Leechnost)
                };
                viewLichnost.AddProperty(nameof(Leechnost.GruppaDublei));

                var doc = new XmlDocument();
                doc.LoadXml(logItem.DataSet);

                var response = SerializationTools.DeserialiseDataContract <ToMsrFromReestrMspMergedItemsResponse>(logItem.DataSet);
                var i        = 0;
                if (response?.Items == null)
                {
                    return;
                }
                foreach (var item in response.Items)
                {
                    var idReestrZapisi = item.Beneficiary.Guid.ToString();
                    var xml            = doc.SelectNodes("//*[local-name() = 'Item']")[i].OuterXml;
                    var gruppa         = ds.Query <GruppaDublei>(GruppaDublei.Views.AuditView).Where(x => x.idReestrZapisi == idReestrZapisi).FirstOrDefault();
                    if (gruppa == null)
                    {
                        gruppa = new GruppaDublei
                        {
                            idReestrZapisi = idReestrZapisi.ToString(),
                            FullValue      = xml
                        };
                    }
                    else
                    {
                        gruppa.FullValue = xml;
                    }
                    toUpdate.Add(gruppa);
                    var keys      = item.Sources.Select(x => (object)x.Key).ToList();
                    var lichnosti = ds.Query <Leechnost>(viewLichnost).Where(x => keys.Contains(x.__PrimaryKey)).ToList();
                    lichnosti.ForEach(x => x.GruppaDublei = gruppa);
                    toUpdate.AddRange(lichnosti);
                    i++;
                }

                var objects = toUpdate.ToArray();

                ds.UpdateObjects(ref objects);
            }
        }
        /// <summary>
        /// Обработка поступившего объекта <see cref="SyncLogItem"/>.
        /// </summary>
        /// <param name="logItem"></param>
        public void HandleMessage(SyncLogItem logItem)
        {
            _syncLogItem = logItem;
            Process();
            var toUpdate = _toUpdateDef.ToArray();

            _ds.UpdateObjects(ref toUpdate);

            // Если объекты обновились\добавились успешно, то запишем в лог сообщения.
            foreach (var msg in _messagesToLog)
            {
                LogService.LogInfo(msg);
            }
        }
        private void AddDeletedDoc(BatchSet bs, BsonDocument doc, SyncLogItem logItem)
        {
            if (bs.DeletedDocuments == null)
            {
                bs.DeletedDocuments = new List <DeletedDocument>();
            }

            //check uploaded anchor- means cliet just uploaded this record and we should not return back
            if (logItem != null && logItem.KeyVersion != null && logItem.KeyVersion.ContainsKey(doc["o"].AsBsonDocument["_id"].AsString))
            {
                return;
            }

            DeletedDocument delDoc = new DeletedDocument();

            delDoc.Key = doc["o"].AsBsonDocument["_id"].AsString;
            bs.DeletedDocuments.Add(delDoc);
        }
Beispiel #5
0
        public bool Save(string senderName = null, string serializeData = null, bool throwException = false)
        {
            var result = false;

            try
            {
                var sli = new SyncLogItem
                {
                    Created     = DateTime.Now,
                    ChangesFrom = Items.FirstOrDefault()?.ChangeDate,
                    ChangesTo   = Items.LastOrDefault()?.ChangeDate,
                    DataSet     = string.IsNullOrEmpty(serializeData)
                        ? Serialize(throwException)
                        : serializeData,
                    DataSource = string.IsNullOrEmpty(senderName)
                        ? ConfigurationManager.AppSettings["AppName"]
                        : senderName,
                    Description = NameForESB,
                    Direction   = tSyncDirection.Out,
                    Processed   = null,
                    RequestInfo = null,
                    ResultInfo  = null,
                    Status      = tSyncStatus.Prepared
                };

                DataServiceFactory.SyncDataService.UpdateObject(sli);
                LogService.LogInfo(
                    $"Успешно сформировано синхронизационное сообщения типа {NameForESB}(pk-{sli.__PrimaryKey}) в него включено {Items.Count} изменений{Helper.GetDatePartAsString(sli.ChangesFrom, sli.ChangesTo)}");
                result = true;
            }
            catch (Exception)
            {
                if (throwException)
                {
                    throw;
                }

                LogService.LogError(
                    $"Произошла ошибка при попытке сохранить SyncLogItem для сообщения: {nameof(ToReestrMspFromMsrDataChanges)}.");
            }

            return(result);
        }
        public async Task <BatchSet> GetChanges(string bucketName, Filter query, int limit, string anchor, string uploadAnchor)
        {
            var db = client.GetDatabase("local");

            var collection    = db.GetCollection <BsonDocument>("oplog.rs");
            var filterBuilder = Builders <BsonDocument> .Filter;
            FilterDefinition <BsonDocument> filter = filterBuilder.Eq("ns", DbName + "." + bucketName);

            if (anchor != null)
            {
                filter = filter & filterBuilder.Gt("ts", new BsonTimestamp(Convert.ToInt64(anchor)));
            }
            var docs = await collection.Find(filter).Limit(limit).ToListAsync();

            BatchSet    bs      = new BatchSet();
            SyncLogItem logItem = null;

            if (docs != null && docs.Count > 0 && !string.IsNullOrEmpty(uploadAnchor))
            {
                logItem = await GetSyncLogItem(uploadAnchor);
            }

            int i = 0;

            foreach (var doc in docs)
            {
                if (i == docs.Count - 1)
                {
                    bs.Anchor = doc["ts"].AsBsonTimestamp.ToString();
                }
                i++;
                if (doc["op"] == "i" || doc["op"] == "u")
                {
                    this.AddChangedDoc(bs, doc, logItem, query);
                }
                else if (doc["op"] == "d")
                {
                    this.AddDeletedDoc(bs, doc, logItem);
                }
            }
            return(bs);
        }
Beispiel #7
0
        public bool Save(string senderName = null, string serializeData = null, bool throwException = false)
        {
            var result = false;

            try
            {
                var sli = new SyncLogItem
                {
                    ChangesFrom = null,
                    ChangesTo   = null,
                    Created     = DateTime.Now,
                    DataSource  = string.IsNullOrEmpty(senderName)
                        ? ConfigurationManager.AppSettings["AppName"]
                        : senderName,
                    DataSet = string.IsNullOrEmpty(serializeData)
                        ? Serialize(throwException)
                        : serializeData,
                    Description = NameForESB,
                    Direction   = tSyncDirection.Out,
                    Processed   = null,
                    RequestInfo = RequestInfo,
                    ResultInfo  = null,
                    Status      = tSyncStatus.Prepared
                };

                DataServiceFactory.SyncDataService.UpdateObject(sli);
                result = true;
            }
            catch (Exception)
            {
                if (throwException)
                {
                    throw;
                }

                LogService.LogError(
                    $"Произошла ошибка при попытке сохранить SyncLogItem для сообщения: {nameof(ToReestrMspFromMsrCatalogItemsRequest)}.");
            }

            return(result);
        }
        public static SyncLogItem GetLastSendMessage <TMessage>(bool throwException = false)
            where TMessage : ICommonMessage

        {
            SyncLogItem result   = null;
            var         typeName = GetDataContractNameForMessage <TMessage>();

            if (!string.IsNullOrEmpty(typeName))
            {
                var lcs = LoadingCustomizationStruct.GetSimpleStruct(typeof(SyncLogItem),
                                                                     SyncLogItem.Views.SyncLogItemE);
                lcs.LimitFunction = FunctionBuilder.BuildAnd(
                    FunctionBuilder.BuildEquals <SyncLogItem>(x => x.Description, typeName),
                    FunctionBuilder.BuildEquals <SyncLogItem>(x => x.Direction, tSyncDirection.Out),
                    FunctionBuilder.BuildIsNotNull <SyncLogItem>(x => x.ChangesTo),
                    FunctionBuilder.BuildIsNotNull <SyncLogItem>(x => x.ChangesFrom));
                lcs.ReturnTop   = 1;
                lcs.ColumnsSort = new[] { new ColumnsSortDef(nameof(SyncLogItem.Created), SortOrder.Desc) };
                try
                {
                    result = DataServiceFactory.SyncDataService.LoadObjects(lcs).Cast <SyncLogItem>().FirstOrDefault();
                }
                catch (Exception ex)
                {
                    if (throwException)
                    {
                        throw;
                    }

                    LogService.LogError(
                        $"Ошибка при попытке получить последнее sync-сообщение типа {typeof(TMessage).Name}. Ошибка вычитки сообщения из БД - {ex.Message}");
                }
            }
            else
            {
                LogService.LogError(
                    $"Ошибка при попытке получить последнее sync-сообщение типа {typeof(TMessage).Name}. Для сообщения не задан DataContractAttribute с заполенным значением Name");
            }

            return(result);
        }
        private void AddChangedDoc(BatchSet bs, BsonDocument doc, SyncLogItem logItem, Filter query)
        {
            if (bs.ChangedDocuments == null)
            {
                bs.ChangedDocuments = new List <SiaqodbDocument>();
            }

            var nestedDoc = doc["o"].AsBsonDocument;

            if (logItem != null && logItem.KeyVersion != null && logItem.KeyVersion.ContainsKey(nestedDoc["_id"].AsString) && logItem.KeyVersion[nestedDoc["_id"].AsString] == nestedDoc["_rev"].AsString)
            {
                return;
            }
            if (OutOfFilter(query, nestedDoc))
            {
                return;
            }
            SiaqodbDocument siaqodbDoc = Mapper.ToSiaqodbDocument(nestedDoc);

            bs.ChangedDocuments.Add(siaqodbDoc);
        }
        public async Task <BatchSet> GetChanges(string bucketName, Filter query, int limit, string anchor, string uploadAnchor)
        {
            using (var client = new MyCouchClient(DbServerUrl, bucketName))
            {
                GetChangesRequest changesReq = new GetChangesRequest();
                changesReq.Since       = anchor;
                changesReq.Limit       = limit;
                changesReq.IncludeDocs = true;
                var response = await client.Changes.GetAsync(changesReq);

                if (response.IsSuccess)
                {
                    BatchSet changeSet = new BatchSet();
                    if (response.Results != null)
                    {
                        SyncLogItem logItem = await this.GetSyncLogItem(uploadAnchor);

                        foreach (var row in response.Results)
                        {
                            if (row.Deleted)
                            {
                                this.AddDeletedDoc(changeSet, row, logItem);
                            }
                            else
                            {
                                this.AddChangedDoc(changeSet, row, logItem, query, client.Serializer);
                            }
                        }
                        changeSet.Anchor = response.LastSeq;
                    }

                    return(changeSet);
                }
                else
                {
                    CheckBucketNotFound(bucketName, response);
                }
                return(null);
            }
        }
        private async Task <SyncLogItem> GetSyncLogItem(string uploadAnchor)
        {
            var dbLog = client.GetDatabase(DbName);

            var collectionLog = dbLog.GetCollection <BsonDocument>(SyncLogBucket);
            var filterLog     = Builders <BsonDocument> .Filter.Eq("_id", ObjectId.Parse(uploadAnchor));

            var syncLogItem = await collectionLog.Find(filterLog).FirstOrDefaultAsync();

            if (syncLogItem != null)
            {
                var logItem = new SyncLogItem();
                logItem.KeyVersion = new Dictionary <string, string>();
                var logItemKV = syncLogItem["KeyVersion"].AsBsonDocument;
                foreach (var k in logItemKV.Names)
                {
                    logItem.KeyVersion.Add(k, logItemKV[k].ToString());
                }
                return(logItem);
            }
            return(null);
        }
        public bool Save(string senderName = null, string serializeData = null, bool throwException = false)
        {
            var result = false;

            try
            {
                var sli = new SyncLogItem
                {
                    Created     = DateTime.Now,
                    ChangesFrom = Items[0].ChangeDate,
                    ChangesTo   = Items[Items.Count - 1].ChangeDate,
                    DataSet     = string.IsNullOrEmpty(serializeData)
                        ? Serialize(throwException)
                        : serializeData,
                    DataSource  = senderName,
                    Description = NameForESB,
                    Direction   = tSyncDirection.In,
                    Processed   = null,
                    RequestInfo = null,
                    ResultInfo  = null,
                    Status      = tSyncStatus.Prepared
                };

                DataServiceFactory.SyncDataService.UpdateObject(sli);
                result = true;
            }
            catch (Exception)
            {
                if (throwException)
                {
                    throw;
                }

                LogService.LogError(
                    $"Произошла ошибка при попытке сохранить SyncLogItem для сообщения: {nameof(ToMsrFromTUResponse)}.");
            }

            return(result);
        }
        public async Task <BatchResponse> Store(string bucketName, BatchSet value)
        {
            var db = client.GetDatabase(DbName);

            var collection = db.GetCollection <BsonDocument>(bucketName);
            var response   = new BatchResponse();

            response.BatchItemResponses = new List <BatchItemResponse>();
            SyncLogItem syncLogItem = new SyncLogItem();

            syncLogItem.KeyVersion = new Dictionary <string, string>();

            foreach (var document in value.ChangedDocuments)
            {
                var newDoc = Mapper.ToBsonDoc(document);
                newDoc["_rev"] = this.GenerateNewVersion();
                try
                {
                    var exists = await collection.Find(filter : new BsonDocument {
                        { "_id", document.Key }
                    }).FirstOrDefaultAsync();

                    if (exists == null && !string.IsNullOrEmpty(document.Version)) //somebody else deleted the doc-> conflict
                    {
                        BatchItemResponse respWithError = BuildResponseWithError(document.Key, document.Version, "conflict");
                        response.ItemsWithErrors++;
                        response.BatchItemResponses.Add(respWithError);
                        continue;
                    }
                    var result = await collection.ReplaceOneAsync(filter : new BsonDocument {
                        { "_id", document.Key }, { "_rev", BsonTypeMapper.MapToBsonValue(document.Version) }
                    },
                                                                  options : new UpdateOptions {
                        IsUpsert = true
                    },
                                                                  replacement : newDoc);

                    BatchItemResponse itemResp = new BatchItemResponse
                    {
                        Key     = document.Key,
                        Version = newDoc["_rev"].AsString
                    };
                    response.BatchItemResponses.Add(itemResp);
                    syncLogItem.KeyVersion.Add(itemResp.Key, itemResp.Version);
                }
                catch (MongoWriteException ex)
                {
                    string error = ex.Message;
                    if (ex.Message.Contains("duplicate key"))//conflict
                    {
                        error = "conflict";
                    }
                    var itemResp = BuildResponseWithError(document.Key, document.Version, error);
                    response.ItemsWithErrors++;
                    response.BatchItemResponses.Add(itemResp);
                }
            }
            foreach (var document in value.DeletedDocuments)
            {
                BatchItemResponse itemResp = new BatchItemResponse()
                {
                    Key     = document.Key,
                    Version = document.Version
                };
                var del = await collection.DeleteOneAsync(filter : new BsonDocument {
                    { "_id", document.Key }, { "_rev", BsonTypeMapper.MapToBsonValue(document.Version) }
                });

                if (del.DeletedCount == 0)
                {
                    var docFromDB = collection.Find(filter: new BsonDocument {
                        { "_id", document.Key }
                    }).FirstOrDefaultAsync();
                    if (docFromDB != null)
                    {
                        itemResp.Error     = "conflict";
                        itemResp.ErrorDesc = "conflict";
                        response.ItemsWithErrors++;
                    }
                }
                response.BatchItemResponses.Add(itemResp);
            }
            //store uploadedAnchor
            if (syncLogItem.KeyVersion.Count > 0)
            {
                syncLogItem.TimeInserted = DateTime.UtcNow;
                BsonDocument syncLogDoc = new BsonDocument();
                syncLogDoc["KeyVersion"]   = new BsonDocument(syncLogItem.KeyVersion);
                syncLogDoc["TimeInserted"] = syncLogItem.TimeInserted;
                var collectionLog = db.GetCollection <BsonDocument>(SyncLogBucket);
                await collectionLog.InsertOneAsync(syncLogDoc);

                response.UploadAnchor = syncLogDoc["_id"].ToString();
            }

            return(response);
        }
Beispiel #14
0
        /// <summary>
        ///     Обработать сообщение.
        /// </summary>
        /// <param name="logItem">Сообщение из журнала синхронизации.</param>
        public void HandleDataChangeMessage <TMessage, TItem>(SyncLogItem logItem)
            where TMessage : IDataChangeMessageResponse <TItem>
            where TItem : IChangedItem
        {
            if (!string.IsNullOrEmpty(logItem.DataSet))
            {
                var doc = new XmlDocument();
                doc.LoadXml(logItem.DataSet);

                var xmlClassName = Settings.GetMessageClassTypeName(logItem.Description);
                if (!string.IsNullOrEmpty(xmlClassName))
                {
                    // Получаем тип по названию класса из конфиг файла.
                    var messageType = Type.GetType(xmlClassName);
                    if (messageType != null)
                    {
                        TMessage response;
                        try
                        {
                            response =
                                SerializationTools.DeserialiseDataContract <TMessage>(logItem.DataSet);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(
                                      $"Ошибка десерилизации объекта SyncLogItem.Pk = {logItem.__PrimaryKey}, тип ToMsrFromTUResponse.", ex);
                        }

                        if (response?.Items == null)
                        {
                            LogService.LogWarnFormat(
                                "В сообщениии SyncLogItem.Pk = {0}, отсутствуют объекты для обработки.",
                                logItem.__PrimaryKey);
                            return;
                        }

                        var arrToUpdate   = new List <DataObject>();
                        var arrConformity = new Dictionary <string, List <DataObject> >
                        {
                            { sObjectType, new List <DataObject>() },
                            { sSource, new List <DataObject>() },
                            { sConformity, new List <DataObject>() }
                        };

                        Source source = null;
                        try
                        {
                            source = _syncDS.Query <Source>(Source.Views.SourceE)
                                     .FirstOrDefault(x => x.name == logItem.DataSource);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(
                                      $"Произошла ошибка при вычитке источника из БД Source.Name = '{logItem.DataSource}'.", ex);
                        }

                        if (source == null)
                        {
                            source = new Source {
                                name = logItem.DataSource
                            };
                            arrConformity[sSource].Add(source);
                        }

                        foreach (var item in response.Items)
                        {
                            var obj = GetXMLDataObjInChangedItem(item);
                            //Получаем настройки для обработки типа сообщения.
                            GetSyncSettings(obj, out var destType, out var mapper);
                            ProcessObject(obj, item.State, destType, mapper,
                                          item.СhangedAttributes?.Select(x => x.Name).ToList(), source, ref arrToUpdate,
                                          ref arrConformity);
                        }

                        var listSync = new List <DataObject>();
                        listSync.AddRange(arrConformity[sObjectType]);
                        listSync.AddRange(arrConformity[sSource]);
                        var objectsDef  = arrToUpdate.ToArray();
                        var objectsSync = listSync.ToArray();

                        try
                        {
                            _defDS.UpdateObjectsOrdered(ref objectsDef);

                            _syncDS.UpdateObjects(ref objectsSync);
                            objectsSync = arrConformity[sConformity].ToArray();
                            _syncDS.UpdateObjects(ref objectsSync);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception($"Произошла ошибка при сохранении объектов в БД. {ex.InnerException?.Message ?? ex.Message}");
                        }
                    }
                    else
                    {
                        var errorMessage = $" Не найден XML-класс типа сообщения с названием {xmlClassName}";
                        throw new InvalidOperationException(errorMessage);
                    }
                }
                else
                {
                    var errorMessage =
                        $"Незаполнен тип xml-класса, для сообщения {logItem.Description}. Проверьте настройки секции messageHandlers в конфигурационном файле.";
                    throw new Exception(errorMessage);
                }
            }
        }
        public async Task <BatchResponse> Store(string bucketName, BatchSet batch)
        {
            using (var client = new MyCouchClient(DbServerUrl, bucketName))
            {
                var dbExists = await client.Database.HeadAsync();

                if (dbExists.IsSuccess)
                {
                    BulkRequest bulkRequest = new BulkRequest();

                    DateTime        start = DateTime.Now;
                    int             size  = 0;
                    SiaqodbDocument crObjForUpdateViews = null;
                    if (batch.ChangedDocuments != null)
                    {
                        foreach (SiaqodbDocument obj in batch.ChangedDocuments)
                        {
                            if (obj != null)
                            {
                                if (crObjForUpdateViews == null)
                                {
                                    crObjForUpdateViews = obj;
                                }

                                await CheckTagsViews(client, bucketName, obj.Tags);

                                CouchDBDocument doc = Mapper.ToCouchDBDoc(obj);
                                var             serializedObject = client.Serializer.Serialize <CouchDBDocument>(doc);
                                bulkRequest.Include(serializedObject);
                                size += serializedObject.Length;
                            }
                        }
                    }
                    if (batch.DeletedDocuments != null)
                    {
                        foreach (DeletedDocument obj in batch.DeletedDocuments)
                        {
                            if (obj != null)
                            {
                                if (obj.Version != null)//otherwise means is a non-existing object
                                {
                                    bulkRequest.Delete(obj.Key, obj.Version);
                                }
                            }
                        }
                    }
                    var response = await client.Documents.BulkAsync(bulkRequest);

                    if (response.IsSuccess)
                    {
                        var cnorResponse = new BatchResponse();
                        if (response.Rows != null)
                        {
                            cnorResponse.BatchItemResponses = new List <BatchItemResponse>();
                            SyncLogItem syncLogItem = new SyncLogItem();
                            syncLogItem.KeyVersion = new Dictionary <string, string>();
                            foreach (var row in response.Rows)
                            {
                                BatchItemResponse wresp = new BatchItemResponse();
                                if (!string.IsNullOrEmpty(row.Error))
                                {
                                    cnorResponse.ItemsWithErrors++;
                                }
                                wresp.Error     = row.Error;
                                wresp.ErrorDesc = row.Reason;
                                wresp.Key       = row.Id;
                                wresp.Version   = row.Rev;
                                cnorResponse.BatchItemResponses.Add(wresp);
                                if (string.IsNullOrEmpty(row.Error))
                                {
                                    syncLogItem.KeyVersion.Add(row.Id, row.Rev);
                                }
                            }
                            if (syncLogItem.KeyVersion.Count > 0)
                            {
                                syncLogItem.TimeInserted = DateTime.UtcNow;
                                using (var clientLog = new MyCouchClient(DbServerUrl, SyncLogBucket))
                                {
                                    string serLogItem = Newtonsoft.Json.JsonConvert.SerializeObject(syncLogItem);
                                    var    logResp    = await clientLog.Documents.PostAsync(serLogItem);

                                    cnorResponse.UploadAnchor = logResp.Id;
                                }
                            }
                        }
                        if (crObjForUpdateViews != null)
                        {
                            await this.StartRebuildViews(client, crObjForUpdateViews);
                        }

                        return(cnorResponse);
                    }
                    else
                    {
                        CheckBucketNotFound(bucketName, response);
                    }
                }
                else if (dbExists.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    throw new BucketNotFoundException(bucketName);
                }
                return(null);
            }
        }
        private void AddDeletedDoc(BatchSet changeSet, ChangesResponse <string> .Row row, SyncLogItem logItem)
        {
            if (changeSet.DeletedDocuments == null)
            {
                changeSet.DeletedDocuments = new List <DeletedDocument>();
            }
            DeletedDocument delObj = new DeletedDocument()
            {
                Key = row.Id, Version = row.Changes[0].Rev
            };

            //check uploaded anchor- means cliet just uploaded this record and we should not return back
            if (logItem != null && logItem.KeyVersion != null && logItem.KeyVersion.ContainsKey(delObj.Key) && logItem.KeyVersion[delObj.Key] == delObj.Version)
            {
                return;
            }
            changeSet.DeletedDocuments.Add(delObj);
        }
        public void Process()
        {
            var lcs = LoadingCustomizationStruct.GetSimpleStruct(
                typeof(SyncLogItem),
                SyncLogItem.Views.SyncLogItemE);

            lcs.LimitFunction = FunctionBuilder.BuildEquals <SyncLogItem>(i => i.Status, tSyncStatus.Invalid);

            if (DataService.GetObjectsCount(lcs) > 0)
            {
                LogService.LogWarn(
                    $"{MessageHeader}Обнаружено входящее сообщение, обработанное с ошибкой. Дальнейшее продолжение обработки невозможно! Исправьте сообщение и вручную обновите его статус.");
                return;
            }

            lcs.LimitFunction =
                FunctionBuilder.BuildAnd(
                    FunctionBuilder.BuildEquals <SyncLogItem>(i => i.Status, tSyncStatus.Prepared),
                    FunctionBuilder.BuildEquals <SyncLogItem>(i => i.Direction, tSyncDirection.In));
            lcs.AddColumnSort(new ColumnsSortDef(Information.ExtractPropertyName <SyncLogItem>(i => i.Created),
                                                 SortOrder.Asc));
            var preparedLogItems = DataService.LoadObjects(lcs).Cast <SyncLogItem>().ToArray();

            if (preparedLogItems.Any())
            {
                var itemCount = preparedLogItems.Length;
                LogService.LogInfo($"{MessageHeader}Обнаружено {itemCount} готовых к обработке сообщений.");
                var         syncLogitemForUpdate = new List <SyncLogItem>();
                var         errorMessage         = "";
                SyncLogItem logItem = null;
                for (var i = 0; i < itemCount; i++)
                {
                    logItem = preparedLogItems[i];
                    LogService.LogInfo(
                        $"{MessageHeader}Начата обработка {i+1}го сообщения (pk - {logItem.__PrimaryKey}) типа {logItem.Description}.");

                    var className = Settings.GetMessageHandlerTypeName(logItem.Description);
                    if (!string.IsNullOrEmpty(className))
                    {
                        var handlerType = Type.GetType(className);
                        if (handlerType != null)
                        {
                            if (Activator.CreateInstance(handlerType) is IMessageHandler handler)
                            {
                                try
                                {
                                    handler.HandleMessage(logItem);
                                }
                                catch (Exception ex)
                                {
                                    errorMessage =
                                        $"Произошла ошибка во время обработки сообщения типа: {logItem.Description}.{Environment.NewLine}{ex.Message}{Environment.NewLine}{ex.InnerException?.Message ?? ""}.";
                                    break;
                                }

                                logItem.Status = tSyncStatus.Success;
                                syncLogitemForUpdate.Add(logItem);
                                LogService.LogInfo(
                                    $"{MessageHeader} Cообщение (pk - {logItem.__PrimaryKey}) типа {logItem.Description} успешно обработано.");
                            }
                            else
                            {
                                errorMessage =
                                    $"Ошибка при попытке получить экземпляр обработчика для сообщения типа {logItem.Description}.";
                                break;
                            }
                        }
                        else
                        {
                            errorMessage =
                                $"Не удалось получить тип обработчика для сообщения типа {logItem.Description}. Проверьте настройки конфигурационного файла.";
                            break;
                        }
                    }
                    else
                    {
                        errorMessage =
                            $"Не удалось найти обработчик для сообщения типа {logItem.Description}. Проверьте настройки конфигурационного файла.";
                        break;
                    }
                }

                if (!string.IsNullOrEmpty(errorMessage))
                {
                    if (logItem != null)
                    {
                        logItem.Status = tSyncStatus.Invalid;
                        syncLogitemForUpdate.Add(logItem);
                        LogService.LogError($"{MessageHeader}Возникла ошибка при обработке входящего сообщения (pk - {logItem.__PrimaryKey}) {errorMessage}.");
                    }
                }

                var objToUpdate = syncLogitemForUpdate.Cast <DataObject>().ToArray();
                try
                {
                    DataService.UpdateObjects(ref objToUpdate);
                }
                catch (Exception ex)
                {
                    //TODO предусмотреть механизм автоматического выключения обработчика при этой ошибке.
                    var errorMsg = string.Join(";", syncLogitemForUpdate.Select(x => $"SincLogItem.PK - {x.__PrimaryKey}, new status -{x.Status}"));
                    LogService.LogError(
                        $"{MessageHeader}Произошла ошибка во время обновления статусов сообщений - {errorMsg}! Возможна повторная обработка сообщений! Необходимо срочно остановить обработчик и проставить статусы вручную!", ex);
                }
            }
        }
Beispiel #18
0
 /// <summary>
 ///     Обработать сообщение.
 /// </summary>
 /// <param name="logItem">Сообщение из журнала сообщений.</param>
 public void HandleMessage(SyncLogItem logItem)
 {
     DataChangeMessageHandlerFactory.DataMessageHandler.HandleDataChangeMessage <ToMsrFromTUResponse, ChangedItem>(logItem);
 }
        private void AddChangedDoc(BatchSet changeSet, ChangesResponse <string> .Row row, SyncLogItem logItem, Filter query, MyCouch.Serialization.ISerializer serializer)
        {
            if (changeSet.ChangedDocuments == null)
            {
                changeSet.ChangedDocuments = new List <SiaqodbDocument>();
            }
            CouchDBDocument co = serializer.Deserialize <CouchDBDocument>(row.IncludedDoc);

            if (co._id.StartsWith("_design/"))
            {
                return;
            }
            //check uploaded anchor- means cliet just uploaded this record and we should not return back
            if (logItem != null && logItem.KeyVersion != null && logItem.KeyVersion.ContainsKey(co._id) && logItem.KeyVersion[co._id] == co._rev)
            {
                return;
            }
            if (OutOfFilter(query, co))
            {
                return;
            }
            changeSet.ChangedDocuments.Add(Mapper.ToSiaqodbDocument(co));
        }
Beispiel #20
0
 /// <summary>
 /// Обработка поступившего объекта <see cref="SyncLogItem"/>.
 /// </summary>
 /// <param name="logItem"></param>
 public void HandleMessage(SyncLogItem logItem)
 {
     _syncLogItem = logItem;
     Process();
 }