示例#1
0
        public async Task Invoke_ThrowExceptionAwaitedRelease_ReleaseCalledAndErrorThrown()
        {
            // Arrange
            var releaseTcs       = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);
            var serviceActivator = new TcsGrpcServiceActivator <TestService>(releaseTcs);
            var thrownException  = new Exception("Exception!");
            var invoker          = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => throw thrownException,
                new Method <TestMessage, TestMessage>(MethodType.Unary, "test", "test", _marshaller, _marshaller),
                HttpContextServerCallContextHelper.CreateMethodOptions(),
                serviceActivator);
            var httpContext = HttpContextHelpers.CreateContext();

            // Act
            var task = invoker.Invoke(httpContext, HttpContextServerCallContextHelper.CreateServerCallContext(), new TestMessage());

            Assert.False(task.IsCompleted);

            releaseTcs.SetResult(null);

            try
            {
                await task;
                Assert.Fail();
            }
            catch (Exception ex)
            {
                // Assert
                Assert.True(serviceActivator.Released);
                Assert.AreEqual(thrownException, ex);
            }
        }
        public async Task Deadline_HandleCallAsyncWaitsForDeadlineToFinish()
        {
            // Arrange
            Task?handleCallTask = null;
            bool?isHandleCallTaskCompleteDuringDeadline = null;
            var  httpContext = HttpContextHelpers.CreateContext(completeAsyncAction: async() =>
            {
                await Task.Delay(200);
                isHandleCallTaskCompleteDuringDeadline = handleCallTask?.IsCompleted;
            });

            httpContext.Request.Headers[GrpcProtocolConstants.TimeoutHeader] = "50m";
            var call = CreateHandler(MethodType.ClientStreaming, handlerAction: () => Task.Delay(100));

            // Act
            handleCallTask = call.HandleCallAsync(httpContext).DefaultTimeout();
            await handleCallTask;

            // Assert
            var serverCallContext = httpContext.Features.Get <IServerCallContextFeature>() !;

            Assert.AreEqual(StatusCode.DeadlineExceeded, serverCallContext.ServerCallContext.Status.StatusCode);

            Assert.IsFalse(isHandleCallTaskCompleteDuringDeadline);
        }
示例#3
0
        public async Task Invoke_AwaitedSuccess_ReleaseCalled()
        {
            // Arrange
            var methodTcs        = new TaskCompletionSource <TestMessage>(TaskCreationOptions.RunContinuationsAsynchronously);
            var methodResult     = new TestMessage();
            var serviceActivator = new TestGrpcServiceActivator <TestService>();
            var invoker          = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => methodTcs.Task,
                new Method <TestMessage, TestMessage>(MethodType.Unary, "test", "test", _marshaller, _marshaller),
                HttpContextServerCallContextHelper.CreateMethodOptions(),
                serviceActivator);
            var httpContext = HttpContextHelpers.CreateContext();

            // Act
            var task = invoker.Invoke(httpContext, HttpContextServerCallContextHelper.CreateServerCallContext(), new TestMessage());

            Assert.False(task.IsCompleted);

            methodTcs.SetResult(methodResult);
            var awaitedResult = await task;

            // Assert
            Assert.AreEqual(methodResult, awaitedResult);
            Assert.True(serviceActivator.Released);
        }
        public void CreateClient_MultipleNamedClients_ReturnMatchingClient()
        {
            // Arrange
            var services = new ServiceCollection();

            HttpContextHelpers.SetupHttpContext(services);
            services.AddGrpcClient <TestGreeterClient>("contoso", options =>
            {
                options.BaseAddress = new Uri("http://contoso");
            });
            services.AddGrpcClient <TestGreeterClient>("adventureworks", options =>
            {
                options.BaseAddress = new Uri("http://adventureworks");
            });

            var provider = services.BuildServiceProvider();

            // Act
            var clientFactory = provider.GetRequiredService <GrpcClientFactory>();

            var contosoClient        = clientFactory.CreateClient <TestGreeterClient>("contoso");
            var adventureworksClient = clientFactory.CreateClient <TestGreeterClient>("adventureworks");

            // Assert
            Assert.AreEqual("http://contoso", contosoClient.GetCallInvoker().BaseAddress.OriginalString);
            Assert.AreEqual("http://adventureworks", adventureworksClient.GetCallInvoker().BaseAddress.OriginalString);
        }
        public async Task CreateClient_LoggingSetup_ClientLogsToTestSink()
        {
            // Arrange
            var testSink = new TestSink();

            var services = new ServiceCollection();

            HttpContextHelpers.SetupHttpContext(services);
            var clientBuilder = services.AddGrpcClient <TestGreeterClient>("contoso", options =>
            {
                options.BaseAddress = new Uri("http://contoso");
            }).AddHttpMessageHandler(() => new TestDelegatingHandler());

            services.AddLogging(configure => configure.SetMinimumLevel(LogLevel.Trace));
            services.TryAddEnumerable(ServiceDescriptor.Singleton <ILoggerProvider, TestLoggerProvider>(s => new TestLoggerProvider(testSink, true)));

            var provider = services.BuildServiceProvider();

            // Act
            var clientFactory = provider.GetRequiredService <GrpcClientFactory>();

            var contosoClient = clientFactory.CreateClient <TestGreeterClient>("contoso");

            var response = await contosoClient.SayHelloAsync(new HelloRequest());

            // Assert
            Assert.AreEqual("http://contoso", contosoClient.GetCallInvoker().BaseAddress.OriginalString);

            Assert.IsTrue(testSink.Writes.Any(w => w.EventId.Name == "StartingCall"));
        }
