public static async void NonSuccessfulHttpRequestThrows() { var client = Substitute.For<IElasticsearchClient>(); client.SearchAsync<string>( "_all", "docType", @"{""timeout"":""10s""}", Arg.Any<Func<SearchRequestParameters, SearchRequestParameters>>()) .Returns(Task.FromResult(ElasticsearchResponse<string>.Create( new ConnectionConfiguration(), 404, "_search", "_all", new byte[0]))); var localConnection = new ElasticNetConnection(client); var request = new SearchRequest { DocumentType = "docType" }; var formatter = new SearchRequestFormatter(localConnection, mapping, request); var ex = await Record.ExceptionAsync(() => localConnection.SearchAsync( formatter.Body, request, CancellationToken.None, log)); Assert.IsType<HttpRequestException>(ex); Assert.Equal("Response status code does not indicate success: 404 (Not Found).", ex.Message); }
public void BodyContainsFromWhenSpecified() { const int expectedFrom = 1024; var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", From = expectedFrom }); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("from"); Assert.Equal(expectedFrom, result); }
public void BodyContainsMinScoreWhenSpecified() { var searchRequest = new SearchRequest { MinScore = 1.3 }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, searchRequest); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("min_score"); Assert.Equal(searchRequest.MinScore.ToString(), result); }
public void BodyContainsStatisticalFacet() { var expectedFacet = new StatisticalFacet("TotalSales", "OrderTotal"); var searchRequest = new SearchRequest { Facets = new List<IFacet>(new[] { expectedFacet }) }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, searchRequest); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("facets", expectedFacet.Name, expectedFacet.Type, "field"); Assert.Equal(expectedFacet.Fields[0], result.ToString()); }
public void BodyContainsQueryString() { const string expectedQuery = "this is my query string"; var queryString = new QueryStringCriteria(expectedQuery); var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Query = queryString }); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("query", "query_string", "query"); Assert.Equal(expectedQuery, result.ToString()); }
public void BodyContainsFieldSelections() { var expectedFields = new List<string> { "first", "second", "third" }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Fields = expectedFields }); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("fields"); foreach (var field in expectedFields) Assert.Contains(field, result); }
public void BodyContainsFilterExists() { const string expectedFieldName = "fieldShouldExist"; var existsCriteria = new ExistsCriteria(expectedFieldName); var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Filter = existsCriteria }); var body = JObject.Parse(formatter.Body); var field = body.TraverseWithAssert("query", "filtered", "filter", "exists", "field"); Assert.Equal(expectedFieldName, field); }
public void BodyContainsBoolMustQuery() { var rangeCriteria = new RangeCriteria("ranged", memberInfo, RangeComparison.GreaterThanOrEqual, 88); var boolMust = new BoolCriteria(new[] { rangeCriteria }, null, null); var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Query = boolMust }); var body = JObject.Parse(formatter.Body); var mustItems = body.TraverseWithAssert("query", "bool", "must"); Assert.Equal(1, mustItems.Count()); mustItems[0].TraverseWithAssert("range"); }
public void BodyContainsFilterTerm() { var termCriteria = TermsCriteria.Build(TermsExecutionMode.@bool, "term1", memberInfo, "singlecriteria"); var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Filter = termCriteria }); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("query", "filtered", "filter", "term"); Assert.Equal(1, result.Count()); Assert.Equal("!!! singlecriteria !!!", result[termCriteria.Field].ToString()); Assert.Null(result["execution"]); // Only applicable to "terms" filters }
public void BodyContainsTermsFacetWithNoSizeWhenNotSpecified() { var expectedFacet = new TermsFacet("Totals", null, "OrderTotal"); var searchRequest = new SearchRequest { Facets = new List<IFacet>(new[] { expectedFacet }) }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, searchRequest); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("facets", expectedFacet.Name, expectedFacet.Type); Assert.False(result.Contains("size")); }
public void BodyContainsFilterFacet() { var expectedFilter = new ExistsCriteria("IsLocal"); var expectedFacet = new FilterFacet("LocalSales", expectedFilter); var searchRequest = new SearchRequest { Facets = new List<IFacet>(new[] { expectedFacet }) }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, searchRequest); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("facets", expectedFacet.Name, expectedFacet.Type, expectedFilter.Name, "field"); Assert.Equal(expectedFilter.Field, result.ToString()); }
public void BodyContainsQueryStringWithFields() { const string expectedQuery = "this is my query string"; var expectedFields = new[] { "green", "brown", "yellow" }; var queryString = new QueryStringCriteria(expectedQuery, expectedFields); var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Query = queryString }); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("query", "query_string"); Assert.Equal(expectedQuery, result.TraverseWithAssert("query").ToString()); Assert.Equal(expectedFields, result.TraverseWithAssert("fields").Select(f => f.ToString()).ToArray()); }
public void BodyContainsFilterTerms() { var termCriteria = TermsCriteria.Build("term1", memberInfo, "criteria1", "criteria2"); var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Filter = termCriteria }); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("query", "filtered", "filter", "terms"); var actualTerms = result.TraverseWithAssert(termCriteria.Field); foreach (var criteria in termCriteria.Values) Assert.Contains("!!! " + criteria + " !!!", actualTerms.Select(t => t.ToString()).ToArray()); Assert.Null(result["execution"]); }
public static async void SearchAsyncCapturesRequestInfoOnFailure() { var spyLog = new SpyLog(); var brokenConnection = new ElasticConnection(new Uri("http://localhost:12"), index: "MyIndex"); var processor = new ElasticRequestProcessor(brokenConnection, mapping, spyLog, new RetryPolicy(spyLog, 100, 1)); var searchRequest = new SearchRequest { DocumentType = "docType" }; var formatter = new SearchRequestFormatter(brokenConnection, mapping, searchRequest); var ex = await Record.ExceptionAsync(() => processor.SearchAsync(searchRequest, CancellationToken.None)); Assert.IsType<RetryFailedException>(ex); var retryLogEntry = Assert.Single(spyLog.Entries, s => s.AdditionalInfo.ContainsKey("category") && s.AdditionalInfo["category"].Equals("retry")); Assert.Equal("MyIndex", retryLogEntry.AdditionalInfo["index"]); Assert.Equal(brokenConnection.GetSearchUri(searchRequest), retryLogEntry.AdditionalInfo["uri"]); Assert.Equal(formatter.Body, retryLogEntry.AdditionalInfo["query"]); }
public void BodyContainsFilterFacetAndedWithRequestFilter() { var expectedFacet = new FilterFacet("LocalSales", new ExistsCriteria("IsLocal")); var searchRequest = new SearchRequest { Filter = new MissingCriteria("Country"), Query = new PrefixCriteria("Field", "Prefix"), Facets = new List<IFacet>(new[] { expectedFacet }) }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, searchRequest); var body = JObject.Parse(formatter.Body); var andFilter = body.TraverseWithAssert("facets", expectedFacet.Name, expectedFacet.Type, "and"); Assert.Equal(2, andFilter.Count()); }
public void BodyContainsTermsFacet() { const int expectedSize = 1234; var expectedFacet = new TermsFacet("Totals", expectedSize, "OrderTotal", "OrderCost"); var searchRequest = new SearchRequest { Facets = new List<IFacet>(new[] { expectedFacet }) }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, searchRequest); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("facets", expectedFacet.Name, expectedFacet.Type); Assert.Equal(expectedSize.ToString(CultureInfo.InvariantCulture), result.TraverseWithAssert("size").ToString()); var actualFields = result.TraverseWithAssert("fields").ToArray(); foreach (var expectedField in expectedFacet.Fields) Assert.Contains(expectedField, actualFields); }
public void BodyContainsQueryRange() { var rangeCriteria = new RangeCriteria("someField", memberInfo, new[] { new RangeSpecificationCriteria(RangeComparison.LessThan, 100), new RangeSpecificationCriteria(RangeComparison.GreaterThan, 200) }); var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Query = rangeCriteria }); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("query", "range"); var actualRange = result.TraverseWithAssert(rangeCriteria.Field); Assert.Equal("!!! 100 !!!", actualRange["lt"]); Assert.Equal("!!! 200 !!!", actualRange["gt"]); }
public void BodyContainsMultipleFacets() { var expectedFacets = new List<IFacet> { new FilterFacet("LocalSales", new ExistsCriteria("IsLocal")), new StatisticalFacet("TotalSales", "OrderTotal") }; var searchRequest = new SearchRequest { Facets = expectedFacets }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, searchRequest); var body = JObject.Parse(formatter.Body); var facetResults = body.TraverseWithAssert("facets"); foreach (var expectedFacet in expectedFacets) facetResults.TraverseWithAssert(expectedFacet.Name, expectedFacet.Type); }
public Task<ElasticResponse> SearchAsync(SearchRequest searchRequest, CancellationToken cancellationToken) { var formatter = new SearchRequestFormatter(connection, mapping, searchRequest); return retryPolicy.ExecuteAsync( async token => await connection.SearchAsync( formatter.Body, searchRequest, token, log), (response, exception) => !cancellationToken.IsCancellationRequested && exception != null, (response, additionalInfo) => { additionalInfo["index"] = connection.Index; additionalInfo["uri"] = connection.GetSearchUri(searchRequest); additionalInfo["query"] = formatter.Body; }, cancellationToken); }
public void BodyContainsBoolShouldQuery() { var range1 = new RangeCriteria("range1", memberInfo, RangeComparison.GreaterThanOrEqual, 88); var range2 = new RangeCriteria("range2", memberInfo, RangeComparison.GreaterThanOrEqual, 88); var boolMust = new BoolCriteria(null, new[] { range1, range2 }, null); var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Query = boolMust }); var body = JObject.Parse(formatter.Body); var boolBody = body.TraverseWithAssert("query", "bool"); var minMatch = boolBody.TraverseWithAssert("minimum_should_match"); Assert.Equal(1, minMatch.Value<int>()); var mustNotItems = boolBody.TraverseWithAssert("should"); Assert.Equal(2, mustNotItems.Count()); mustNotItems[0].TraverseWithAssert("range"); }
public Task<ElasticResponse> SearchAsync(SearchRequest searchRequest, CancellationToken cancellationToken) { var formatter = new SearchRequestFormatter(connection, mapping, searchRequest); log.Debug(null, null, "Request: POST {0}", formatter.Uri); log.Debug(null, null, "Body:\n{0}", formatter.Body); return retryPolicy.ExecuteAsync( async token => { using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, formatter.Uri) { Content = new StringContent(formatter.Body) }) using (var response = await SendRequestAsync(connection.HttpClient, requestMessage, token)) using (var responseStream = await response.Content.ReadAsStreamAsync()) return ParseResponse(responseStream, log); }, (response, exception) => !cancellationToken.IsCancellationRequested && exception != null, (response, additionalInfo) => { additionalInfo["index"] = connection.Index; additionalInfo["uri"] = formatter.Uri; additionalInfo["query"] = formatter.Body; }, cancellationToken); }
public void BodyContainsMatchAllFilter() { var matchAllCriteria = MatchAllCriteria.Instance; var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Filter = matchAllCriteria }); var body = JObject.Parse(formatter.Body); body.TraverseWithAssert("query", "filtered", "filter", "match_all"); }
public void BodyContainsTermsFacetWithDefaultSizeFromConnection() { const int expectedSize = 678; var sizedConnection = new ElasticConnection(defaultConnection.Endpoint, options:new ElasticConnectionOptions { SearchSizeDefault = expectedSize }); var expectedFacet = new TermsFacet("Totals", null, "OrderTotal", "OrderCost"); var searchRequest = new SearchRequest { Facets = new List<IFacet>(new[] { expectedFacet }) }; var formatter = new SearchRequestFormatter(sizedConnection, mapping, searchRequest); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("facets", expectedFacet.Name, expectedFacet.Type); Assert.Equal(expectedSize.ToString(CultureInfo.InvariantCulture), result.TraverseWithAssert("size").ToString()); }
public static async Task ForcesBasicAuthorizationWhenProvidedWithUsernameAndPassword() { var messageHandler = new SpyMessageHandler(); var localConnection = new ElasticConnection(messageHandler, new Uri("http://localhost"), "myUser", "myPass"); var request = new SearchRequest { DocumentType = "docType" }; var formatter = new SearchRequestFormatter(localConnection, mapping, request); await localConnection.SearchAsync( formatter.Body, request, token, log); var auth = messageHandler.Request.Headers.Authorization; Assert.NotNull(auth); Assert.Equal("Basic", auth.Scheme); Assert.Equal("myUser:myPass", Encoding.ASCII.GetString(Convert.FromBase64String(auth.Parameter))); }
public static async Task NoAuthorizationWithEmptyUserName() { var messageHandler = new SpyMessageHandler(); var localConnection = new ElasticConnection(messageHandler, new Uri("http://localhost")); var request = new SearchRequest { DocumentType = "docType" }; var formatter = new SearchRequestFormatter(localConnection, mapping, request); await localConnection.SearchAsync( formatter.Body, request, token, log); Assert.Null(messageHandler.Request.Headers.Authorization); }
public static async void NonSuccessfulHttpRequestThrows() { var messageHandler = new SpyMessageHandler(); messageHandler.Response.StatusCode = HttpStatusCode.NotFound; var localConnection = new ElasticConnection(messageHandler, new Uri("http://localhost"), "myUser", "myPass"); var request = new SearchRequest { DocumentType = "docType" }; var formatter = new SearchRequestFormatter(localConnection, mapping, request); var ex = await Record.ExceptionAsync(() => localConnection.SearchAsync( formatter.Body, request, token, log)); Assert.IsType<HttpRequestException>(ex); Assert.Equal("Response status code does not indicate success: 404 (Not Found).", ex.Message); }
public void ParseThrowsInvalidOperationForUnknownCriteriaTypes() { var facets = new List<IFacet> { new FakeFacet() }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, new SearchRequest { DocumentType = "type1", Facets = facets }); Assert.Throws<InvalidOperationException>(() => JObject.Parse(formatter.Body)); }
public void BodyContainsTermsStatsFacet() { const int expectedSize = 101; var expectedFacet = new TermsStatsFacet("Name", "Key", "Value", expectedSize); var searchRequest = new SearchRequest { Facets = new List<IFacet>(new[] { expectedFacet }) }; var formatter = new SearchRequestFormatter(defaultConnection, mapping, searchRequest); var body = JObject.Parse(formatter.Body); var result = body.TraverseWithAssert("facets", expectedFacet.Name, expectedFacet.Type); Assert.Equal(expectedFacet.Key, result.TraverseWithAssert("key_field").ToString()); Assert.Equal(expectedFacet.Value, result.TraverseWithAssert("value_field").ToString()); Assert.Equal(expectedSize.ToString(CultureInfo.InvariantCulture), result.TraverseWithAssert("size").ToString()); }
public static async void SearchAsyncThrowsTaskCancelledExceptionWithAlreadyCancelledCancellationToken() { var spyLog = new SpyLog(); var localConnection = new ElasticConnection(new Uri("http://localhost"), index: "SearchIndex"); var request = new SearchRequest { DocumentType = "docType" }; var formatter = new SearchRequestFormatter(localConnection, mapping, request); var ex = await Record.ExceptionAsync(() => localConnection.SearchAsync( formatter.Body, request, new CancellationToken(true), spyLog)); Assert.IsType<TaskCanceledException>(ex); }
public static async Task LogsDebugMessagesDuringExecution() { var responseString = BuildResponseString(2, 1, 1, 0.3141, "testIndex", "testType", "testId"); var messageHandler = new SpyMessageHandler(); var spyLog = new SpyLog(); messageHandler.Response.Content = new StringContent(responseString); var localConnection = new ElasticConnection(messageHandler, new Uri("http://localhost"), "myUser", "myPass", index: "SearchIndex"); var request = new SearchRequest { DocumentType = "abc123", Size = 2112 }; var formatter = new SearchRequestFormatter(localConnection, mapping, request); await localConnection.SearchAsync( formatter.Body, request, token, spyLog); Assert.Equal(4, spyLog.Entries.Count); Assert.Equal(@"Request: POST http://localhost/SearchIndex/abc123/_search", spyLog.Entries[0].Message); Assert.Equal(@"Body:" + '\n' + @"{""size"":2112,""timeout"":""10s""}", spyLog.Entries[1].Message); Assert.True(new Regex(@"Response: 200 OK \(in \d+ms\)").Match(spyLog.Entries[2].Message).Success); Assert.True(new Regex(@"Deserialized \d+ bytes into 1 hits in \d+ms").Match(spyLog.Entries[3].Message).Success); }