Beispiel #1
0
        public async Task BatchQueryMissingCounterStillProducesGoodResponse()
        {
            var data = new BatchQueryRequest();

            data.Queries.Add(new BatchCounterQuery {
                CounterName = "Tacos", UserContext = "Tacos"
            });

            var response = await
                           this.httpClient.PostAsync(TestUtils.GetUri(this.server, RestCommands.BatchQueryCommand,
                                                                      string.Empty),
                                                     GetRequestPayload(data));

            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);

            using (var readerStream = new ReaderStream(await response.Content.ReadAsStreamAsync()))
            {
                var reader       = readerStream.CreateBondedCompactBinaryReader <BatchQueryResponse>();
                var responseData = reader.Deserialize();
                Assert.AreEqual(1, responseData.Responses.Count);

                var singleResponse =
                    (responseData.Responses as List <CounterQueryResponse>).Find(item => item.UserContext.Equals("Tacos"));
                Assert.IsNotNull(singleResponse);
                Assert.AreEqual((int)HttpStatusCode.NotFound, singleResponse.HttpResponseCode);
            }
        }
Beispiel #2
0
        public void AggregatorAggregatesCorrectlyWhenNoOverlaps()
        {
            var aCounter = new BatchCounterQuery {
                CounterName = "a", UserContext = "a"
            };
            var bCounter = new BatchCounterQuery {
                CounterName = "b", UserContext = "b"
            };

            var batchRequest = new BatchQueryRequest();

            batchRequest.Queries.Add(aCounter);
            batchRequest.Queries.Add(bCounter);

            var agg = new BatchResponseAggregator(batchRequest);

            var aOnlyResponse = new BatchQueryResponse
            {
                Responses      = { this.CreateHitCountResponse("a", 100) },
                RequestDetails =
                {
                    new RequestDetails
                    {
                        Server = new ServerInfo
                        {
                            Hostname = "something",
                            Port     = 42
                        },
                        HttpResponseCode = 200
                    }
                }
            };
            var bOnlyResponse = new BatchQueryResponse
            {
                Responses      = { this.CreateHitCountResponse("b", 200) },
                RequestDetails =
                {
                    new RequestDetails
                    {
                        Server = new ServerInfo
                        {
                            Hostname = "somewhere",
                            Port     = 42
                        },
                        HttpResponseCode = 200
                    }
                }
            };

            agg.AddResponse(aOnlyResponse);
            agg.AddResponse(bOnlyResponse);

            var finalResponse = agg.GetResponse();

            Assert.IsNotNull(finalResponse);
            Assert.AreEqual(2, finalResponse.RequestDetails.Count);
            Assert.AreEqual(2, finalResponse.Responses.Count);
            Assert.AreEqual(1, finalResponse.Responses.Count(x => x.UserContext.Equals("a") && x.Samples[0].HitCount == 100));
            Assert.AreEqual(1, finalResponse.Responses.Count(x => x.UserContext.Equals("b") && x.Samples[0].HitCount == 200));
        }
        /// <summary>
        /// Constructor that validates the query request and initializes internal state and fixes/cleans up the individual queries
        /// </summary>
        public BatchResponseAggregator(BatchQueryRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (request.Queries == null || request.Queries.Count == 0)
            {
                throw new ArgumentException("No queries provided", "request");
            }

            foreach (var counterRequest in request.Queries)
            {
                if (string.IsNullOrEmpty(counterRequest.UserContext))
                {
                    counterRequest.UserContext = Guid.NewGuid().ToString("D");
                }
                else if (this.requestMapping.ContainsKey(counterRequest.UserContext))
                {
                    throw new ArgumentException("Duplicate user context in request");
                }

                var counterAggregator = new CounterAggregator(counterRequest.QueryParameters);
                var shouldMergeSamples = DistributedQueryClient.ShouldMergeTimeBuckets(counterRequest.QueryParameters);

                counterRequest.QueryParameters = counterAggregator.ApplyPercentileCalculationAggregation(counterRequest.QueryParameters);
                this.requestMapping.Add(counterRequest.UserContext, new Tuple<bool, CounterAggregator>(shouldMergeSamples, counterAggregator));
            }
        }
        /// <summary>
        /// Constructor that validates the query request and initializes internal state and fixes/cleans up the individual queries
        /// </summary>
        public BatchResponseAggregator(BatchQueryRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (request.Queries == null || request.Queries.Count == 0)
            {
                throw new ArgumentException("No queries provided", "request");
            }

            foreach (var counterRequest in request.Queries)
            {
                if (string.IsNullOrEmpty(counterRequest.UserContext))
                {
                    counterRequest.UserContext = Guid.NewGuid().ToString("D");
                }
                else if (this.requestMapping.ContainsKey(counterRequest.UserContext))
                {
                    throw new ArgumentException("Duplicate user context in request");
                }

                var counterAggregator  = new CounterAggregator(counterRequest.QueryParameters);
                var shouldMergeSamples = DistributedQueryClient.ShouldMergeTimeBuckets(counterRequest.QueryParameters);

                counterRequest.QueryParameters = counterAggregator.ApplyPercentileCalculationAggregation(counterRequest.QueryParameters);
                this.requestMapping.Add(counterRequest.UserContext, new Tuple <bool, CounterAggregator>(shouldMergeSamples, counterAggregator));
            }
        }
        /// <summary>
        /// Perform a distributed batch query (proxies to the generic Execute method of this class)
        /// </summary>
        public async Task <BatchQueryResponse> BatchQuery(BatchQueryRequest request)
        {
            var aggregator = new BatchResponseAggregator(request);

            return(await this.Execute(request, RestCommands.BatchQueryCommand,
                                      aggregator.AddResponse,
                                      aggregator.GetResponse));
        }
