public async Task <IActionResult> Get(string cacheKey, int index, [FromQuery] TraceQueryParameters location) { if (!ModelState.IsValid) { return(BadRequest()); } var res = await directionsCache.GetAsync(cacheKey); if (null != res && index < res.Itineraries.Length) { return(Ok(_userRouteTracer.TraceUserWithParticles(res.Itineraries[index], new TraceLocation { Accuracy = new TraceLocationAccuracy() { Confidence = location.AccuracyConfidence, Radius = location.AccuracyRadius }, Coordinate = new Coordinate(location.Lat, location.Lng), Timestamp = location.Timestamp }))); } else { return(NotFound()); } }
public async Task <Trace[]> FindTracesAsync(TraceQueryParameters query) { var traceIDs = await FindTraceIDsAsync(query); if (traceIDs.Length == 0) { return(Array.Empty <Trace>()); } return(await FindTracesAsync(traceIDs, query.StartTimeMin, query.StartTimeMax)); }
private async Task <string[]> FindTraceIDsAsync(TraceQueryParameters query) { string BuildQueryCondition() { var stringBuilder = new StringBuilder(); stringBuilder.Append(" { \"match\": { \"process.serviceName\": \"" + query.ServiceName + "\" }}"); if (!string.IsNullOrWhiteSpace(query.OperationName)) { stringBuilder.AppendLine(","); stringBuilder.Append(" { \"match\": { \"operationName\": \"" + query.OperationName + "\"}}"); } if (query.StartTimeMin.HasValue || query.StartTimeMax.HasValue) { stringBuilder.AppendLine(","); stringBuilder.AppendLine(" {"); stringBuilder.AppendLine(" \"range\": {"); stringBuilder.AppendLine(" \"startTime\": {"); if (query.StartTimeMin.HasValue) { stringBuilder.AppendLine(" \"gte\": " + query.StartTimeMin); } if (query.StartTimeMax.HasValue) { stringBuilder.AppendLine(" ,\"lte\": " + query.StartTimeMax); } stringBuilder.AppendLine(" }"); stringBuilder.AppendLine(" }"); stringBuilder.Append(" }"); } if (query.DurationMin.HasValue || query.DurationMax.HasValue) { stringBuilder.AppendLine(","); stringBuilder.AppendLine(" {"); stringBuilder.AppendLine(" \"range\": {"); stringBuilder.AppendLine(" \"duration\": {"); if (query.DurationMin.HasValue) { stringBuilder.AppendLine(" \"gte\": " + query.DurationMin); } if (query.DurationMax.HasValue) { stringBuilder.AppendLine(" ,\"lte\": " + query.DurationMax); } stringBuilder.AppendLine(" }"); stringBuilder.AppendLine(" }"); stringBuilder.Append(" }"); } if (query.Tags?.Any() ?? false) { foreach (var(key, value) in query.Tags) { stringBuilder.AppendLine(","); stringBuilder.AppendLine(" {"); stringBuilder.AppendLine("\"bool\": {"); stringBuilder.AppendLine(" \"should\": ["); stringBuilder.AppendLine(" { \"nested\" : {"); stringBuilder.AppendLine(" \"path\" : \"tags\","); stringBuilder.AppendLine(" \"query\" : {"); stringBuilder.AppendLine(" \"bool\" : {"); stringBuilder.AppendLine(" \"must\" : ["); stringBuilder.AppendLine(" { \"match\" : {\"tags.key\" : \"" + key + "\"} },"); stringBuilder.AppendLine(" { \"match\" : {\"tags.value\" : \"" + value + "\"} }"); stringBuilder.AppendLine(" ]"); stringBuilder.AppendLine(" }}}},"); stringBuilder.AppendLine(" { \"nested\" : {"); stringBuilder.AppendLine(" \"path\" : \"process.tags\","); stringBuilder.AppendLine(" \"query\" : {"); stringBuilder.AppendLine(" \"bool\" : {"); stringBuilder.AppendLine(" \"must\" : ["); stringBuilder.AppendLine(" { \"match\" : {\"tags.key\" : \"" + key + "\"} },"); stringBuilder.AppendLine( " { \"match\" : {\"tags.value\" : \"" + value + "\"} }"); stringBuilder.AppendLine(" ]"); stringBuilder.AppendLine(" }}}},"); stringBuilder.AppendLine(" { \"nested\" : {"); stringBuilder.AppendLine(" \"path\" : \"logs.fields\","); stringBuilder.AppendLine(" \"query\" : {"); stringBuilder.AppendLine(" \"bool\" : {"); stringBuilder.AppendLine(" \"must\" : ["); stringBuilder.AppendLine(" { \"match\" : {\"tags.key\" : \"" + key + "\"} },"); stringBuilder.AppendLine( " { \"match\" : {\"tags.value\" : \"" + value + "\"} }"); stringBuilder.AppendLine(" ]"); stringBuilder.Append(" }}}}"); } stringBuilder.AppendLine(" ]"); stringBuilder.AppendLine(" }"); stringBuilder.Append(" }"); } return(stringBuilder.ToString()); } var sbBuilder = new StringBuilder(); sbBuilder.AppendLine("{"); sbBuilder.AppendLine(" \"size\": 0,"); sbBuilder.AppendLine(" \"query\": {"); sbBuilder.AppendLine(" \"bool\": {"); sbBuilder.AppendLine(" \"must\": ["); sbBuilder.AppendLine(BuildQueryCondition()); sbBuilder.AppendLine(" ]"); sbBuilder.AppendLine(" }"); sbBuilder.AppendLine(" },"); sbBuilder.AppendLine("\"sort\": [{ \"startTime\": { \"order\": \"desc\" }}],"); sbBuilder.AppendLine( " \"aggs\": { \"traceIDs\": { \"terms\" : {\"size\": " + query.NumTraces + ",\"field\": \"traceID.keyword\" }}}"); sbBuilder.AppendLine("}"); var client = _httpClientFactory.CreateClient(); var request = sbBuilder.ToString(); var httpResponseMessage = await client.PostAsync($"{_options.URL}/{ElasticsearchStorageConstants.SpanIndexName}/_search", new StringContent(request, Encoding.UTF8, "application/json")); if (httpResponseMessage.StatusCode == HttpStatusCode.NotFound) { return(Array.Empty <string>()); } var response = await httpResponseMessage.Content.ReadAsStringAsync(); var result = response.FromJson <SearchResponse <object> >(); return(result.Aggregations["traceIDs"].Buckets.Select(b => b.Key).ToArray()); }