Ejemplo n.º 1
0
        public virtual void SetUp()
        {
            _testinghost = new NonOrleansServiceTester <ConfigurableHost <IDemoService> >();

            //    Metric.Context("Service");
            TracingContext.SetRequestID("1");
        }
Ejemplo n.º 2
0
        public async Task OneHostHasNetworkErrorShouldMoveToNextHost()
        {
            var port = DisposablePort.GetPort().Port;
            var dict = new Dictionary <string, string>
            {
                { "Discovery.Services.DemoService.Source", "Config" },
                { "Discovery.Services.DemoService.Hosts", "host1,host2" },
                { "Discovery.Services.DemoService.DefaultPort", port.ToString() }
            };

            int counter = 0;
            Func <HttpClientConfiguration, HttpMessageHandler> messageHandlerFactory = _ =>
            {
                var messageHandler = new MockHttpMessageHandler();
                messageHandler
                .When("*")
                .Respond(req =>
                {
                    if (req.Method == HttpMethod.Get && req.RequestUri.Scheme == "https")
                    {
                        throw new HttpRequestException();
                    }

                    counter++;

                    if (req.RequestUri.Host == "host1")
                    {
                        throw new HttpRequestException();
                    }
                    return(HttpResponseFactory.GetResponse(content: $"'{req.RequestUri.Host}'"));
                });
                return(messageHandler);
            };

            using (var kernel =
                       new TestingKernel <ConsoleLog>(
                           k =>
            {
                k.Rebind <IDiscovery>().To <ServiceDiscovery.Rewrite.Discovery>().InSingletonScope();
                k.Rebind <Func <HttpClientConfiguration, HttpMessageHandler> >().ToMethod(c => messageHandlerFactory);
            }, dict)
                   )
            {
                var providerFactory = kernel.Get <Func <string, ServiceProxyProvider> >();
                var serviceProxy    = providerFactory("DemoService");
                serviceProxy.DefaultPort = port;
                TracingContext.SetRequestID("1");

                var request = new HttpServiceRequest("testMethod", null, new Dictionary <string, object>());

                for (int i = 0; i < 3; i++)
                {
                    var server = await serviceProxy.Invoke(request, typeof(string));

                    server.ShouldBe("host2");
                }

                counter.ShouldBe(3);
            }
        }
 public virtual void SetUp()
 {
     _testinghost    = new NonOrleansServiceTester <TestingHost <IDemoService> >();
     _insecureClient = _testinghost.GetServiceProxy <IDemoService>();
     Metric.ShutdownContext("Service");
     TracingContext.SetRequestID("1");
 }
Ejemplo n.º 4
0
        public async Task ServiceProxyRpcMessageShouldRemainSame()
        {
            const string serviceName = "DemoService";
            int          defaultPort = DisposablePort.GetPort().Port;
            var          dict        = new Dictionary <string, string>
            {
                { $"Discovery.Services.{serviceName}.Source", "Config" },
                { $"Discovery.Services.{serviceName}.Hosts", "host1" },
                { $"Discovery.Services.{serviceName}.DefaultPort", defaultPort.ToString() }
            };

            Uri    uri            = null;
            string requestMessage = null;

            Func <HttpClientConfiguration, HttpMessageHandler> messageHandlerFactory = _ =>
            {
                var messageHandler = new MockHttpMessageHandler();
                messageHandler
                .When("*").Respond(async req =>
                {
                    requestMessage = await req.Content.ReadAsStringAsync();
                    uri            = req.RequestUri;
                    return(HttpResponseFactory.GetResponse(HttpStatusCode.Accepted));
                });
                return(messageHandler);
            };

            using (var kernel = new TestingKernel <ConsoleLog>(k =>
            {
                k.Rebind <IDiscovery>().To <ServiceDiscovery.Rewrite.Discovery>().InSingletonScope();
                k.Rebind <Func <HttpClientConfiguration, HttpMessageHandler> >().ToMethod(c => messageHandlerFactory);
            }, dict))
            {
                var providerFactory = kernel.Get <Func <string, ServiceProxyProvider> >();

                TracingContext.SetRequestID("g");

                var serviceProxy = providerFactory(serviceName);

                string expectedHost = "override-host";
                int    expectedPort = DisposablePort.GetPort().Port;

                TracingContext.SetHostOverride(serviceName, expectedHost, expectedPort);

                var request = new HttpServiceRequest("testMethod", null, new Dictionary <string, object>());
                using (TracingContext.Tags.SetUnencryptedTag("test", 1))
                    await serviceProxy.Invoke(request, typeof(string));
                var body = requestMessage;
                Console.WriteLine($"error: {body}");

                JsonConvert.DeserializeObject <GigyaRequestProtocol>(body, new JsonSerializerSettings()
                {
                    MissingMemberHandling = MissingMemberHandling.Error
                });


                uri.Host.ShouldBe(expectedHost);
                uri.Port.ShouldBe(expectedPort);
            }
        }
 public virtual void SetUp()
 {
     unitTesting = new TestingKernel <ConsoleLog>(mockConfig: MockConfig);
     Metric.ShutdownContext(ServiceProxyProvider.METRICS_CONTEXT_NAME);
     TracingContext.SetUpStorage();
     TracingContext.SetRequestID("1");
 }