示例#6
0
        public void ResolveDefaultAndNamedClients_ClientsUseCorrectConfiguration()
        {
            // Arrange
            var services = new ServiceCollection();

            HttpContextHelpers.SetupHttpContext(services);
            services.AddGrpcClient <TestGreeterClient>(options =>
            {
                options.BaseAddress = new Uri("http://testgreeterclient");
            });
            services.AddGrpcClient <TestSecondGreeterClient>("contoso", options =>
            {
                options.BaseAddress = new Uri("http://contoso");
            });
            services.AddGrpcClient <TestSecondGreeterClient>(options =>
            {
                options.BaseAddress = new Uri("http://testsecondgreeterclient");
            });

            var provider = services.BuildServiceProvider();

            // Act
            var client       = provider.GetRequiredService <TestGreeterClient>();
            var secondClient = provider.GetRequiredService <TestSecondGreeterClient>();

            var factory       = provider.GetRequiredService <GrpcClientFactory>();
            var contosoClient = factory.CreateClient <TestSecondGreeterClient>("contoso");

            // Assert
            Assert.AreEqual("http://testgreeterclient", client.GetCallInvoker().BaseAddress.OriginalString);
            Assert.AreEqual("http://testsecondgreeterclient", secondClient.GetCallInvoker().BaseAddress.OriginalString);
            Assert.AreEqual("http://contoso", contosoClient.GetCallInvoker().BaseAddress.OriginalString);
        }
 public HttpAuditAction(IHttpContextAccessor accessor, AuditHttpActionOptions options)
 {
     Action = new
     {
         accessor.HttpContext.TraceIdentifier,
         RequestUrl    = accessor.HttpContext.Request.GetDisplayUrl(),
         HttpMethod    = accessor.HttpContext.Request.Method,
         FormVariables = options.IncludeFormVariables ? HttpContextHelpers.GetFormVariables(accessor.HttpContext) : null
     };
 }
示例#8
0
        public void Verify_GetIpAddress_Should_Return_IpAddress()
        {
            // Arrange
            Mock <HttpContext> httpContext = new HttpContextMock().HttpContext;

            // Act
            var ipAddress = HttpContextHelpers.GetIpAddress(httpContext.Object);

            // Assert
            ipAddress.Should().Be("127.0.0.1");
        }
示例#9
0
        public async Task MaxRequestBodySizeFeature_MethodType_HasMaxRequestBodySize(MethodType methodType, bool hasMaxRequestBodySize)
        {
            // Arrange
            var httpContext = HttpContextHelpers.CreateContext();
            var call        = CreateHandler(methodType);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            Assert.AreEqual(hasMaxRequestBodySize, httpContext.Features.Get <IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize != null);
        }
示例#10
0
        public async Task StatusDebugException_ErrorInHandler_SetInDebugException()
        {
            // Arrange
            var ex          = new Exception("Test exception");
            var httpContext = HttpContextHelpers.CreateContext();
            var call        = CreateHandler(MethodType.ClientStreaming, handlerAction: () => throw ex);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            var serverCallContext = httpContext.Features.Get <IServerCallContextFeature>();

            Assert.AreEqual(ex, serverCallContext.ServerCallContext.Status.DebugException);
        }