Beispiel #6
0
 private static ByteArrayContent GetRequestPayload(BatchQueryRequest data)
 {
     using (var ms = new MemoryStream())
         using (var writerStream = new WriterStream(ms))
         {
             writerStream.CreateCompactBinaryWriter().Write(data);
             return(new ByteArrayContent(ms.GetBuffer()));
         }
 }
Beispiel #7
0
        public void AggregatorAggregatesOverlapCorrectly()
        {
            var aCounter = new BatchCounterQuery {
                CounterName = "a", UserContext = "a"
            };

            var batchRequest = new BatchQueryRequest();

            batchRequest.Queries.Add(aCounter);

            var agg = new BatchResponseAggregator(batchRequest);

            var oneResponse = new BatchQueryResponse
            {
                Responses      = { this.CreateHitCountResponse("a", 100) },
                RequestDetails =
                {
                    new RequestDetails
                    {
                        Server = new ServerInfo
                        {
                            Hostname = "something",
                            Port     = 42
                        },
                        HttpResponseCode = 200
                    }
                }
            };
            var twoResponse = new BatchQueryResponse
            {
                Responses      = { this.CreateHitCountResponse("a", 200) },
                RequestDetails =
                {
                    new RequestDetails
                    {
                        Server = new ServerInfo
                        {
                            Hostname = "somewhere",
                            Port     = 42
                        },
                        HttpResponseCode = 200
                    }
                }
            };

            agg.AddResponse(oneResponse);
            agg.AddResponse(twoResponse);

            var finalResponse = agg.GetResponse();

            Assert.IsNotNull(finalResponse);
            Assert.AreEqual(2, finalResponse.RequestDetails.Count);
            Assert.AreEqual(1, finalResponse.Responses.Count);
            Assert.AreEqual(300, finalResponse.Responses[0].Samples[0].HitCount);
        }
        public void AggregatorAggregatesCorrectlyWhenNoOverlaps()
        {
            var aCounter = new BatchCounterQuery { CounterName = "a", UserContext = "a" };
            var bCounter = new BatchCounterQuery { CounterName = "b", UserContext = "b" };

            var batchRequest = new BatchQueryRequest();
            batchRequest.Queries.Add(aCounter);
            batchRequest.Queries.Add(bCounter);

            var agg = new BatchResponseAggregator(batchRequest);

            var aOnlyResponse = new BatchQueryResponse
                                {
                                    Responses = {this.CreateHitCountResponse("a", 100)},
                                    RequestDetails =
                                    {
                                        new RequestDetails
                                        {
                                            Server = new ServerInfo
                                            {
                                                Hostname = "something",
                                                Port = 42
                                            },
                                            HttpResponseCode = 200
                                        }
                                    }
                                };
            var bOnlyResponse = new BatchQueryResponse
                                {
                                    Responses = {this.CreateHitCountResponse("b", 200)},
                                    RequestDetails =
                                    {
                                        new RequestDetails
                                        {
                                            Server = new ServerInfo
                                            {
                                                Hostname = "somewhere",
                                                Port = 42
                                            },
                                            HttpResponseCode = 200
                                        }
                                    }
                                };

            agg.AddResponse(aOnlyResponse);
            agg.AddResponse(bOnlyResponse);

            var finalResponse = agg.GetResponse();
            Assert.IsNotNull(finalResponse);
            Assert.AreEqual(2, finalResponse.RequestDetails.Count);
            Assert.AreEqual(2, finalResponse.Responses.Count);
            Assert.AreEqual(1, finalResponse.Responses.Count(x => x.UserContext.Equals("a") && x.Samples[0].HitCount == 100));
            Assert.AreEqual(1, finalResponse.Responses.Count(x => x.UserContext.Equals("b") && x.Samples[0].HitCount == 200));
        }
