private async Task <string> EnsureTestIndex(BingCommerceIngestion client) { var allIndexes = await client.GetAllIndexesAsync(TENANT_ID); foreach (var index in allIndexes.Indexes) { if (index.Name == TEST_INDEX_NAME) { return(index.Id); } } var field = new IndexField() { Name = "testField01234", Type = IndexFieldType.ProductId }; var newIndexReq = new Index() { Name = TEST_INDEX_NAME, Description = "Created with the csharp unit testing", Fields = new List <IndexField>() { field } }; var createResponse = await client.CreateIndexAsync(TENANT_ID, body : newIndexReq); return(createResponse.Indexes[0].Id); }
/// <summary> /// Initializes a new instance of the <see cref="SimpleBingCommercePusher"/> class. /// </summary> /// <param name="config">The pusher configurations object</param> /// <param name="checkpoint">The checkpoint to poll the data since if it's valid.</param> /// <param name="serializer">(Optional): Explicit serialier to be used.</param> public SimpleBingCommercePusher(BingCommerceConfig config, IDataCheckpoint checkpoint, IPushSerializer <IDictionary <string, object> > serializer = null) { var sdkClient = new BingCommerceIngestion(new TokenCredentials(config.AccessToken)); var logger = new RequestLogger(config.RequestLogLocation, config.RequestLog); this.config = config; this.client = new IngestionClient(sdkClient, config.TenantId, config.IndexId, config.RetryCount, logger); this.tracker = new StatusTracker(this.client, config.TrackingInterval, logger); this.taskManager = new TaskManager(config.MaxConcurrentRequests); this.checkpointAcceptor = new CheckpointAcceptor(checkpoint); this.Serializer = serializer ?? new FormatSerializer(config.PushFormat); log.Debug("Successfully created the Simple Bing Commerce Pusher with the provided access token."); }
public IngestionClient(BingCommerceIngestion client, string tenantid, string indexid, uint maxAttempts, RequestLogger logger) { Require.Instance.IsNotNull(client, nameof(client)) .IsNotNull(logger, nameof(logger)) .IsNotNull(tenantid, nameof(tenantid)) .IsNotNull(indexid, nameof(indexid)) .IsTrue(maxAttempts > 0, "max attempts cannot be zero or less."); this.clientWithRetry = new BingCommerceIngestionWithRetry(client, maxAttempts, 500); this.client = client; this.Tenantid = tenantid; this.Indexid = indexid; this.retryCount = maxAttempts; this.logger = logger; }
public async Task TestIngestionClient() { var attemptCount = 0; var failFor = 6; var interceptor = new TestDelegatingHandler((request) => { // Artificial response for the PushDataUpdate API. attemptCount++; if (failFor > 0) { failFor--; return(new HttpResponseMessage(System.Net.HttpStatusCode.GatewayTimeout)); } var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); response.Content = new StringContent("{}"); return(response); }); var ingestion = new BingCommerceIngestion(new TokenCredentials("test"), interceptor); var client = new IngestionClient(ingestion, "tenant", "index", 5, new RequestLogger(null, RequestLogLevel.None)); var result = await client.PushDataUpdateAsync("body"); Assert.IsNull(result); Assert.AreEqual(5, attemptCount); Assert.AreEqual(1, failFor); result = await client.PushDataUpdateAsync("body"); Assert.IsNotNull(result); Assert.AreEqual(7, attemptCount); Assert.AreEqual(0, failFor); }
public async Task TestStatusTracker() { var updateId = "123"; var failAfter = 2; AutoResetEvent signal = new AutoResetEvent(false); var interceptor = new TestDelegatingHandler((request) => { if (request.RequestUri.ToString().Contains("/status/")) { // Artificial response for the PushUpdateStatus request. PushUpdateStatusResponse status = new PushUpdateStatusResponse() { UpdateId = updateId, Status = (failAfter-- > 0) ? "InProgress" : "PartiallySucceeded", Records = new List <ResponseRecordStatus>() { new ResponseRecordStatus() { RecordId = "1", Status = "Succeeded" }, new ResponseRecordStatus() { RecordId = "2", Status = "Failed", ErrorMessage = "error message" } } }; var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); response.Content = new StringContent(JsonConvert.SerializeObject(status)); if (status.Status != "InProgress") { signal.Set(); } return(response); } else { // Artificial response for the GetIndex request. var index = new IndexResponse() { Indexes = new List <ResponseIndex>() { new ResponseIndex { Id = "index", Fields = new List <IndexField>() { new IndexField() { Name = "notid", Type = IndexFieldType.Title }, new IndexField() { Name = "myid", Type = IndexFieldType.ProductId }, new IndexField() { Name = "alsonotid", Type = IndexFieldType.Description } } } } }; var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); response.Content = new StringContent(JsonConvert.SerializeObject(index)); return(response); } }); try { var ingestion = new BingCommerceIngestion(new TokenCredentials("test"), interceptor); var logger = new RequestLogger(".\\log", RequestLogLevel.DeadletterOnly); var client = new IngestionClient(ingestion, "tenant", "index", 1, logger); var tracker = new StatusTracker(client, TimeSpan.FromSeconds(1), logger); tracker.Start(); tracker.Add(updateId, new List <Dictionary <string, object> >() { new Dictionary <string, object>() { { "myid", "1" }, { "notid", "something" }, { "stillnotid", "still something" } }, new Dictionary <string, object>() { { "myid", "2" }, { "notid", "something else" }, { "stillnotid", "still something else" } }, }); Assert.AreEqual(0, Directory.GetFiles(".\\log\\deadletter").Length, "Expecting no files to be in the deadletter directory"); signal.WaitOne(TimeSpan.FromSeconds(10)); // Adding an extra 2 seconds delay for two reasons: // 1. Make sure to give the tracker the chance to process the api response and logging the failure. // 2. Make sure that the failure would be processed only once (the next event would skip it). await Task.Delay(TimeSpan.FromSeconds(2)); Assert.AreEqual(1, Directory.GetFiles(".\\log\\deadletter").Length, "Expecting one file to be in the deadletter directory"); Assert.AreEqual(1, JArray.Parse(File.ReadAllText(Directory.EnumerateFiles(".\\log\\deadletter").First())).Count); } finally { Directory.Delete(".\\log", true); } }
private static async Task <string> EnsureIndex(BingCommerceIngestion client) { Console.WriteLine($"Trying to find the index with name: {INDEX_NAME}."); var allIndexes = await client.GetAllIndexesAsync(TENANT_ID); foreach (var index in allIndexes.Indexes) { if (index.Name == INDEX_NAME) { return(index.Id); } } Console.WriteLine("Index was not found, now creating one."); // Prepare the index fields var idField = new IndexField() { Name = "ProductId", Type = IndexFieldType.ProductId, Filterable = true, Retrievable = true }; var titleField = new IndexField() { Name = "ProductTitle", Type = IndexFieldType.Title, Filterable = true, Searchable = true }; var descriptionField = new IndexField() { Name = "ProductDescription", Type = IndexFieldType.Description, Filterable = true, Searchable = true }; var priceField = new IndexField() { Name = "ProductPrice", Type = IndexFieldType.Price, Filterable = true, Sortable = true }; var urlField = new IndexField() { Name = "ProductDetailsUrl", Type = IndexFieldType.Url, Retrievable = true }; var arbitraryTextField = new IndexField() { Name = "arbitraryText", Type = IndexFieldType.String, Searchable = true }; var arbitraryNumberField = new IndexField() { Name = "arbitraryNumber", Type = IndexFieldType.Number, Facetable = true }; // Create the request using the prepared fields var newIndexReq = new Index() { Name = INDEX_NAME, Description = "Created with dotnet sdk sample", Fields = { idField, titleField, descriptionField, priceField, urlField, arbitraryTextField, arbitraryNumberField } }; // Send the request, create the index var createResponse = await client.CreateIndexAsync(TENANT_ID, body : newIndexReq); return(createResponse.Indexes[0].Id); }
private static async Task <string> PushData(BingCommerceIngestion ingestionClient, string indexId, string content) { var pushResponse = await ingestionClient.PushDataUpdateAsync(content, TENANT_ID, indexId); return(pushResponse.UpdateId); }