示例#11
0
        public async Task SetResponseTrailers_FeatureMissing_ThrowError()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(skipTrailerFeatureSet: true);
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            var ex = await ExceptionAssert.ThrowsAsync <InvalidOperationException>(() => call.HandleCallAsync(httpContext)).DefaultTimeout();

            // Assert
            Assert.AreEqual("Trailers are not supported for this response. The server may not support gRPC.", ex.Message);
        }
示例#12
0
        public async Task <IActionResult> ShareContact([FromBody] ShareDto shareDto)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var userEmail = HttpContextHelpers.GetCurrentUserEmail(User);
            var user      = await _userService.FindByEmailAsync(userEmail);

            var shareKardCommand = new ShareContactCommand(shareDto.ContactId, shareDto.RecipientUserId, user.Id);

            await _commandBus.Send(shareKardCommand);

            return(Ok());
        }
示例#13
0
        public async Task MaxRequestBodySizeFeature_FeatureIsReadOnly_FailureLogged()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(isMaxRequestBodySizeFeatureReadOnly: true);
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            Assert.AreEqual(true, httpContext.Features.Get <IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize != null);
            Assert.IsTrue(testSink.Writes.Any(w => w.EventId.Name == "UnableToDisableMaxRequestBodySizeLimit"));
        }
示例#14
0
        public List <SomeDataDto> SomeData()
        {
            var config = new MapperConfiguration(cfg => {
                cfg.CreateMap <Data.Contexts.Models.SomeData, SomeAggregate>();
                cfg.CreateMap <Color, string>().ConvertUsing(l => l.Value);
                cfg.CreateMap <FacebookUrl, string>().ConvertUsing(l => l.Value);
            });

            config.AssertConfigurationIsValid();
            var mapper = config.CreateMapper();

            var userEmail = HttpContextHelpers.GetCurrentUserEmail(User);
            var myData    = _someDataReadService.GetSomeData(userEmail);
            var someData  = mapper.Map <List <SomeAggregate>, List <SomeDataDto> >(myData);

            return(someData);
        }
示例#15
0
        public async Task ProtocolValidation_IISHttp2Protocol_Success()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(protocol: GrpcProtocolConstants.Http20Protocol);
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            var log = testSink.Writes.SingleOrDefault(w => w.EventId.Name == "UnsupportedRequestProtocol");

            Assert.IsNull(log);
        }
示例#16
0
        public async Task ProtocolValidation_InvalidProtocol_FailureLogged()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(protocol: "HTTP/1.1");
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            var log = testSink.Writes.SingleOrDefault(w => w.EventId.Name == "UnsupportedRequestProtocol");

            Assert.IsNotNull(log);
            Assert.AreEqual("Request protocol of 'HTTP/1.1' is not supported.", log.Message);
        }
示例#17
0
        public async Task ContentTypeValidation_InvalidContentType_FailureLogged()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(contentType: "text/plain");
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            var log = testSink.Writes.SingleOrDefault(w => w.EventId.Name == "UnsupportedRequestContentType");

            Assert.IsNotNull(log);
            Assert.AreEqual("Request content-type of 'text/plain' is not supported.", log.Message);
        }
        public async Task OnServiceMethodDiscovery_ServiceWithDuplicateMethodNames_Success()
        {
            // Arrange
            var services = new ServiceCollection();

            services.AddSingleton <GreeterServiceWithDuplicateNames>();

            var serverCallHandlerFactory = new ServerCallHandlerFactory <GreeterServiceWithDuplicateNames>(
                NullLoggerFactory.Instance,
                Options.Create <GrpcServiceOptions>(new GrpcServiceOptions()),
                Options.Create <GrpcServiceOptions <GreeterServiceWithDuplicateNames> >(new GrpcServiceOptions <GreeterServiceWithDuplicateNames>()),
                new TestGrpcServiceActivator <GreeterServiceWithDuplicateNames>());

            var provider = new BinderServiceMethodProvider <GreeterServiceWithDuplicateNames>(NullLoggerFactory.Instance);
            var context  = new ServiceMethodProviderContext <GreeterServiceWithDuplicateNames>(serverCallHandlerFactory);

            var httpContext = HttpContextHelpers.CreateContext();

            httpContext.RequestServices = services.BuildServiceProvider();

            // Act
            provider.OnServiceMethodDiscovery(context);

            // Assert
            Assert.AreEqual(2, context.Methods.Count);

            var methodModel = context.Methods[0];

            Assert.AreEqual("SayHello", methodModel.Method.Name);

            var ms = new MemoryStream();

            MessageHelpers.WriteMessage(ms, new HelloRequest
            {
                Name = "World"
            });
            ms.Seek(0, SeekOrigin.Begin);
            httpContext.Request.Body = ms;

            await methodModel.RequestDelegate(httpContext);

            // Expect 12 (unimplemented) from base type
            Assert.AreEqual("12", httpContext.Response.Headers["grpc-status"]);
        }