Beispiel #9
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="request"></param>
 /// <returns></returns>
 internal static string GetBatchQueryText(BatchQueryRequest request)
 {
     if (cache.TryGetValue(request, out var commandText) == false)
     {
         var fields = GetActualFields(request.Connection,
                                      request.Name,
                                      request.Fields,
                                      request.Transaction);
         commandText = GetBatchQueryTextInternal(request, fields);
         cache.TryAdd(request, commandText);
     }
     return(commandText);
 }
Beispiel #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="request"></param>
        /// <param name="fields"></param>
        /// <returns></returns>
        internal static string GetBatchQueryTextInternal(BatchQueryRequest request,
                                                         IEnumerable <Field> fields)
        {
            var statementBuilder = EnsureStatementBuilder(request.Connection, request.StatementBuilder);

            return(statementBuilder.CreateBatchQuery(new QueryBuilder(),
                                                     request.Name,
                                                     fields,
                                                     request.Page,
                                                     request.RowsPerBatch,
                                                     request.OrderBy,
                                                     request.Where,
                                                     request.Hints));
        }
        public void AggregatorFixesUpQueryParametersIfNeeded()
        {
            var counterQuery = new BatchCounterQuery();
            counterQuery.QueryParameters.Add("percentile", "50");
            
            var batchRequest = new BatchQueryRequest();
            batchRequest.Queries.Add(counterQuery);

            new BatchResponseAggregator(batchRequest);

            // percentile should have been removed to downstream requests
            Assert.IsFalse(counterQuery.QueryParameters.ContainsKey("percentile"));

            // user context should have been filled in as a guid
            Assert.IsNotNullOrEmpty(counterQuery.UserContext);
        }
Beispiel #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal static async Task <string> GetBatchQueryTextAsync(BatchQueryRequest request,
                                                                   CancellationToken cancellationToken = default)
        {
            if (cache.TryGetValue(request, out var commandText) == false)
            {
                var fields = await GetActualFieldsAsync(request.Connection,
                                                        request.Name,
                                                        request.Fields,
                                                        request.Transaction,
                                                        cancellationToken);

                commandText = GetBatchQueryTextInternal(request, fields);
                cache.TryAdd(request, commandText);
            }
            return(commandText);
        }
