Ejemplo n.º 1
0
 private void PushEvent(ServiceCallEvent e)
 {
     lock (_service_call_queue_lock)
     {
         serviceCallQueue.Enqueue(e);
     }
 }
Ejemplo n.º 2
0
 private void SetCallEventRequestData(ServiceCallEvent callEvent, HttpServiceRequest requestData)
 {
     callEvent.ClientMetadata = requestData.TracingData;
     callEvent.ServiceMethod  = requestData.Target?.MethodName;
     callEvent.RequestId      = requestData.TracingData?.RequestID;
     callEvent.SpanId         = requestData.TracingData?.SpanID;
     callEvent.ParentSpanId   = requestData.TracingData?.ParentSpanID;
 }
Ejemplo n.º 3
0
 private void SetCallEventRequestData(ServiceCallEvent callEvent, HttpServiceRequest requestData)
 {
     callEvent.ClientMetadata         = requestData.TracingData;
     callEvent.ServiceMethod          = requestData.Target?.MethodName;
     callEvent.RequestId              = requestData.TracingData?.RequestID;
     callEvent.SpanId                 = requestData.TracingData?.SpanID;
     callEvent.ParentSpanId           = requestData.TracingData?.ParentSpanID;
     callEvent.ContextUnencryptedTags = requestData.TracingData?.Tags?.GetUnencryptedTags();
     callEvent.ContextTagsEncrypted   = requestData.TracingData?.Tags?.GetEncryptedTags();
     callEvent.UnknownTracingData     = requestData.TracingData?.AdditionalProperties;
 }
Ejemplo n.º 4
0
        public void TryPublish(ServiceCallEvent callEvent, IEnumerable <DictionaryEntry> arguments, ServiceMethod serviceMethod)
        {
            EndPointMetadata metaData = _serviceEndPointDefinition.GetMetaData(serviceMethod);

            callEvent.Params = arguments.SelectMany(_ => ExtractParamValues(_, metaData)).Select(_ => new Param
            {
                Name        = _.name,
                Value       = _.value,
                Sensitivity = _.sensitivity,
            });

            _eventPublisher.TryPublish(callEvent);
        }