示例#19
0
        public async Task Invoke(
            HttpContext httpContext,
            IAuthenticatedUserService authenticatedUserService,
            IUnitOfWork unitOfWork)
        {
            string requestMethod      = default;
            string requestPath        = default;
            string requestIpAddress   = default;
            string requestUserId      = default;
            int    responseStatusCode = default;

            if (httpContext.Request != default)
            {
                requestMethod    = httpContext.Request.Method;
                requestPath      = httpContext.Request.Path.Value;
                requestIpAddress = HttpContextHelpers.GetIpAddress(httpContext.Request.HttpContext);
                requestUserId    = authenticatedUserService.IsValid ? authenticatedUserService.Id : default;
            }

            await this._next(httpContext);

            if (httpContext.Request != default && httpContext.Response != default)
            {
                responseStatusCode = httpContext.Response.StatusCode;

                var log = new ActivityLog
                {
                    Method             = requestMethod,
                    Path               = requestPath,
                    IpAddress          = requestIpAddress,
                    UserId             = requestUserId,
                    ResponseStatusCode = responseStatusCode,
                    Timestamp          = DateTime.UtcNow,
                };

                unitOfWork.ActivityLogs.Add(log);

                if (unitOfWork.Finish() == 0)
                {
                    throw new Exception("Could not save the activity log into the database.");
                }
            }
        }
示例#20
0
        public void Invoke_ThrowException_ReleaseCalledAndErrorThrown()
        {
            // Arrange
            var serviceActivator = new TestGrpcServiceActivator <TestService>();
            var ex      = new Exception("Exception!");
            var invoker = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => throw ex,
                new Method <TestMessage, TestMessage>(MethodType.Unary, "test", "test", _marshaller, _marshaller),
                HttpContextServerCallContextHelper.CreateMethodOptions(),
                serviceActivator);
            var httpContext = HttpContextHelpers.CreateContext();

            // Act
            var task = invoker.Invoke(httpContext, HttpContextServerCallContextHelper.CreateServerCallContext(), new TestMessage());

            // Assert
            Assert.True(serviceActivator.Released);
            Assert.True(task.IsFaulted);
            Assert.AreEqual(ex, task.Exception !.InnerException);
        }
        public void CreateClient_UnmatchedName_ThrowError()
        {
            // Arrange
            var services = new ServiceCollection();

            HttpContextHelpers.SetupHttpContext(services);
            services.AddGrpcClient <TestGreeterClient>(options =>
            {
                options.BaseAddress = new Uri("http://contoso");
            });

            var provider = services.BuildServiceProvider();

            var clientFactory = provider.GetRequiredService <GrpcClientFactory>();

            // Act
            var ex = Assert.Throws <InvalidOperationException>(() => clientFactory.CreateClient <TestGreeterClient>("DOES_NOT_EXIST"));

            // Assert
            Assert.AreEqual("No gRPC client configured with name 'DOES_NOT_EXIST'.", ex.Message);
        }
示例#22
0
        public void UseRequestCancellationTokenIsTrue_HasHttpContext_UseRequestToken()
        {
            // Arrange
            var cts = new CancellationTokenSource();

            var services = new ServiceCollection();

            HttpContextHelpers.SetupHttpContext(services, cts.Token);
            services.AddGrpcClient <TestGreeterClient>(options =>
            {
                options.PropagateCancellationToken = true;
            });

            var provider = services.BuildServiceProvider();

            // Act
            var client = provider.GetRequiredService <TestGreeterClient>();

            // Assert
            Assert.AreEqual(cts.Token, client.GetCallInvoker().CancellationToken);
        }