Ejemplo n.º 6
0
        public void SetUp()
        {
            Metric.ShutdownContext("Service");

            TracingContext.SetUpStorage();
            TracingContext.SetRequestID("1");


            var kernel = new TestingKernel <ConsoleLog>();

            _proxyInstance = kernel.Get <IDemoService>();
        }
Ejemplo n.º 7
0
        public virtual void SetUp()
        {
            _insecureClient      = _kernel.Get <IDemoService>();
            _exceptionSerializer = _kernel.Get <JsonExceptionSerializer>();

            Metric.ShutdownContext("Service");
            TracingContext.SetUpStorage();
            TracingContext.SetRequestID("1");

            _testinghost = new TestingHost <IDemoService>();
            _stopTask    = _testinghost.RunAsync(new ServiceArguments(ServiceStartupMode.CommandLineNonInteractive));
        }
Ejemplo n.º 8
0
        public virtual void SetUp()
        {
            var kernel = new TestingKernel<ConsoleLog>();
            _insecureClient = kernel.Get<IDemoService>();
            _exceptionSerializer = kernel.Get<JsonExceptionSerializer>();

            Metric.ShutdownContext("Service");
            TracingContext.SetUpStorage();
            TracingContext.SetRequestID("1");

            _testinghost = new TestingHost<IDemoService>();
            _stopTask = _testinghost.RunAsync();
        }
Ejemplo n.º 9
0
        public async Task AllRequestsForSameCallID_SameHostSelected()
        {
            var port = DisposablePort.GetPort().Port;
            var dict = new Dictionary <string, string> {
                { "Discovery.Services.DemoService.Source", "Config" },
                { "Discovery.Services.DemoService.Hosts", "host1,host2" },
                { "Discovery.Services.DemoService.DefaultPort", port.ToString() }
            };

            Func <HttpClientConfiguration, HttpMessageHandler> messageHandlerFactory = _ =>
            {
                var messageHandler = new MockHttpMessageHandler();
                messageHandler
                .When("*")
                .Respond(req => HttpResponseFactory.GetResponse(content: $"'{req.RequestUri.Host}'"));
                return(messageHandler);
            };

            using (var kernel =
                       new TestingKernel <ConsoleLog>(
                           k =>
            {
                k.Rebind <IDiscovery>().To <ServiceDiscovery.Rewrite.Discovery>().InSingletonScope();
                k.Rebind <Func <HttpClientConfiguration, HttpMessageHandler> >().ToMethod(c => messageHandlerFactory);
            },
                           dict))
            {
                var providerFactory = kernel.Get <Func <string, ServiceProxyProvider> >();
                var serviceProxy    = providerFactory("DemoService");
                serviceProxy.DefaultPort = port;

                //If we set Request Id we would like always to select same Host
                TracingContext.SetRequestID("dumyId1");
                var request        = new HttpServiceRequest("testMethod", null, new Dictionary <string, object>());
                var hostOfFirstReq = (string)await serviceProxy.Invoke(request, typeof(string));

                string host;
                for (int i = 0; i < 50; i++)
                {
                    host = (string)await serviceProxy.Invoke(request, typeof(string));

                    host.ShouldBe(hostOfFirstReq);
                }

                TracingContext.SetRequestID("dumyId2");
                host = (string)await serviceProxy.Invoke(request, typeof(string));

                host.ShouldNotBe(hostOfFirstReq);
            }
        }