Ejemplo n.º 5
0
        public void TryPublish(ServiceCallEvent callEvent, object[] arguments, ServiceMethod serviceMethod)
        {
            try
            {
                if (arguments != null)
                {
                    callEvent.Params = ExtractParamValues(arguments, serviceMethod);
                }
            }
            catch (Exception e)
            {
                _log.Error("Can not extract params from request", exception: e,
                           unencryptedTags: new { serviceInterfaceMethod = serviceMethod.ServiceInterfaceMethod.Name });
            }

            _eventPublisher.TryPublish(callEvent);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// IUnityUpdatable update method, that will be called by uOS to process events
        /// inside Unity's thread.
        /// </summary>
        public void Update()
        {
            // Processes async events...
            lock (_service_call_queue_lock)
            {
                while (serviceCallQueue.Count > 0)
                {
                    ServiceCallEvent e = serviceCallQueue.Dequeue();
                    e.callback(e.info, e.response, e.exception);
                }
            }

            // Updates server and radar.
            server.Update();
            if (radar != null)
            {
                radar.Update();
            }
        }
Ejemplo n.º 7
0
        public async Task PublishExceptionEvent_WhileShouldExcludeStackTraceForFlume()
        {
            var evt = new ServiceCallEvent
            {
                Exception = new ArgumentException("Test Test").ThrowAndCatch()
            };

            var serializedEvent = SerializerWithoutStackTrace.Serialize(evt).ToDictionary(_ => _.Name, _ => _.Value);

            serializedEvent.ShouldContainKey(EventConsts.exMessage);
            serializedEvent[EventConsts.exMessage].ShouldBe("Test Test");

            serializedEvent.ShouldContainKey(EventConsts.exOneWordMessage);
            serializedEvent[EventConsts.exOneWordMessage].ShouldBe("Test_Test");

            serializedEvent.ShouldContainKey(EventConsts.exType);
            serializedEvent[EventConsts.exType].ShouldBe(typeof(ArgumentException).FullName);

            serializedEvent.ShouldNotContainKey(EventConsts.exInnerMessages);
            serializedEvent.ShouldNotContainKey(EventConsts.exStackTrace);
        }
Ejemplo n.º 8
0
        private async Task WriteResponseAndMeasureTime(HttpListenerContext context, byte[] body, ServiceCallEvent serviceCallEvent = null)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();
            await context.Response.OutputStream.WriteAsync(body, 0, body.Length);

            sw.Stop();

            if (serviceCallEvent != null)
            {
                serviceCallEvent.ClientResponseTime = sw.Elapsed.TotalMilliseconds;
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Writes to response output stream and returns response time
        /// </summary>
        /// <param name="context"></param>
        /// <param name="data"></param>
        /// <param name="httpStatus"></param>
        /// <param name="contentType"></param>
        /// <returns>double? - response time</returns>
        private async Task <bool> TryWriteResponse(HttpListenerContext context, string data, HttpStatusCode httpStatus = HttpStatusCode.OK, string contentType = "application/json", ServiceCallEvent serviceCallEvent = null)
        {
            context.Response.Headers.Add(GigyaHttpHeaders.ProtocolVersion, HttpServiceRequest.ProtocolVersion);

            var body = Encoding.UTF8.GetBytes(data ?? "");

            context.Response.StatusCode      = (int)httpStatus;
            context.Response.ContentLength64 = body.Length;
            context.Response.ContentType     = contentType;
            context.Response.Headers.Add(GigyaHttpHeaders.DataCenter, Environment.Zone);
            context.Response.Headers.Add(GigyaHttpHeaders.Environment, Environment.DeploymentEnvironment);
            context.Response.Headers.Add(GigyaHttpHeaders.ServiceVersion, AppInfo.Version.ToString());
            context.Response.Headers.Add(GigyaHttpHeaders.ServerHostname, CurrentApplicationInfo.HostName);
            context.Response.Headers.Add(GigyaHttpHeaders.SchemaHash, ServiceSchema.Hash);

            try
            {
                await WriteResponseAndMeasureTime(context, body, serviceCallEvent);

                return(true);
            }
            catch (HttpListenerException writeEx)
            {
                if (serviceCallEvent != null)
                {
                    serviceCallEvent.Exception = writeEx;
                }
                // For some reason, HttpListener.IgnoreWriteExceptions doesn't work here.
                Log.Warn(_ => _("HttpServiceListener: Failed to write the response of a service call. See exception and tags for details.",
                                exception: writeEx,
                                unencryptedTags: new
                {
                    remoteEndpoint = context.Request.RemoteEndPoint,
                    rawUrl         = context.Request.RawUrl,
                    status         = httpStatus
                },
                                encryptedTags: new { response = data }));
                return(false);
            }
        }
Ejemplo n.º 10
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);
            }
        }
Ejemplo n.º 11
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.º 12
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"))
                {
                    TracingContext.SetUpStorage();
                    RequestTimings.GetOrCreate(); // initialize request timing context

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

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

                            requestData = await ParseRequest(context);

                            SetCallEventRequestData(callEvent, requestData);

                            TracingContext.SetOverrides(requestData.Overrides);

                            serviceMethod = ServiceEndPointDefinition.Resolve(requestData.Target);
                            callEvent.CalledServiceName = serviceMethod.GrainInterfaceType.Name;
                            methodName = serviceMethod.ServiceInterfaceMethod.Name;
                        }
                        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);

                        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);
                        }

                        IEnumerable <DictionaryEntry> arguments = (requestData.Arguments ?? new OrderedDictionary()).Cast <DictionaryEntry>();
                        _serverRequestPublisher.TryPublish(callEvent, arguments, serviceMethod);
                    }
                }
            }
        }
Ejemplo n.º 13
0
 private void PushEvent(ServiceCallEvent e)
 {
     lock (_service_call_queue_lock)
     {
         serviceCallQueue.Enqueue(e);
     }
 }