示例#23
0
        public async Task <ActionResult <IResponse <string> > > RevokeRefreshToken(RevokeRefreshTokenDto dto)
        {
            IResponse response;

            var command = this._mapper.Map <RevokeRefreshTokenCommand>(dto);

            command.IpAddress = HttpContextHelpers.GetIpAddress(this.Request.HttpContext);

            response = await this._mediator.Send(command);

            if (response == default)
            {
                return(NotFound(this._responseFactory.Create(message: ResponseMessages.RefreshTokenNotFound)));
            }

            if (!response.Success)
            {
                return(BadRequest(response));
            }

            return(Ok(response));
        }
示例#24
0
        public async Task Invoke_SuccessAwaitedRelease_ReleaseCalled()
        {
            // Arrange
            var releaseTcs       = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);
            var serviceActivator = new TcsGrpcServiceActivator <TestService>(releaseTcs);
            var invoker          = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => Task.FromResult(new TestMessage()),
                new Method <TestMessage, TestMessage>(MethodType.Unary, "test", "test", _marshaller, _marshaller),
                HttpContextServerCallContextHelper.CreateMethodOptions(),
                serviceActivator);
            var httpContext = HttpContextHelpers.CreateContext();

            // Act
            var task = invoker.Invoke(httpContext, HttpContextServerCallContextHelper.CreateServerCallContext(), new TestMessage());

            Assert.False(task.IsCompleted);

            releaseTcs.SetResult(null);
            await task;

            // Assert
            Assert.True(serviceActivator.Released);
        }
示例#25
0
        public void Setup()
        {
            areaData = new AreaRouteData()
            {
                Controller             = "Home",
                Action                 = "Index",
                Area                   = "Temp",
                UseChildActionBehavior = true
            };

            var stream = new MemoryStream();

            routeData     = new RouteData();
            routeDataMock = new Mock <IRouteData>();
            routeDataMock.Setup(x => x.Values)
            .Returns(routeData.Values);
            routeDataMock.Setup(x => x.DataTokens)
            .Returns(routeData.DataTokens);

            httpContextMock = HttpContextHelpers.GetMockHttpContext();
            httpContextMock
            .Setup(x => x.Response)
            .Returns(new HttpResponseWrapper(new HttpResponse(new StreamWriter(stream))));
            var requestContext = new RequestContext(httpContextMock.Object, routeData);

            ContextService.Get().Push <PageContext>(new PageContext()
            {
                RequestContext = requestContext
            });

            pageContextMock = new Mock <IPageContext>();
            pageContextMock
            .Setup(x => x.RequestContext)
            .Returns(requestContext);

            viewContextProviderMock = new Mock <IViewContextProvider>();
        }
示例#26
0
        public async Task <IActionResult> CreateSomeData([FromBody] CreateSomeDataDto createSomeDataModel)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var userEmail = HttpContextHelpers.GetCurrentUserEmail(User);
            var user      = await _userService.FindByEmailAsync(userEmail);

            var createCommand = new CreateSomeDataCommand(Guid.NewGuid(),
                                                          createSomeDataModel.FirstName,
                                                          createSomeDataModel.MiddleName,
                                                          createSomeDataModel.LastName,
                                                          createSomeDataModel.Title,
                                                          new Color(createSomeDataModel.Color),
                                                          DateTime.Now,
                                                          new FacebookUrl(createSomeDataModel.FacebookUrl),
                                                          new ApplicationUserId(user.Id));

            await _commandBus.Send(createCommand);

            return(Ok());
        }
示例#27
0
        public async Task <ActionResult <IResponse <AccessTokenDto> > > RefreshAccessToken(RefreshAccessTokenDto dto)
        {
            IResponse <AccessTokenDto> response;

            var command = this._mapper.Map <RefreshAccessTokenCommand>(dto);

            command.IpAddress = HttpContextHelpers.GetIpAddress(this.Request.HttpContext);

            response = await this._mediator.Send(command);

            if (response == default)
            {
                return(NotFound(this._responseFactory.Create <AccessTokenDto>(message: ResponseMessages.UserNotRegistered)));
            }

            if (!response.Success)
            {
                return(BadRequest(response));
            }

            this.Response.Headers.Append("refresh-token", response.Data.RefreshToken);

            return(Ok(response));
        }