protected internal virtual async Task <IServerResponseWrapper> HandleBatch(BatchRequestWrapper batchRequestWrapper, BatchHandling batchHandling, HandlingContext context) { // If the batch rpc call itself fails to be recognized as an valid JSON or as an Array with at least one value, the response from the Server MUST be a single Response object if (batchRequestWrapper.Batch.Count == 0) { throw new JsonRpcInternalException("JSON Rpc batch request is empty"); } // the server MUST NOT return an empty Array and should return nothing at all var hasRequestInBatch = batchRequestWrapper.Batch.OfType <UntypedRequest>().Any(); context.WriteResponse = hasRequestInBatch; log.LogTrace($"{nameof(HandleBatch)}: set writeResponse [{context.WriteResponse}] because {nameof(hasRequestInBatch)} is [{hasRequestInBatch}]"); // We ignore headers and other properties from nested responses because there is no good way to solve possible conflicts switch (batchHandling) { case BatchHandling.Sequential: var batchResponse = await HandleBatchSequential(batchRequestWrapper, context); return(new JsonServerResponseWrapper(batchResponse, null, null)); default: throw new ArgumentOutOfRangeException(nameof(options.BatchHandling), options.BatchHandling, "Unsupported value"); } }
public async Task Test_HandleBatch_ThrowsOnEmpty() { var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); Func <Task> action = async() => await requestHandlerMock.Object.HandleBatch(batch, BatchHandling.Sequential, handlingContext); await action.Should().ThrowAsync <JsonRpcInternalException>(); requestHandlerMock.Verify(x => x.HandleBatch(It.IsAny <BatchRequestWrapper>(), BatchHandling.Sequential, It.IsAny <HandlingContext>())); }
public async Task Test_HandleBatchSequential_ReturnsEmptyOnEmptyBatch() { var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); var result = await requestHandlerMock.Object.HandleBatchSequential(batch, handlingContext); result.Should().BeEmpty(); requestHandlerMock.Verify(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())); }
public async Task Test_HandleBatch_ThrowsOnUnknown() { var request = new UntypedRequest(); var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() { request } }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); Func <Task> action = async() => await requestHandlerMock.Object.HandleBatch(batch, (BatchHandling)(-1), handlingContext); await action.Should().ThrowAsync <ArgumentOutOfRangeException>(); requestHandlerMock.Verify(x => x.HandleBatch(It.IsAny <BatchRequestWrapper>(), It.IsAny <BatchHandling>(), It.IsAny <HandlingContext>())); }
public async Task Test_HandleBatch_WritesFlagWhenHaveRequests() { var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() { new UntypedRequest() } }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())) .ReturnsAsync(new JArray()); await requestHandlerMock.Object.HandleBatch(batch, BatchHandling.Sequential, handlingContext); handlingContext.WriteResponse.Should().BeTrue(); requestHandlerMock.Verify(x => x.HandleBatch(It.IsAny <BatchRequestWrapper>(), BatchHandling.Sequential, It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())); }
public async Task Test_GetRequestWrapper_DoesNotStoreBatch() { var request = new BatchRequestWrapper(); var itemsMock = new Mock <IDictionary <object, object> >(); itemsMock.Setup(x => x.ContainsKey(JsonRpcConstants.RequestItemKey)) .Returns(false); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.Items) .Returns(itemsMock.Object); requestReaderMock.Setup(x => x.ParseRequest(It.IsAny <HttpContext>(), It.IsAny <Encoding>())) .ReturnsAsync(request); var result = await requestReaderMock.Object.GetRequestWrapper(httpContextMock.Object, Encoding.UTF8); result.Should().BeOfType <BatchRequestWrapper>(); result.Should().Be(request); requestReaderMock.Verify(x => x.ParseRequest(It.IsAny <HttpContext>(), It.IsAny <Encoding>())); requestReaderMock.Verify(x => x.GetRequestWrapper(It.IsAny <HttpContext>(), It.IsAny <Encoding>())); }
public async Task Test_HandleBatchSequential_ReturnsEmptyOnNotification() { var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() { new UntypedNotification() } }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); var jValue = JValue.CreateString("test"); requestHandlerMock.Setup(x => x.GetResponseSafeInBatch(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>())) .ReturnsAsync(jValue); var result = await requestHandlerMock.Object.HandleBatchSequential(batch, handlingContext); result.Should().BeEmpty(); requestHandlerMock.Verify(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.GetResponseSafeInBatch(It.IsAny <UntypedNotification>(), It.IsAny <HandlingContext>())); }
protected internal virtual async Task <JArray> HandleBatchSequential(BatchRequestWrapper batchRequestWrapper, HandlingContext context) { var batchResponse = new JArray(); var i = 1; foreach (var call in batchRequestWrapper.Batch) { log.LogTrace($"{nameof(HandleBatchSequential)}: [{i}/{batchRequestWrapper.Batch.Count}] processing"); var response = await GetResponseSafeInBatch(call, context); if (call is UntypedRequest) { batchResponse.Add(response); log.LogTrace($"{nameof(HandleBatchSequential)}: [{i}/{batchRequestWrapper.Batch.Count}] add response to result because call was request"); } else { log.LogTrace($"{nameof(HandleBatchSequential)}: [{i}/{batchRequestWrapper.Batch.Count}] ignored response because call was not request"); } } return(batchResponse); }
public async Task Test_HandleBatch_CallsSequential() { var request = new UntypedRequest(); var value = new JArray(); var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() { request } }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())) .ReturnsAsync(value); var result = await requestHandlerMock.Object.HandleBatch(batch, BatchHandling.Sequential, handlingContext); result.Should().BeOfType <JsonServerResponseWrapper>(); Assert.AreEqual(value, (result as JsonServerResponseWrapper).Value); requestHandlerMock.Verify(x => x.HandleBatch(It.IsAny <BatchRequestWrapper>(), BatchHandling.Sequential, It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())); }