Ejemplo n.º 10
0
        private async Task <HttpServiceRequest> ParseRequest(HttpListenerContext context)
        {
            var request = await _deserializationTime.Time(async() =>
            {
                using (var streamReader = new StreamReader(context.Request.InputStream))
                {
                    var json = await streamReader.ReadToEndAsync();
                    return(JsonConvert.DeserializeObject <HttpServiceRequest>(json, JsonSettings));
                }
            });

            request.TracingData           = request.TracingData ?? new TracingData();
            request.TracingData.RequestID = request.TracingData.RequestID ?? Guid.NewGuid().ToString("N");

            TracingContext.SetRequestID(request.TracingData.RequestID);
            TracingContext.SetSpan(request.TracingData.SpanID, request.TracingData.ParentSpanID);
            return(request);
        }
Ejemplo n.º 11
0
        public async Task SingleGrainCall_CallSucceeds_PublishesEvent()
        {
            _flumeQueue.Clear();

            var requestId = nameof(SingleGrainCall_CallSucceeds_PublishesEvent) + Guid.NewGuid();

            TracingContext.SetRequestID(requestId);
            TracingContext.TryGetRequestID();

            await _serviceProxy.Add(5, 3);


            var events   = _flumeQueue.Events;
            var grainReq = events.Where(r => r.EventType == "grainReq")
                           .Select(r => (GrainCallEvent)r)
                           .Single(r => r.TargetType == typeof(CalculatorServiceGrain).FullName);

            Assert.AreEqual("Add", grainReq.TargetMethod);
            Assert.AreEqual(requestId, grainReq.RequestId);
        }
Ejemplo n.º 12
0
        public async Task AllRequestsForSameCallID_SameHostSelected()
        {
            var dict = new Dictionary <string, string> {
                { "Discovery.Services.DemoService.Source", "Config" },
                { "Discovery.Services.DemoService.Hosts", "host1,host2" },
                { "Discovery.Services.DemoService.DefaultPort", "5555" }
            };

            var kernel          = new TestingKernel <ConsoleLog>(k => k.Rebind <IDiscoverySourceLoader>().To <DiscoverySourceLoader>().InSingletonScope(), dict);
            var providerFactory = kernel.Get <Func <string, ServiceProxyProvider> >();
            var serviceProxy    = providerFactory("DemoService");



            var messageHandler = new MockHttpMessageHandler();

            messageHandler
            .When("*")
            .Respond(req => HttpResponseFactory.GetResponse(content: $"'{req.RequestUri.Host}'"));

            serviceProxy.HttpMessageHandler = messageHandler;

            //If we set Request Id we would like always to select same Host
            TracingContext.SetRequestID("dumyId1");
            var request        = new HttpServiceRequest("testMethod", new Dictionary <string, object>());
            var hostOfFirstReq = (string)await serviceProxy.Invoke(request, typeof(string));

            string host;

            for (int i = 0; i < 50; i++)
            {
                host = (string)await serviceProxy.Invoke(request, typeof(string));

                host.ShouldBe(hostOfFirstReq);
            }

            TracingContext.SetRequestID("dumyId2");
            host = (string)await serviceProxy.Invoke(request, typeof(string));

            host.ShouldNotBe(hostOfFirstReq);
        }
        private async Task <HttpServiceRequest> ParseRequest(HttpListenerContext context)
        {
            HttpServiceRequest request;

            using (var streamReader = new StreamReader(context.Request.InputStream))
            {
                var json = await streamReader.ReadToEndAsync();

                request = JsonConvert.DeserializeObject <HttpServiceRequest>(json, JsonSettings);
            }

            request.TracingData           = request.TracingData ?? new TracingData();
            request.TracingData.RequestID = request.TracingData.RequestID ?? Guid.NewGuid().ToString("N");

            TracingContext.SetRequestID(request.TracingData.RequestID);
            TracingContext.SetSpan(request.TracingData.SpanID, request.TracingData.ParentSpanID);
            TracingContext.SpanStartTime    = request.TracingData.SpanStartTime;
            TracingContext.AbandonRequestBy = request.TracingData.AbandonRequestBy;

            return(request);
        }