Beispiel #13
0
        /// <summary>
        /// Gets a command text from the cache for the <see cref="DbConnectionExtension.BatchQuery{TEntity}(IDbConnection, QueryGroup, int, int, IEnumerable{OrderField}, int?, IDbTransaction, ITrace, IStatementBuilder)"/> operation.
        /// </summary>
        /// <typeparam name="TEntity">The type of the target entity.</typeparam>
        /// <param name="request">The request object.</param>
        /// <returns>The cached command text.</returns>
        public static string GetBatchQueryText <TEntity>(BatchQueryRequest request)
            where TEntity : class
        {
            var commandText = (string)null;

            if (m_cache.TryGetValue(request, out commandText) == false)
            {
                var statementBuilder = EnsureStatementBuilder(request.Connection, request.StatementBuilder);
                commandText = statementBuilder.CreateBatchQuery(queryBuilder: new QueryBuilder <TEntity>(),
                                                                where : request.Where,
                                                                page: request.Page,
                                                                rowsPerBatch: request.RowsPerBatch,
                                                                orderBy: request.OrderBy);
                m_cache.TryAdd(request, commandText);
            }
            return(commandText);
        }
Beispiel #14
0
        public void AggregatorFixesUpQueryParametersIfNeeded()
        {
            var counterQuery = new BatchCounterQuery();

            counterQuery.QueryParameters.Add("percentile", "50");

            var batchRequest = new BatchQueryRequest();

            batchRequest.Queries.Add(counterQuery);

            new BatchResponseAggregator(batchRequest);

            // percentile should have been removed to downstream requests
            Assert.IsFalse(counterQuery.QueryParameters.ContainsKey("percentile"));

            // user context should have been filled in as a guid
            Assert.IsNotNullOrEmpty(counterQuery.UserContext);
        }
Beispiel #15
0
        /// <summary>
        /// Gets a command text from the cache for the batch query operation.
        /// </summary>
        /// <param name="request">The request object.</param>
        /// <returns>The cached command text.</returns>
        internal static string GetBatchQueryText(BatchQueryRequest request)
        {
            var commandText = (string)null;

            if (m_cache.TryGetValue(request, out commandText) == false)
            {
                var statementBuilder = EnsureStatementBuilder(request.Connection, request.StatementBuilder);
                var fields           = GetActualFields(request.Connection, request.Name, request.Fields);
                commandText = statementBuilder.CreateBatchQuery(new QueryBuilder(),
                                                                request.Name,
                                                                fields,
                                                                request.Page,
                                                                request.RowsPerBatch,
                                                                request.OrderBy,
                                                                request.Where);
                m_cache.TryAdd(request, commandText);
            }
            return(commandText);
        }
Beispiel #16
0
 /// <summary>
 /// Helper to create a final response based on request config
 /// </summary>
 private BatchQueryResponse CreateQueryResponse(BatchQueryRequest request, IEnumerable <CounterQueryResponse> responses)
 {
     return(new BatchQueryResponse
     {
         RequestDetails = request.IncludeRequestDiagnostics
                                     ? new List <RequestDetails>
         {
             new RequestDetails
             {
                 Server = this.server.ServerInfo,
                 HttpResponseCode = 200,
                 IsAggregator = request.Sources != null && request.Sources.Count > 0,
                 Status = RequestStatus.Success
             }
         }
                                     : new List <RequestDetails>(),
         Responses = responses.ToList()
     });
 }
