public void PurgeQueue(IFeedSubmissionEntryService feedSubmissionService) { var entriesToDelete = feedSubmissionService.GetAll().Where(rre => rre.AmazonRegion == _region && rre.MerchantId == _merchantId); feedSubmissionService.DeleteRange(entriesToDelete); feedSubmissionService.SaveChanges(); }
public void Setup() { _options = new EasyMwsOptions(); var propertiesContainer = new FeedSubmissionPropertiesContainer("testFeedContent", "testFeedType", false, new List <string>(MwsMarketplaceGroup.AmazonEurope().Select(m => m.Id))); var serializedPropertiesContainer = JsonConvert.SerializeObject(propertiesContainer); _feedSubmissionEntries = new List <FeedSubmissionEntry> { new FeedSubmissionEntry(serializedPropertiesContainer) { Id = 2 }, new FeedSubmissionEntry(serializedPropertiesContainer) { Id = 1, AmazonRegion = AmazonRegion.Europe, TargetHandlerId = "TargetHandlerId", TargetHandlerArgs = JsonConvert.SerializeObject(new Dictionary <string, object> { { "key1", "value1" } }), FeedType = propertiesContainer.FeedType, FeedSubmissionData = JsonConvert.SerializeObject(propertiesContainer) } }; _loggerMock = new Mock <IEasyMwsLogger>(); _feedSubmissionCallbackRepoMock = new Mock <IFeedSubmissionEntryRepository>(); _feedSubmissionCallbackRepoMock.Setup(x => x.GetAll()).Returns(_feedSubmissionEntries.AsQueryable()); _feedSubmissionEntryService = new FeedSubmissionEntryService(_feedSubmissionCallbackRepoMock.Object, _options, _loggerMock.Object); }
public void DownloadNextFeedSubmissionResultFromAmazon(IFeedSubmissionEntryService feedSubmissionService) { var nextFeedWithProcessingComplete = feedSubmissionService.GetNextFromQueueOfProcessingCompleteFeeds(_merchantId, _region); if (nextFeedWithProcessingComplete == null) { return; } _feedSubmissionProcessor.DownloadFeedSubmissionResultFromAmazon(feedSubmissionService, nextFeedWithProcessingComplete); }
public void SubmitNextFeedInQueueToAmazon(IFeedSubmissionEntryService feedSubmissionService) { var feedSubmission = feedSubmissionService.GetNextFromQueueOfFeedsToSubmit(_merchantId, _region); if (feedSubmission == null) { return; } _feedSubmissionProcessor.SubmitFeedToAmazon(feedSubmissionService, feedSubmission); }
public void RequestFeedSubmissionStatusesAllFromAmazon(IFeedSubmissionEntryService feedSubmissionService) { var allFeedSubmissions = feedSubmissionService.GetAllSubmittedFeedsFromQueue(_merchantId, _region).ToList(); const int batchSize = 20; var numberOfBatches = (allFeedSubmissions.Count + batchSize - 1) / batchSize; for (int batchNumber = 0; batchNumber < numberOfBatches; batchNumber++) { var nextBatchOfEntriesToProcess = allFeedSubmissions.Skip(batchSize * batchNumber).Take(batchSize).ToList(); RequestFeedSubmissionStatusesBatchFromAmazon(feedSubmissionService, nextBatchOfEntriesToProcess); } }
public void UnlockFeedSubmissionEntries(IFeedSubmissionEntryService feedSubmissionService, IEnumerable <string> feedSubmissionIds) { foreach (var submissionId in feedSubmissionIds) { var feedSubmissionEntry = feedSubmissionService.FirstOrDefault(fsc => fsc.FeedSubmissionId == submissionId); if (feedSubmissionEntry != null) { feedSubmissionService.Unlock(feedSubmissionEntry, "Unlocking multiple feed submission entries - amazon processing status update has been completed."); feedSubmissionService.Update(feedSubmissionEntry); } } feedSubmissionService.SaveChanges(); }
public void PollFeeds(IFeedSubmissionEntryService feedSubmissionService) { _logger.Debug("Executing polling action for feed requests."); _feedSubmissionProcessor.CleanUpFeedSubmissionQueue(feedSubmissionService); SubmitNextFeedInQueueToAmazon(feedSubmissionService); RequestFeedSubmissionStatusesAllFromAmazon(feedSubmissionService); DownloadNextFeedSubmissionResultFromAmazon(feedSubmissionService); PublishEventsForPreviouslySubmittedFeeds(feedSubmissionService); }
public void RequestFeedSubmissionStatusesFromAmazon(IFeedSubmissionEntryService feedSubmissionService) { var feedSubmissionIds = feedSubmissionService.GetIdsForSubmittedFeedsFromQueue(_merchantId, _region).ToList(); if (!feedSubmissionIds.Any()) { return; } var feedSubmissionResults = _feedSubmissionProcessor.RequestFeedSubmissionStatusesFromAmazon(feedSubmissionService, feedSubmissionIds, _merchantId); if (feedSubmissionResults != null) { _feedSubmissionProcessor.QueueFeedsAccordingToProcessingStatus(feedSubmissionService, feedSubmissionResults); } _feedSubmissionProcessor.UnlockFeedSubmissionEntries(feedSubmissionService, feedSubmissionIds); }
public void RequestFeedSubmissionStatusesBatchFromAmazon(IFeedSubmissionEntryService feedSubmissionService, List <FeedSubmissionEntry> feedSubmissionsBatch) { if (!feedSubmissionsBatch.Any()) { return; } feedSubmissionService.LockMultipleEntries(feedSubmissionsBatch, "Amazon status update has started"); var feedSubmissionIds = feedSubmissionsBatch.Select(_ => _.FeedSubmissionId); var feedSubmissionResults = _feedSubmissionProcessor.RequestFeedSubmissionStatusesFromAmazon(feedSubmissionService, feedSubmissionIds, _merchantId); if (feedSubmissionResults != null) { _feedSubmissionProcessor.QueueFeedsAccordingToProcessingStatus(feedSubmissionService, feedSubmissionResults); } feedSubmissionService.UnlockMultipleEntries(feedSubmissionsBatch, "Amazon status update has been completed"); }
public void QueueFeed(IFeedSubmissionEntryService feedSubmissionService, FeedSubmissionPropertiesContainer propertiesContainer, string targetEventId = null, Dictionary <string, object> targetEventArgs = null) { try { if (propertiesContainer == null) { throw new ArgumentNullException(); } var serializedPropertiesContainer = JsonConvert.SerializeObject(propertiesContainer); var feedSubmission = new FeedSubmissionEntry(serializedPropertiesContainer) { AmazonRegion = _region, MerchantId = _merchantId, LastSubmitted = DateTime.MinValue, DateCreated = DateTime.UtcNow, IsProcessingComplete = false, HasErrors = false, SubmissionErrorData = null, FeedSubmissionRetryCount = 0, FeedSubmissionId = null, FeedType = propertiesContainer.FeedType, TargetHandlerId = targetEventId, TargetHandlerArgs = targetEventArgs == null ? null : JsonConvert.SerializeObject(targetEventArgs), InstanceId = _options?.EventPublishingOptions?.RestrictInvocationToOriginatingInstance?.HashedInstanceId, Details = new FeedSubmissionDetails { FeedContent = ZipHelper.CreateArchiveFromContent(propertiesContainer.FeedContent) } }; feedSubmissionService.Unlock(feedSubmission, "Unlocking single feed submission entry - newly created, ready for processing."); feedSubmissionService.Create(feedSubmission); feedSubmissionService.SaveChanges(); _logger.Debug($"The following feed was queued for submission to Amazon {feedSubmission.EntryIdentityDescription}."); } catch (Exception e) { _logger.Error(e.Message, e); } }
private void PublishEventsForPreviouslySubmittedFeeds(IFeedSubmissionEntryService feedSubmissionService) { var previouslySubmittedFeeds = feedSubmissionService.GetAllFromQueueOfFeedsReadyForCallback(_merchantId, _region); foreach (var feedSubmissionEntry in previouslySubmittedFeeds) { try { var processingReportContent = ZipHelper.ExtractArchivedSingleFileToStream(feedSubmissionEntry.Details.FeedSubmissionReport); var feedType = feedSubmissionEntry.FeedType; var handlerId = feedSubmissionEntry.TargetHandlerId; var handledArgs = feedSubmissionEntry.TargetHandlerArgs == null ? null : new ReadOnlyDictionary <string, object>(JsonConvert.DeserializeObject <Dictionary <string, object> >(feedSubmissionEntry.TargetHandlerArgs)); var eventArgs = new FeedUploadedEventArgs(processingReportContent, feedType, handlerId, handledArgs); _logger.Debug($"Attempting publish FeedUploaded for the next submitted feed in queue : {feedSubmissionEntry.EntryIdentityDescription}"); OnFeedUploaded(eventArgs); feedSubmissionService.Delete(feedSubmissionEntry); _logger.Info($"Event publishing has succeeded for {feedSubmissionEntry.EntryIdentityDescription}."); } catch (SqlException e) { _logger.Error($"Event publishing failed for {feedSubmissionEntry.EntryIdentityDescription} due to an internal error '{e.Message}'. The event publishing will be retried at the next poll request", e); feedSubmissionService.Unlock(feedSubmissionEntry, "Unlocking single feed submission entry - an SQL exception occurred while trying to invoke callback."); feedSubmissionService.Update(feedSubmissionEntry); } catch (Exception e) { _logger.Error($"Event publishing failed for {feedSubmissionEntry.EntryIdentityDescription}. Current retry count is :{feedSubmissionEntry.FeedSubmissionRetryCount}. {e.Message}", e); feedSubmissionEntry.InvokeCallbackRetryCount++; feedSubmissionService.Unlock(feedSubmissionEntry, "Unlocking single feed submission entry - an exception occurred while trying to invoke callback."); feedSubmissionService.Update(feedSubmissionEntry); } } feedSubmissionService.SaveChanges(); }
public void SubmitFeedToAmazon(IFeedSubmissionEntryService feedSubmissionService, FeedSubmissionEntry feedSubmission) { void HandleSubmitFeedSuccess(SubmitFeedResponse response) { var requestId = response?.ResponseHeaderMetadata?.RequestId ?? "unknown"; var timestamp = response?.ResponseHeaderMetadata?.Timestamp ?? "unknown"; feedSubmission.FeedSubmissionId = response?.SubmitFeedResult?.FeedSubmissionInfo?.FeedSubmissionId; feedSubmission.FeedSubmissionRetryCount = 0; _logger.Info($"AmazonMWS feed submission has succeeded for {feedSubmission.EntryIdentityDescription}. FeedSubmissionId:'{feedSubmission.FeedSubmissionId}'.", new RequestInfo(timestamp, requestId)); } void HandleMissingFeedSubmissionId() { feedSubmission.FeedSubmissionRetryCount++; _logger.Warn($"SubmitFeed did not generate a FeedSubmissionId for {feedSubmission.EntryIdentityDescription}. Feed submission will be retried. FeedSubmissionRetryCount is now : {feedSubmission.FeedSubmissionRetryCount}."); } void HandleNonFatalOrGenericException(Exception e) { feedSubmission.FeedSubmissionRetryCount++; feedSubmission.LastSubmitted = DateTime.UtcNow; _logger.Warn($"AmazonMWS SubmitFeed failed for {feedSubmission.EntryIdentityDescription}. Feed submission will be retried. FeedSubmissionRetryCount is now : {feedSubmission.FeedSubmissionRetryCount}.", e); } void HandleFatalException(Exception e) { feedSubmissionService.Delete(feedSubmission); _logger.Error($"AmazonMWS SubmitFeed failed for {feedSubmission.EntryIdentityDescription}. The entry will now be removed from queue", e); } var missingInformationExceptionMessage = "Cannot submit queued feed to amazon due to missing feed submission information"; if (feedSubmission == null) { throw new ArgumentNullException($"{missingInformationExceptionMessage}: Feed submission entry is null"); } if (feedSubmission.FeedSubmissionData == null) { throw new ArgumentNullException($"{missingInformationExceptionMessage}: Feed submission data is null"); } var feedContentZip = feedSubmission.Details?.FeedContent; if (feedContentZip == null) { throw new ArgumentNullException($"{missingInformationExceptionMessage}: Feed content is missing"); } if (string.IsNullOrEmpty(feedSubmission?.FeedType)) { throw new ArgumentException($"{missingInformationExceptionMessage}: Feed type is missing"); } _logger.Debug($"Attempting to submit the next feed in queue to Amazon: {feedSubmission.EntryIdentityDescription}."); var feedSubmissionData = feedSubmission.GetPropertiesContainer(); using (var stream = ZipHelper.ExtractArchivedSingleFileToStream(feedContentZip)) { var submitFeedRequest = new SubmitFeedRequest { Merchant = feedSubmission.MerchantId, FeedType = feedSubmission.FeedType, FeedContent = stream, MarketplaceIdList = feedSubmissionData.MarketplaceIdList == null ? null : new IdList { Id = feedSubmissionData.MarketplaceIdList }, PurgeAndReplace = feedSubmissionData.PurgeAndReplace ?? false, ContentMD5 = MD5ChecksumHelper.ComputeHashForAmazon(stream), }; if (!string.IsNullOrEmpty(_mWSAuthToken)) { submitFeedRequest.MWSAuthToken = _mWSAuthToken; } try { feedSubmissionService.Unlock(feedSubmission, "Unlocking single feed submission entry - finished attempt to submit feed to amazon."); feedSubmissionService.Update(feedSubmission); var response = _marketplaceWebServiceClient.SubmitFeed(submitFeedRequest); feedSubmission.LastSubmitted = DateTime.UtcNow; if (string.IsNullOrEmpty(response?.SubmitFeedResult?.FeedSubmissionInfo?.FeedSubmissionId)) { HandleMissingFeedSubmissionId(); } else { HandleSubmitFeedSuccess(response); } } catch (MarketplaceWebServiceException e) when(e.StatusCode == HttpStatusCode.BadRequest && IsAmazonErrorCodeFatal(e.ErrorCode)) { HandleFatalException(e); } catch (MarketplaceWebServiceException e) when(IsAmazonErrorCodeNonFatal(e.ErrorCode)) { HandleNonFatalOrGenericException(e); } catch (Exception e) { HandleNonFatalOrGenericException(e); } finally { stream.Dispose(); feedSubmissionService.SaveChanges(); } } }
public void QueueFeedsAccordingToProcessingStatus(IFeedSubmissionEntryService feedSubmissionService, List <(string FeedSubmissionId, string FeedProcessingStatus)> feedProcessingStatuses)
public List <(string FeedSubmissionId, string FeedProcessingStatus)> RequestFeedSubmissionStatusesFromAmazon(IFeedSubmissionEntryService feedSubmissionService, IEnumerable <string> feedSubmissionIdList, string merchant) { List <(string FeedSubmissionId, string IsProcessingComplete)> GetProcessingStatusesPerSubmissionIdFromResponse(GetFeedSubmissionListResponse response) { var responseInfo = new List <(string FeedSubmissionId, string IsProcessingComplete)>(); foreach (var feedSubmissionInfo in response.GetFeedSubmissionListResult.FeedSubmissionInfo) { responseInfo.Add((feedSubmissionInfo.FeedSubmissionId, feedSubmissionInfo.FeedProcessingStatus)); } return(responseInfo); } _logger.Debug($"Attempting to request feed submission statuses for all feeds in queue."); var request = new GetFeedSubmissionListRequest() { FeedSubmissionIdList = new IdList(), Merchant = merchant }; request.FeedSubmissionIdList.Id.AddRange(feedSubmissionIdList); if (!string.IsNullOrEmpty(_mWSAuthToken)) { request.MWSAuthToken = _mWSAuthToken; } try { var response = _marketplaceWebServiceClient.GetFeedSubmissionList(request); var requestId = response?.ResponseHeaderMetadata?.RequestId ?? "unknown"; var timestamp = response?.ResponseHeaderMetadata?.Timestamp ?? "unknown"; _logger.Debug($"AmazonMWS request for feed submission statuses succeeded.", new RequestInfo(timestamp, requestId)); if (response?.GetFeedSubmissionListResult?.FeedSubmissionInfo != null) { return(GetProcessingStatusesPerSubmissionIdFromResponse(response)); } else { _logger.Warn("AmazonMWS GetFeedSubmissionList response does not contain any results. The operation will be executed again at the next poll request."); return(null); } } catch (MarketplaceWebServiceException e) { _logger.Warn($"AmazonMWS GetFeedSubmissionList failed! The operation will be executed again at the next poll request.", e); return(null); } catch (Exception e) { _logger.Warn($"AmazonMWS GetFeedSubmissionList failed! The operation will be executed again at the next poll request.", e); return(null); } }