Ejemplo n.º 14
0
        public async Task SingleServerCall_CallSucceeds_PublishesEvent()
        {
            _flumeQueue.Clear();

            var requestId = nameof(SingleServerCall_CallSucceeds_PublishesEvent) + Guid.NewGuid();

            TracingContext.SetRequestID(requestId);
            TracingContext.TryGetRequestID();

            await _serviceProxy.Add(5, 3);

            await Task.Delay(100);

            var events    = _flumeQueue.Events;
            var serverReq = (ServiceCallEvent)events.Single();

            Assert.AreEqual("serverReq", serverReq.EventType);
            Assert.AreEqual(nameof(ICalculatorService), serverReq.ServiceName);
            Assert.AreEqual("Add", serverReq.ServiceMethod);
            Assert.AreEqual(requestId, serverReq.RequestId);
        }
Ejemplo n.º 15
0
        public async Task HttpsListening_CallHttpsAfterFirstHttpCall()
        {
            var host            = "host1";
            var httpsPortOffset = 5;
            var port            = DisposablePort.GetPort().Port;
            var dict            = new Dictionary <string, string>
            {
                { "Discovery.Services.DemoService.Source", "Config" },
                { "Discovery.Services.DemoService.Hosts", host },
                { "Discovery.Services.DemoService.DefaultPort", port.ToString() }
            };

            int httpsTestCount = 0;

            Func <bool, string, HttpMessageHandler> messageHandlerFactory = (_, __) =>
            {
                var messageHandler = new MockHttpMessageHandler();
                messageHandler
                .When("https://*")
                .Respond(req =>
                {
                    if (req.RequestUri.AbsoluteUri == $"https://{host}:{port + httpsPortOffset}/")
                    {
                        httpsTestCount++;
                        return(HttpResponseFactory.GetResponse(content: "'some HTTPS response'"));
                    }
                    if (req.RequestUri.AbsoluteUri == $"https://{host}:{port + httpsPortOffset}/DemoService.testMethod")
                    {
                        return(HttpResponseFactory.GetResponse(content: "'some HTTPS response'"));
                    }
                    throw new HttpRequestException("Invalid uri");
                });
                messageHandler
                .When("http://*")
                .Respond(req =>
                {
                    if (req.RequestUri.AbsoluteUri == $"http://{host}:{port}/DemoService.testMethod")
                    {
                        return(HttpResponseFactory.GetResponse(content: "'some HTTP response'"));
                    }
                    throw new HttpRequestException("Invalid uri");
                });

                return(messageHandler);
            };

            using (var kernel =
                       new TestingKernel <ConsoleLog>(
                           k =>
            {
                k.Rebind <IDiscovery>().To <ServiceDiscovery.Rewrite.Discovery>().InSingletonScope();
                k.Rebind <Func <bool, string, HttpMessageHandler> >().ToMethod(c => messageHandlerFactory);
            }, dict)
                   )
            {
                var providerFactory = kernel.Get <Func <string, ServiceProxyProvider> >();
                var serviceProxy    = providerFactory("DemoService");
                serviceProxy.DefaultPort = port;
                TracingContext.SetRequestID("1");

                var request = new HttpServiceRequest("testMethod", null, new Dictionary <string, object>());

                for (int i = 0; i < 10; i++)
                {
                    bool httpsTestFinished = httpsTestCount > 0;

                    var server = await serviceProxy.Invoke(request, typeof(string));

                    server.ShouldBe(httpsTestFinished ? "some HTTPS response" : "some HTTP response");
                }

                Assert.That(() => httpsTestCount, Is.EqualTo(1).After(10).Seconds.PollEvery(1).Seconds);
            }
        }