Beispiel #17
0
        public void AggregatorIgnoresUnknownCounterInResponse()
        {
            var aCounter = new BatchCounterQuery {
                CounterName = "a", UserContext = "a"
            };

            var batchRequest = new BatchQueryRequest();

            batchRequest.Queries.Add(aCounter);

            var agg = new BatchResponseAggregator(batchRequest);

            var oneResponse = new BatchQueryResponse
            {
                Responses      = { this.CreateHitCountResponse("i am a key tree", 100) },
                RequestDetails =
                {
                    new RequestDetails
                    {
                        Server = new ServerInfo
                        {
                            Hostname = "something",
                        },
                        HttpResponseCode = 200
                    }
                }
            };

            agg.AddResponse(oneResponse);

            var finalResponse = agg.GetResponse();

            Assert.IsNotNull(finalResponse);
            Assert.AreEqual(1, finalResponse.Responses.Count);
            Assert.AreEqual(0, finalResponse.Responses[0].Samples.Count);
        }
 private static ByteArrayContent GetRequestPayload(BatchQueryRequest data)
 {
     using (var ms = new MemoryStream())
     using (var writerStream = new WriterStream(ms))
     {
         writerStream.CreateCompactBinaryWriter().Write(data);
         return new ByteArrayContent(ms.GetBuffer());
     }
 }
        public async void BatchQueryAggregatesFanoutCorrectly()
        {
            const string tacoTruck = "/Tacos";
            const string competingBurritoTruck = "/Burritos";

            var dimensionSet = new DimensionSet(new HashSet<Dimension>());
            var counter = await this.dataManager.CreateHitCounter(tacoTruck, dimensionSet);

            // locally store dim1
            counter.Increment(100, new DimensionSpecification());
            this.dataManager.Flush();

            var data = new BatchQueryRequest();
            data.Queries.Add(new BatchCounterQuery { CounterName = tacoTruck, UserContext = tacoTruck});
            data.Queries.Add(new BatchCounterQuery
                             {
                                 CounterName = competingBurritoTruck,
                                 UserContext = competingBurritoTruck
                             });
            data.Sources.Add(new ServerInfo {Hostname = "a", Port = 42});
            data.Sources.Add(new ServerInfo {Hostname = "b", Port = 42});

            var sampleStart = DateTime.Now;
            var sampleEnd = sampleStart.AddHours(1);

            // remotely return 100 for dim2 only
            DistributedQueryClient.RequesterFactory = new MockHttpRequesterFactory(message =>
                    {
                        var batchResponse = new BatchQueryResponse();
                        batchResponse.RequestDetails.Add(new RequestDetails
                                                         {
                                                             Server =
                                                                 new ServerInfo
                                                                 {
                                                                     Hostname = "bob",
                                                                     Port = 42
                                                                 },
                                                             HttpResponseCode = 200
                                                         });
                        var counterResponse = new CounterQueryResponse
                                              {
                                                  HttpResponseCode = 200, 
                                                  UserContext = competingBurritoTruck,
                                                  Samples = new List<DataSample> {
                                                    new DataSample { HitCount = 100, Dimensions = new Dictionary<string, string>(), SampleType = DataSampleType.HitCount, StartTime = sampleStart.ToMillisecondTimestamp(), EndTime = sampleEnd.ToMillisecondTimestamp() }
                                                    }
                                               };
                        batchResponse.Responses.Add(counterResponse);
                        return MockDataFactory.CreateResponse(batchResponse);
                    });
            
            var response = await
                           this.httpClient.PostAsync(TestUtils.GetUri(this.server, RestCommands.BatchQueryCommand,
                                                                      string.Empty),
                                                     GetRequestPayload(data));
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
            var responseData = await MockDataFactory.ReadResponseData<BatchQueryResponse>(response);
            Assert.IsNotNull(responseData);
            Assert.AreEqual(3, responseData.RequestDetails.Count);
            Assert.IsTrue(responseData.RequestDetails.All(x => x.HttpResponseCode == 200));
            Assert.AreEqual(2, responseData.Responses.Count);
            Assert.AreEqual(1, responseData.Responses.Count(x => x.UserContext.Equals(tacoTruck) && x.Samples[0].HitCount == 100));
            Assert.AreEqual(1, responseData.Responses.Count(x => x.UserContext.Equals(competingBurritoTruck) && x.Samples[0].HitCount == 200));
        }
        public async Task BatchQueryMultipleQueriesForSameCounterWithDifferentParametersWorksFine()
        {
            // Fill up the taco truck
            var dimensionSet = new DimensionSet(new HashSet<Dimension> {new Dimension("Filling")});
            var counter = await this.dataManager.CreateHitCounter("/Tacos", dimensionSet);

            var chickenTacos = new DimensionSpecification {{"Filling", "Chicken"}};
            var beefTacos = new DimensionSpecification {{"Filling", "Beef"}};
            var veggieTacos = new DimensionSpecification {{"Filling", "TOFU"}};
            var baconTacos = new DimensionSpecification {{"Filling", "bacon"}};

            counter.Increment(100, chickenTacos);
            counter.Increment(200, beefTacos);
            counter.Increment(300, veggieTacos);
            this.dataManager.Flush();

            var data = new BatchQueryRequest();
            data.Queries.Add(new BatchCounterQuery {CounterName = "/Tacos", UserContext = "TotalTacos"});
            data.Queries.Add(new BatchCounterQuery
                             {
                                 CounterName = "/Tacos",
                                 UserContext = "CluckCluck",
                                 QueryParameters = chickenTacos.Data
                             });
            data.Queries.Add(new BatchCounterQuery
                             {
                                 CounterName = "/Tacos",
                                 UserContext = "BACON!",
                                 QueryParameters = baconTacos.Data
                             });

            var response = await
                           this.httpClient.PostAsync(
                                                     TestUtils.GetUri(this.server,
                                                                      RestCommands.BatchQueryCommand,
                                                                      string.Empty),
                                                     GetRequestPayload(data));
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);

            using (var readerStream = new ReaderStream(await response.Content.ReadAsStreamAsync()))
            {
                var reader = readerStream.CreateBondedCompactBinaryReader<BatchQueryResponse>();
                var responseData = reader.Deserialize();
                Assert.AreEqual(3, responseData.Responses.Count);

                // unfiltered should have 100+200+300 hitcount
                VerifyHitCounter(responseData, "TotalTacos", 600);

                //only 100 chicken tacos
                VerifyHitCounter(responseData, "CluckCluck", 100);

                //sadly, there is no bacon...
                VerifyHitCounter(responseData, "BACON!", -1);
            }
        }
        public async Task BatchQueryMissingCounterStillProducesGoodResponse()
        {
            var data = new BatchQueryRequest();
            data.Queries.Add(new BatchCounterQuery {CounterName = "Tacos", UserContext = "Tacos"});

            var response = await
                           this.httpClient.PostAsync(TestUtils.GetUri(this.server, RestCommands.BatchQueryCommand,
                                                                      string.Empty),
                                                     GetRequestPayload(data));
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);

            using (var readerStream = new ReaderStream(await response.Content.ReadAsStreamAsync()))
            {
                var reader = readerStream.CreateBondedCompactBinaryReader<BatchQueryResponse>();
                var responseData = reader.Deserialize();
                Assert.AreEqual(1, responseData.Responses.Count);

                var singleResponse =
                    (responseData.Responses as List<CounterQueryResponse>).Find(item => item.UserContext.Equals("Tacos"));
                Assert.IsNotNull(singleResponse);
                Assert.AreEqual((int)HttpStatusCode.NotFound, singleResponse.HttpResponseCode);
            }
        }
