public IPusher CreatePusher(IIndexModel model) { if (model == null) { return(null); } using (var connectionRepository = ResolverFactory.Resolve <ConnectionRepository>()) using (var entityRepository = ResolverFactory.Resolve <EntityRepository>()) { var destinationConnection = connectionRepository.GetById(model.DestinationConnectionId.ToString()); IPusher result = null; if (model.EntityType == EntityType.Attribute) { var attrModel = model as AttributeModel; var entityModel = entityRepository.GetById(attrModel.EntityId.ToString()); result = pushers .Where(p => typeof(IAttributePusher).IsAssignableFrom(p.GetType())) .Select(p => p as IAttributePusher) .FirstOrDefault(p => p.IsImplemented(model.DestinationProcessorId, entityModel.DestinationProcessorId, destinationConnection.ProviderId)); } else { result = pushers .Where(p => typeof(IEntityPusher).IsAssignableFrom(p.GetType())) .Select(p => p as IEntityPusher) .FirstOrDefault(p => p.IsImplemented(model.DestinationProcessorId, destinationConnection.ProviderId)); } var options = entityRepository.LoadOptions(model.Id.ToString(), model.EntityType) .Select(o => new OptionItem { Name = o.Key, Value = o.Value }); result.SetIndex(model); result.SetOptions(options); return(result); } }
public async Task <PushState> PushItem(IndexItemModel item) { Report($@" --------------------------------------------------------------------------------- Begin synchronizing item {JsonConvert.SerializeObject(item, Formatting.Indented)}..."); _pusher.SetIndex(_indexerModel); _pusher.SetItem(item); var result = await Task.Run(() => { try { entityRepository.BeginTransaction(); attributeRepository.BeginTransaction(); messageRepository.BeginTransaction(); var pushState = PushState.Success; var destinationId = item.GetDestinationId(); if (!string.IsNullOrWhiteSpace(destinationId)) { if (item.HasState(ItemState.Removed)) { _pusher.Remove(); } else { _pusher.Update(); } } else { destinationId = _pusher.GetDestinationId(); if (!string.IsNullOrWhiteSpace(destinationId)) { if (item.HasState(ItemState.Removed)) { _pusher.Remove(destinationId); } else { _pusher.Update(destinationId); } } else // still cannot find a destinationId, which means the entity/attribute does not exists { pushState = _pusher.Create(out destinationId); } } if (!string.IsNullOrWhiteSpace(destinationId) && (pushState & PushState.Success) > 0) { entityRepository.UpdateItemDestinationId(_indexerModel, item.GetSourceId(), destinationId); // Detect dependencies that depends on "Synced" step UpdateDependencies(item, destinationId); } else { // Signal to tell that the item is success or not entityRepository.Retry(_indexerModel, item.GetId(), pushState); } entityRepository.Commit(); attributeRepository.Commit(); return(pushState); } catch { entityRepository.RollBack(); attributeRepository.RollBack(); // Update invalid item // Increate retry count // Next time when queue items, it will be put behind because of the retry count entityRepository.Retry(_indexerModel, item.GetId(), PushState.Failed); throw; } finally { Report($@" Ended synchronizing... --------------------------------------------------------------------------------- "); } }); return(result); }
public override async Task Invoke(IStepExecutionContext context = null) { var executeAt = DateTime.Now.ToUnixTimestamp(); var firstQueuedItem = entityRepository.GetCurrentQueuedItems(); if (firstQueuedItem == null) { return; } IIndexModel indexModel = null; IndexItemModel itemModel = null; IIndexer indexer = null; IPusher pusher = null; IEnumerable <OptionItem> options = null; if (firstQueuedItem.TargetEntityType == EntityType.Entity) { indexModel = entityRepository.GetById(firstQueuedItem.TargetEntityId.ToString()); options = entityRepository.LoadOptions(indexModel.Id.ToString()).Select(o => new OptionItem { Name = o.Key, Value = o.Value }); var sourceConnection = connectionRepository.GetById(indexModel.SourceConnectionId.ToString()); var destinationConnection = connectionRepository.GetById(indexModel.DestinationConnectionId.ToString()); indexer = entityIndexers.FirstOrDefault(i => i.IsImplemented(indexModel.SourceProcessorId, sourceConnection.ProviderId)); pusher = entityPushers.FirstOrDefault(p => p.IsImplemented(indexModel.DestinationProcessorId, destinationConnection.ProviderId)); } else { var attributeModel = attributeRepository.GetById(firstQueuedItem.TargetEntityId.ToString()); indexModel = attributeModel; var entityModel = entityRepository.GetById(attributeModel.EntityId.ToString()); options = attributeRepository.LoadOptions(attributeModel.Id.ToString()).Select(o => new OptionItem { Name = o.Key, Value = o.Value }); var sourceConnection = connectionRepository.GetById(attributeModel.SourceConnectionId.ToString()); var destinationConnection = connectionRepository.GetById(attributeModel.DestinationConnectionId.ToString()); indexer = attributeIndexers.FirstOrDefault(i => i.IsImplemented(attributeModel.SourceProcessorId, entityModel.SourceProcessorId, sourceConnection.ProviderId)); pusher = attributePushers.FirstOrDefault(p => p.IsImplemented(attributeModel.DestinationProcessorId, entityModel.DestinationProcessorId, destinationConnection.ProviderId)); } indexer.SetIndex(indexModel); indexer.SetOptions(options); pusher.SetIndex(indexModel); pusher.SetOptions(options); pusherManager.SetIndex(indexModel); pusherManager.OnReport(s => Logger.Information(s)); pusherManager.SetIndexer(indexer); pusherManager.SetPusher(pusher); try { itemModel = entityRepository.GetIndexedItemById(indexModel, firstQueuedItem.TargetItemId.ToString()); var pushState = await pusherManager.PushItem(itemModel); var queueItemStatus = firstQueuedItem.Status == PushState.None ? PushState.Success : firstQueuedItem.Status; var messageId = messageRepository.Create(new { Message = string.Join("\n", pusherManager.GetReportMessages()), CreatedAt = DateTime.Now.ToUnixTimestamp(), MessageType = MessageType.Information, Status = MessageStatus.None }); queueItemStatus = queueItemStatus & pushState; if ((pushState & PushState.Success) <= 0) { queueItemStatus = (queueItemStatus | PushState.Success) ^ (PushState.Success); } queueItemRepository.Update(firstQueuedItem.Id.ToString(), new { UpdatedAt = DateTime.Now.ToUnixTimestamp(), ExecuteAt = executeAt, ExecutedAt = DateTime.Now.ToUnixTimestamp(), MessageId = messageId, Status = queueItemStatus }); } catch (Exception ex) { var messages = $@"Queue item (Id: {firstQueuedItem.Id}) failed to run. Addtional information: ```{JsonConvert.SerializeObject(indexModel, Formatting.Indented)}``` Progress: ```{string.Join("\n - ", pusherManager.GetReportMessages())}``` Exception: ```{ex}```"; var messageId = messageRepository.Create(new { Message = messages, CreatedAt = DateTime.Now.ToUnixTimestamp(), MessageType = MessageType.Error, Status = MessageStatus.None }); queueItemRepository.Update(firstQueuedItem.Id.ToString(), new { UpdatedAt = DateTime.Now.ToUnixTimestamp(), ExecuteAt = executeAt, ExecutedAt = DateTime.Now.ToUnixTimestamp(), MessageId = messageId, Status = (firstQueuedItem.Status | PushState.UnexpectedError | PushState.Failed | PushState.Success) ^ PushState.Success, // remove success }); throw; } }