Ejemplo n.º 16
0
        public async Task HttpsDisabled_NoCertificate_CallSucceeds()
        {
            var host            = "host1";
            var httpsPortOffset = 5;
            var port            = DisposablePort.GetPort().Port;
            var dict            = new Dictionary <string, string>
            {
                { "Discovery.Services.DemoService.Source", "Config" },
                { "Discovery.Services.DemoService.Hosts", host },
                { "Discovery.Services.DemoService.DefaultPort", port.ToString() },
                { "Discovery.Services.DemoService.UseHttpsOverride", "false" }
            };

            int  httpsTestCount    = 0;
            bool httpsMethodCalled = false;

            Func <HttpClientConfiguration, HttpMessageHandler> messageHandlerFactory = _ =>
            {
                var messageHandler = new MockHttpMessageHandler();
                messageHandler
                .When("https://*")
                .Respond(req =>
                         HttpResponseFactory.GetResponseWithException(ExceptionSerializer, new SocketException()));

                messageHandler
                .When("http://*")
                .Respond(req => HttpResponseFactory.GetResponse(content: "'some HTTP response'"));

                return(messageHandler);
            };

            using (var kernel =
                       new TestingKernel <ConsoleLog>(
                           k =>
            {
                k.Rebind <IDiscovery>().To <ServiceDiscovery.Rewrite.Discovery>().InSingletonScope();
                k.Rebind <Func <HttpClientConfiguration, HttpMessageHandler> >().ToMethod(c => messageHandlerFactory);

                var certificateLocator = Substitute.For <ICertificateLocator>();
                certificateLocator
                .When(cl => cl.GetCertificate(Arg.Any <string>()))
                .Do(x => throw new Exception());
                k.Rebind <ICertificateLocator>().ToConstant(certificateLocator);

                var httpsAuthenticator = Substitute.For <IHttpsAuthenticator>();
                httpsAuthenticator
                .When(a => a.AddHttpMessageHandlerAuthentication(Arg.Any <HttpClientHandler>(), Arg.Any <HttpClientConfiguration>()))
                .Do(x => throw new Exception());
                k.Rebind <IHttpsAuthenticator>().ToConstant(httpsAuthenticator);
            }, dict)
                   )
            {
                var providerFactory = kernel.Get <Func <string, ServiceProxyProvider> >();
                var serviceProxy    = providerFactory("DemoService");
                serviceProxy.DefaultPort = port;
                TracingContext.SetRequestID("1");

                var request = new HttpServiceRequest("testMethod", null, new Dictionary <string, object>());

                await serviceProxy.Invoke(request, typeof(string));
            }
        }