Beispiel #22
0
        /// <summary>
        /// Execute the N queries against the CounterQueryHandler. Aggregate the responses in a single response object
        /// </summary>
        private async Task <IEnumerable <CounterQueryResponse> > ProcessBatchQueryRequest(BatchQueryRequest request)
        {
            Events.Write.BeginProcessingQuery("BatchQuery", "batch");
            var tasks = new List <Task <CounterQueryResponse> >(request.Queries.Count);

            tasks.AddRange(request.Queries.Select(RunCounterQuery));

            await Task.WhenAll(tasks);

            Events.Write.EndProcessingQuery("BatchQuery", "batch", 200);

            return(tasks.Select(t => t.Result));
        }
        public void AggregatorIgnoresUnknownCounterInResponse()
        {
            var aCounter = new BatchCounterQuery { CounterName = "a", UserContext = "a" };

            var batchRequest = new BatchQueryRequest();
            batchRequest.Queries.Add(aCounter);

            var agg = new BatchResponseAggregator(batchRequest);

            var oneResponse = new BatchQueryResponse
                              {
                                  Responses = {this.CreateHitCountResponse("i am a key tree", 100)},
                                  RequestDetails =
                                  {
                                      new RequestDetails
                                      {
                                          Server = new ServerInfo
                                                   {
                                                       Hostname = "something",
                                                   },
                                          HttpResponseCode = 200
                                      }
                                  }
                              };

            agg.AddResponse(oneResponse);

            var finalResponse = agg.GetResponse();
            Assert.IsNotNull(finalResponse);
            Assert.AreEqual(1, finalResponse.Responses.Count);
            Assert.AreEqual(0, finalResponse.Responses[0].Samples.Count);
        }
        public void AggregatorAggregatesOverlapCorrectly()
        {
            var aCounter = new BatchCounterQuery { CounterName = "a", UserContext = "a" };

            var batchRequest = new BatchQueryRequest();
            batchRequest.Queries.Add(aCounter);

            var agg = new BatchResponseAggregator(batchRequest);

            var oneResponse = new BatchQueryResponse
                              {
                                  Responses = {this.CreateHitCountResponse("a", 100)},
                                  RequestDetails =
                                  {
                                      new RequestDetails
                                      {
                                          Server = new ServerInfo
                                          {
                                              Hostname = "something",
                                              Port = 42
                                          },
                                          HttpResponseCode = 200
                                      }
                                  }
                              };
            var twoResponse = new BatchQueryResponse
                              {
                                  Responses = {this.CreateHitCountResponse("a", 200)},
                                  RequestDetails =
                                  {
                                      new RequestDetails
                                      {
                                          Server = new ServerInfo
                                          {
                                              Hostname = "somewhere",
                                              Port = 42
                                          },
                                          HttpResponseCode = 200
                                      }
                                  }
                              };

            agg.AddResponse(oneResponse);
            agg.AddResponse(twoResponse);

            var finalResponse = agg.GetResponse();
            Assert.IsNotNull(finalResponse);
            Assert.AreEqual(2, finalResponse.RequestDetails.Count);
            Assert.AreEqual(1, finalResponse.Responses.Count);
            Assert.AreEqual(300, finalResponse.Responses[0].Samples[0].HitCount);
        }
