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 static SubmitFeedResponse SendAmazonFeeds(IMarketplaceWebServiceClient feedService, IEnumerable<Product> amazonUpdateList, AmazonEnvelopeMessageType messageType, AmazonFeedType feedType, string AmazonMerchantId, string AmazonMarketplaceId, string AmazonServiceUrl, string AmazonAccessKeyId, string AmazonSecretAccessKey)
        {
            //var requestResponse = new List<string>();
            SubmitFeedResponse feedResponse = null;

            var amazonEnvelope = new AmazonEnvelope { Header = new Header { DocumentVersion = "1.01", MerchantIdentifier = AmazonMerchantId, }, MessageType = messageType };
            var updates = new List<AmazonEnvelopeMessage>();
            var counter = 1;
            foreach (var amazonUpdate in amazonUpdateList)
            {
                var curUpdate = new AmazonEnvelopeMessage { MessageID = counter.ToString(), Item = amazonUpdate };
                updates.Add(curUpdate);
                counter++;
            }

            //add all update products to envelope's message
            amazonEnvelope.Message = updates.ToArray();

            var serializer = new XmlSerializer(amazonEnvelope.GetType());

            var stringReader = new StringWriter();
            serializer.Serialize(stringReader, amazonEnvelope);
            var xmlResult = stringReader.ToString();

            using (MemoryStream feedStream = new MemoryStream())
            {
                serializer.Serialize(feedStream, amazonEnvelope);

                var feedRequest = new SubmitFeedRequest
                {
                    Merchant = AmazonMerchantId,
                    MarketplaceIdList = new IdList { Id = new List<string>(new[] { AmazonMarketplaceId }) },
                    FeedType = feedType.ToString(),
                    ContentType = new ContentType(MediaType.OctetStream),
                    FeedContent = feedStream
                };

                // Calculating the MD5 hash value exhausts the stream, and therefore we must either reset the
                // position, or create another stream for the calculation.
                feedRequest.ContentMD5 = MarketplaceWebServiceClient.CalculateContentMD5(feedRequest.FeedContent);

                //var feedService = new MockMarketplaceWebServiceClient();

                var uploadSuccess = false;
                var retryCount = 0;

                while (!uploadSuccess)
                {
                    try
                    {
                        feedResponse = feedService.SubmitFeed(feedRequest);
                        //var submissionId = feedResponse.SubmitFeedResult.FeedSubmissionInfo.FeedSubmissionId;
                        //requestResponse.Add(submissionId);
                        uploadSuccess = true;
                    }
                    catch (Exception ex)
                    {
                        //if sending not succeed after 3 attempts stop retrying
                        retryCount++;
                        if (retryCount == 3) break;

                        //pause sending for 3 minutes
                        Thread.Sleep(18000);
                        if (ex.ToString().ToLowerInvariant().Contains("request is throttled")) continue;
                        //requestResponse.Add(string.Format("ERROR: {0}", ex));
                    }
                }
            }

            return feedResponse;
        }
Example #3
0
        public static SubmitFeedResponse SendAmazonFeeds(IMarketplaceWebServiceClient feedService, IEnumerable <Product> amazonUpdateList, AmazonEnvelopeMessageType messageType, AmazonFeedType feedType, string AmazonMerchantId, string AmazonMarketplaceId, string AmazonServiceUrl, string AmazonAccessKeyId, string AmazonSecretAccessKey)
        {
            //var requestResponse = new List<string>();
            SubmitFeedResponse feedResponse = null;

            var amazonEnvelope = new AmazonEnvelope {
                Header = new Header {
                    DocumentVersion = "1.01", MerchantIdentifier = AmazonMerchantId,
                }, MessageType = messageType
            };
            var updates = new List <AmazonEnvelopeMessage>();
            var counter = 1;

            foreach (var amazonUpdate in amazonUpdateList)
            {
                var curUpdate = new AmazonEnvelopeMessage {
                    MessageID = counter.ToString(), Item = amazonUpdate
                };
                updates.Add(curUpdate);
                counter++;
            }

            //add all update products to envelope's message
            amazonEnvelope.Message = updates.ToArray();

            var serializer = new XmlSerializer(amazonEnvelope.GetType());

            var stringReader = new StringWriter();

            serializer.Serialize(stringReader, amazonEnvelope);
            var xmlResult = stringReader.ToString();

            using (MemoryStream feedStream = new MemoryStream())
            {
                serializer.Serialize(feedStream, amazonEnvelope);

                var feedRequest = new SubmitFeedRequest
                {
                    Merchant          = AmazonMerchantId,
                    MarketplaceIdList = new IdList {
                        Id = new List <string>(new[] { AmazonMarketplaceId })
                    },
                    FeedType    = feedType.ToString(),
                    ContentType = new ContentType(MediaType.OctetStream),
                    FeedContent = feedStream
                };

                // Calculating the MD5 hash value exhausts the stream, and therefore we must either reset the
                // position, or create another stream for the calculation.
                feedRequest.ContentMD5 = MarketplaceWebServiceClient.CalculateContentMD5(feedRequest.FeedContent);

                //var feedService = new MockMarketplaceWebServiceClient();

                var uploadSuccess = false;
                var retryCount    = 0;

                while (!uploadSuccess)
                {
                    try
                    {
                        feedResponse = feedService.SubmitFeed(feedRequest);
                        //var submissionId = feedResponse.SubmitFeedResult.FeedSubmissionInfo.FeedSubmissionId;
                        //requestResponse.Add(submissionId);
                        uploadSuccess = true;
                    }
                    catch (Exception ex)
                    {
                        //if sending not succeed after 3 attempts stop retrying
                        retryCount++;
                        if (retryCount == 3)
                        {
                            break;
                        }

                        //pause sending for 3 minutes
                        Thread.Sleep(18000);
                        if (ex.ToString().ToLowerInvariant().Contains("request is throttled"))
                        {
                            continue;
                        }
                        //requestResponse.Add(string.Format("ERROR: {0}", ex));
                    }
                }
            }

            return(feedResponse);
        }