Ejemplo n.º 17
0
        public async Task HttpsStoppedListening_FallbackToHttp()
        {
            var host            = "host1";
            var httpsPortOffset = 5;
            var port            = DisposablePort.GetPort().Port;
            var dict            = new Dictionary <string, string>
            {
                { "Discovery.Services.DemoService.Source", "Config" },
                { "Discovery.Services.DemoService.Hosts", host },
                { "Discovery.Services.DemoService.DefaultPort", port.ToString() },
                { "Discovery.Services.DemoService.TryHttps", "true" }
            };

            int  httpsTestCount    = 0;
            bool httpsMethodCalled = false;

            Func <HttpClientConfiguration, HttpMessageHandler> messageHandlerFactory = _ =>
            {
                var messageHandler = new MockHttpMessageHandler();
                messageHandler
                .When("https://*")
                .Respond(req =>
                {
                    if (httpsMethodCalled)
                    {
                        throw new HttpRequestException("", new WebException("", WebExceptionStatus.ProtocolError));
                    }
                    if (req.RequestUri.AbsoluteUri == $"https://{host}:{port + httpsPortOffset}/")
                    {
                        httpsTestCount++;
                        return(HttpResponseFactory.GetResponse(content: "'some HTTPS response'"));
                    }

                    if (req.RequestUri.AbsoluteUri == $"https://{host}:{port + httpsPortOffset}/DemoService.testMethod")
                    {
                        httpsMethodCalled = true;
                        return(HttpResponseFactory.GetResponse(content: "'some HTTPS response'"));
                    }

                    throw new HttpRequestException("Invalid uri");
                });
                messageHandler
                .When("http://*")
                .Respond(req =>
                {
                    if (req.RequestUri.AbsoluteUri == $"http://{host}:{port}/DemoService.testMethod")
                    {
                        return(HttpResponseFactory.GetResponse(content: "'some HTTP response'"));
                    }
                    if (req.RequestUri.AbsoluteUri == $"http://{host}:{port}/")
                    {
                        return(HttpResponseFactory.GetResponse(content: "'{X-Gigya-ServerHostname: someValue}'"));
                    }
                    throw new HttpRequestException("Invalid uri");
                });

                return(messageHandler);
            };

            using (var kernel =
                       new TestingKernel <ConsoleLog>(
                           k =>
            {
                k.Rebind <IDiscovery>().To <ServiceDiscovery.Rewrite.Discovery>().InSingletonScope();
                k.Rebind <Func <HttpClientConfiguration, HttpMessageHandler> >().ToMethod(c => messageHandlerFactory);
                var getConfig = k.Get <Func <DiscoveryConfig> >();
                k.Rebind <Func <DiscoveryConfig> >().ToMethod(c =>
                {
                    var config = getConfig();
                    config.UseHttpsOverride = false;

                    return(() => config);
                });
            }, dict)
                   )
            {
                var providerFactory = kernel.Get <Func <string, ServiceProxyProvider> >();
                var serviceProxy    = providerFactory("DemoService");
                serviceProxy.DefaultPort = port;
                TracingContext.SetRequestID("1");

                var request = new HttpServiceRequest("testMethod", null, new Dictionary <string, object>());

                var server = await serviceProxy.Invoke(request, typeof(string));

                server.ShouldBe("some HTTP response");

                Assert.That(() => httpsTestCount, Is.EqualTo(1).After(10).Seconds.PollEvery(1).Seconds);

                server = await serviceProxy.Invoke(request, typeof(string));

                server.ShouldBe("some HTTPS response");

                server = await serviceProxy.Invoke(request, typeof(string));

                server.ShouldBe("some HTTP response");
            }
        }