Beispiel #25
0
        public async Task BatchQueryMultipleQueriesForSameCounterWithDifferentParametersWorksFine()
        {
            // Fill up the taco truck
            var dimensionSet = new DimensionSet(new HashSet <Dimension> {
                new Dimension("Filling")
            });
            var counter = await this.dataManager.CreateHitCounter("/Tacos", dimensionSet);

            var chickenTacos = new DimensionSpecification {
                { "Filling", "Chicken" }
            };
            var beefTacos = new DimensionSpecification {
                { "Filling", "Beef" }
            };
            var veggieTacos = new DimensionSpecification {
                { "Filling", "TOFU" }
            };
            var baconTacos = new DimensionSpecification {
                { "Filling", "bacon" }
            };

            counter.Increment(100, chickenTacos);
            counter.Increment(200, beefTacos);
            counter.Increment(300, veggieTacos);
            this.dataManager.Flush();

            var data = new BatchQueryRequest();

            data.Queries.Add(new BatchCounterQuery {
                CounterName = "/Tacos", UserContext = "TotalTacos"
            });
            data.Queries.Add(new BatchCounterQuery
            {
                CounterName     = "/Tacos",
                UserContext     = "CluckCluck",
                QueryParameters = chickenTacos.Data
            });
            data.Queries.Add(new BatchCounterQuery
            {
                CounterName     = "/Tacos",
                UserContext     = "BACON!",
                QueryParameters = baconTacos.Data
            });

            var response = await
                           this.httpClient.PostAsync(
                TestUtils.GetUri(this.server,
                                 RestCommands.BatchQueryCommand,
                                 string.Empty),
                GetRequestPayload(data));

            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);

            using (var readerStream = new ReaderStream(await response.Content.ReadAsStreamAsync()))
            {
                var reader       = readerStream.CreateBondedCompactBinaryReader <BatchQueryResponse>();
                var responseData = reader.Deserialize();
                Assert.AreEqual(3, responseData.Responses.Count);

                // unfiltered should have 100+200+300 hitcount
                VerifyHitCounter(responseData, "TotalTacos", 600);

                //only 100 chicken tacos
                VerifyHitCounter(responseData, "CluckCluck", 100);

                //sadly, there is no bacon...
                VerifyHitCounter(responseData, "BACON!", -1);
            }
        }