Ejemplo n.º 18
0
        private async Task HandleRequest(HttpListenerContext context)
        {
            RequestTimings.ClearCurrentTimings();
            using (context.Response)
            {
                var sw = Stopwatch.StartNew();

                // Special endpoints should not be logged/measured/traced like regular endpoints
                if (await TryHandleSpecialEndpoints(context))
                {
                    return;
                }

                // Regular endpoint handling
                using (_activeRequestsCounter.NewContext("Request"))
                {
                    RequestTimings.GetOrCreate(); // initialize request timing context

                    string methodName = null;
                    // Initialize with empty object for protocol backwards-compatibility.

                    var requestData = new HttpServiceRequest {
                        TracingData = new TracingData()
                    };
                    object[]         argumentsWithDefaults = null;
                    ServiceMethod    serviceMethod         = null;
                    ServiceCallEvent callEvent             = _serverRequestPublisher.GetNewCallEvent();
                    try
                    {
                        try
                        {
                            ValidateRequest(context);
                            await CheckSecureConnection(context);

                            requestData = await ParseRequest(context);


                            //-----------------------------------------------------------------------------------------
                            // Don't move TracingContext writes main flow, IT have to be here, to avoid side changes
                            //-----------------------------------------------------------------------------------------
                            TracingContext.SetRequestID(requestData.TracingData.RequestID);
                            TracingContext.SpanStartTime    = requestData.TracingData.SpanStartTime;
                            TracingContext.AbandonRequestBy = requestData.TracingData.AbandonRequestBy;
                            TracingContext.SetParentSpan(requestData.TracingData.SpanID ?? Guid.NewGuid().ToString("N"));

                            SetCallEventRequestData(callEvent, requestData);

                            TracingContext.SetOverrides(requestData.Overrides);

                            serviceMethod = ServiceEndPointDefinition.Resolve(requestData.Target);
                            callEvent.CalledServiceName = serviceMethod.GrainInterfaceType.Name;
                            methodName = serviceMethod.ServiceInterfaceMethod.Name;
                            var arguments = requestData.Target.IsWeaklyTyped ? GetParametersByName(serviceMethod, requestData.Arguments) : requestData.Arguments.Values.Cast <object>().ToArray();
                            argumentsWithDefaults = GetConvertedAndDefaultArguments(serviceMethod.ServiceInterfaceMethod, arguments);
                        }
                        catch (Exception e)
                        {
                            callEvent.Exception = e;
                            if (e is RequestException)
                            {
                                throw;
                            }

                            throw new RequestException("Invalid request", e);
                        }

                        RejectRequestIfLateOrOverloaded();

                        var responseJson = await GetResponse(context, serviceMethod, requestData, argumentsWithDefaults);

                        if (await TryWriteResponse(context, responseJson, serviceCallEvent: callEvent))
                        {
                            callEvent.ErrCode = 0;
                            _successCounter.Increment();
                        }
                        else
                        {
                            _failureCounter.Increment();
                        }
                    }
                    catch (Exception e)
                    {
                        callEvent.Exception = callEvent.Exception ?? e;
                        _failureCounter.Increment();
                        Exception ex   = GetRelevantException(e);
                        string    json = _serializationTime.Time(() => ExceptionSerializer.Serialize(ex));
                        await TryWriteResponse(context, json, GetExceptionStatusCode(ex), serviceCallEvent : callEvent);
                    }
                    finally
                    {
                        sw.Stop();
                        callEvent.ActualTotalTime = sw.Elapsed.TotalMilliseconds;

                        _roundtripTime.Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds);
                        if (methodName != null)
                        {
                            _endpointContext.Timer(methodName, Unit.Requests).Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds);
                        }

                        _serverRequestPublisher.TryPublish(callEvent, argumentsWithDefaults, serviceMethod);
                    }
                }
            }
        }
Ejemplo n.º 19
0
        private async Task HandleRequest(HttpListenerContext context, long ticks, long timeFromLastReq)
        {
            try
            {
                var deltaDelayTicks = DateTime.UtcNow.Ticks - ticks;
                var sw = Stopwatch.StartNew();
                RequestTimings.ClearCurrentTimings();
                using (context.Response)
                {
                    // Special endpoints should not be logged/measured/traced like regular endpoints
                    // Access is allowed without HTTPS verifications since they don't expose anything sensitive (e.g. config values are encrypted)
                    if (await TryHandleSpecialEndpoints(context))
                    {
                        return;
                    }

                    // Regular endpoint handling
                    using (_activeRequestsCounter.NewContext("Request"))
                    {
                        RequestTimings.GetOrCreate(); // initialize request timing context

                        string methodName = null;
                        // Initialize with empty object for protocol backwards-compatibility.

                        var requestData = new HttpServiceRequest {
                            TracingData = new TracingData()
                        };
                        object[]         argumentsWithDefaults = null;
                        ServiceMethod    serviceMethod         = null;
                        ServiceCallEvent callEvent             = _serverRequestPublisher.GetNewCallEvent();
                        try
                        {
                            try
                            {
                                await CheckSecureConnection(context);

                                ValidateRequest(context);

                                requestData = await ParseRequest(context);


                                //-----------------------------------------------------------------------------------------
                                // Don't move TracingContext writes main flow, IT have to be here, to avoid side changes
                                //-----------------------------------------------------------------------------------------
                                TracingContext.SetRequestID(requestData.TracingData.RequestID);
                                TracingContext.SpanStartTime    = requestData.TracingData.SpanStartTime;
                                TracingContext.AbandonRequestBy = requestData.TracingData.AbandonRequestBy;
                                TracingContext.SetParentSpan(
                                    requestData.TracingData.SpanID ?? Guid.NewGuid().ToString("N"));
                                TracingContext.SetOverrides(requestData.Overrides);
                                if (requestData.TracingData.Tags != null)
                                {
                                    TracingContext.Tags = new ContextTags(requestData.TracingData.Tags);
                                }
                                TracingContext.AdditionalProperties = requestData.TracingData.AdditionalProperties;

                                callEvent.ServiceMethodSchema = context.Request.IsSecureConnection ? "HTTPS" : "HTTP";
                                SetCallEventRequestData(callEvent, requestData);

                                serviceMethod = ServiceEndPointDefinition.Resolve(requestData.Target);
                                callEvent.CalledServiceName = serviceMethod.GrainInterfaceType.Name;
                                methodName = serviceMethod.ServiceInterfaceMethod.Name;
                                var arguments = requestData.Target.IsWeaklyTyped
                                    ? GetParametersByName(serviceMethod, requestData.Arguments)
                                    : requestData.Arguments.Values.Cast <object>().ToArray();
                                argumentsWithDefaults =
                                    GetConvertedAndDefaultArguments(serviceMethod.ServiceInterfaceMethod, arguments);

                                if (_extendedDelayTimeLogging)
                                {
                                    callEvent.RecvDateTicks        = ticks;
                                    callEvent.ReqStartupDeltaTicks = deltaDelayTicks;
                                    callEvent.TimeFromLastReq      = timeFromLastReq;
                                    var outstandingReqs = Interlocked.Read(ref OutstandingRequests);
                                    callEvent.OutstandingRequests = outstandingReqs;
                                    if (deltaDelayTicks > 10_000_000)
                                    {
                                        callEvent.CollectionCountGen0 = GC.CollectionCount(0);
                                        callEvent.CollectionCountGen1 = GC.CollectionCount(1);
                                        callEvent.CollectionCountGen2 = GC.CollectionCount(2);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                callEvent.Exception = e;
                                if (e is RequestException)
                                {
                                    throw;
                                }

                                throw new RequestException("Invalid request", e);
                            }

                            RejectRequestIfLateOrOverloaded();

                            var responseJson = await GetResponse(context, serviceMethod, requestData,
                                                                 argumentsWithDefaults);

                            if (await TryWriteResponse(context, responseJson, serviceCallEvent: callEvent))
                            {
                                callEvent.ErrCode = 0;
                                _successCounter.Increment();
                            }
                            else
                            {
                                _failureCounter.Increment();
                            }
                        }
                        catch (Exception e)
                        {
                            callEvent.Exception = callEvent.Exception ?? e;
                            _failureCounter.Increment();
                            Exception ex   = GetRelevantException(e);
                            string    json = _serializationTime.Time(() => ExceptionSerializer.Serialize(ex));
                            await TryWriteResponse(context, json, GetExceptionStatusCode(ex),
                                                   serviceCallEvent : callEvent);
                        }
                        finally
                        {
                            sw.Stop();
                            callEvent.ActualTotalTime = sw.Elapsed.TotalMilliseconds;

                            _roundtripTime.Record((long)(sw.Elapsed.TotalMilliseconds * 1000000),
                                                  TimeUnit.Nanoseconds);
                            if (methodName != null)
                            {
                                _endpointContext.Timer(methodName, Unit.Requests)
                                .Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds);
                            }

                            _serverRequestPublisher.TryPublish(callEvent, argumentsWithDefaults, serviceMethod);
                        }
                    }
                }
            }
            finally
            {
                Interlocked.Decrement(ref OutstandingRequests);
            }
        }