Beispiel #26
0
        public async void BatchQueryAggregatesFanoutCorrectly()
        {
            const string tacoTruck             = "/Tacos";
            const string competingBurritoTruck = "/Burritos";

            var dimensionSet = new DimensionSet(new HashSet <Dimension>());
            var counter      = await this.dataManager.CreateHitCounter(tacoTruck, dimensionSet);

            // locally store dim1
            counter.Increment(100, new DimensionSpecification());
            this.dataManager.Flush();

            var data = new BatchQueryRequest();

            data.Queries.Add(new BatchCounterQuery {
                CounterName = tacoTruck, UserContext = tacoTruck
            });
            data.Queries.Add(new BatchCounterQuery
            {
                CounterName = competingBurritoTruck,
                UserContext = competingBurritoTruck
            });
            data.Sources.Add(new ServerInfo {
                Hostname = "a", Port = 42
            });
            data.Sources.Add(new ServerInfo {
                Hostname = "b", Port = 42
            });

            var sampleStart = DateTime.Now;
            var sampleEnd   = sampleStart.AddHours(1);

            // remotely return 100 for dim2 only
            DistributedQueryClient.RequesterFactory = new MockHttpRequesterFactory(message =>
            {
                var batchResponse = new BatchQueryResponse();
                batchResponse.RequestDetails.Add(new RequestDetails
                {
                    Server =
                        new ServerInfo
                    {
                        Hostname = "bob",
                        Port     = 42
                    },
                    HttpResponseCode = 200
                });
                var counterResponse = new CounterQueryResponse
                {
                    HttpResponseCode = 200,
                    UserContext      = competingBurritoTruck,
                    Samples          = new List <DataSample> {
                        new DataSample {
                            HitCount = 100, Dimensions = new Dictionary <string, string>(), SampleType = DataSampleType.HitCount, StartTime = sampleStart.ToMillisecondTimestamp(), EndTime = sampleEnd.ToMillisecondTimestamp()
                        }
                    }
                };
                batchResponse.Responses.Add(counterResponse);
                return(MockDataFactory.CreateResponse(batchResponse));
            });

            var response = await
                           this.httpClient.PostAsync(TestUtils.GetUri(this.server, RestCommands.BatchQueryCommand,
                                                                      string.Empty),
                                                     GetRequestPayload(data));

            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
            var responseData = await MockDataFactory.ReadResponseData <BatchQueryResponse>(response);

            Assert.IsNotNull(responseData);
            Assert.AreEqual(3, responseData.RequestDetails.Count);
            Assert.IsTrue(responseData.RequestDetails.All(x => x.HttpResponseCode == 200));
            Assert.AreEqual(2, responseData.Responses.Count);
            Assert.AreEqual(1, responseData.Responses.Count(x => x.UserContext.Equals(tacoTruck) && x.Samples[0].HitCount == 100));
            Assert.AreEqual(1, responseData.Responses.Count(x => x.UserContext.Equals(competingBurritoTruck) && x.Samples[0].HitCount == 200));
        }