Пример #1
0
        private bool IsSpecified(JsonWriter writer, JsonProperty property, object target)
        {
            if (property.GetIsSpecified == null)
            {
                return(true);
            }

            bool isSpecified = property.GetIsSpecified(target);

            if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
            {
                TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "IsSpecified result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, isSpecified)), null);
            }

            return(isSpecified);
        }
Пример #2
0
        private bool ShouldSerialize(JsonWriter writer, JsonProperty property, object target)
        {
            if (property.ShouldSerialize == null)
            {
                return(true);
            }

            bool shouldSerialize = property.ShouldSerialize(target);

            if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
            {
                TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "ShouldSerialize result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, shouldSerialize)), null);
            }

            return(shouldSerialize);
        }
Пример #3
0
        /// <summary>
        /// Emit the provided log event to an Azure WebJobs <see cref="TraceWriter"/>.
        /// </summary>
        /// <param name="logEvent">The log event to write.</param>
        public void Emit(LogEvent logEvent)
        {
            if (logEvent == null)
            {
                throw new ArgumentNullException(nameof(logEvent));
            }

            lock (_lock)
            {
                TraceLevel traceLevel = GetTraceLevel(logEvent.Level);
                string     message    = logEvent.RenderMessage(_formatProvider);
                Exception  exception  = logEvent.Exception;

                var traceEvent = new TraceEvent(traceLevel, message, SourceName, exception);
                _trace.Trace(traceEvent);
            }
        }
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            IEnumerable <KeyValuePair <string, object> > properties = state as IEnumerable <KeyValuePair <string, object> >;
            string formattedMessage = formatter?.Invoke(state, exception);

            // If we have no structured data and no message, there's nothing to log
            if ((string.IsNullOrEmpty(formattedMessage) && properties == null) ||
                !IsEnabled(logLevel))
            {
                return;
            }

            TraceEvent traceEvent = new TraceEvent(logLevel.ToTraceLevel(), formattedMessage, _categoryName, exception);

            TraceWriter traceWriter = _traceWriterFactory.Create(_language, "Worker");

            traceWriter.Trace(traceEvent);
        }
Пример #5
0
        public void Initialize(ExtensionConfigContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            else if (context.Trace == null)
            {
                throw new ArgumentNullException("context.Trace");
            }
            _tracer = context.Trace;

            Uri url = context.GetWebhookHandler();

            _tracer.Trace(new TraceEvent(System.Diagnostics.TraceLevel.Info, $"registered EventGrid Endpoint = {url}"));

            // Register our extension binding providers
            context.Config.RegisterBindingExtension(new EventGridTriggerAttributeBindingProvider(this));
        }
Пример #6
0
        public static void Trace(this TraceWriter traceWriter, string message, TraceLevel level, IDictionary <string, object> properties)
        {
            TraceEvent traceEvent = CreateEvent(message, level, properties);

            traceWriter.Trace(traceEvent);
        }
Пример #7
0
 protected void TraceOnPrimaryHost(string message, TraceLevel level)
 {
     TraceWriter.Trace(message, level, PrimaryHostTraceProperties);
 }
        private async Task <HttpResponseMessage> ProcessAsync(HttpRequestMessage req)
        {
            // webjobs.script uses req.GetQueryNameValuePairs();
            // which requires webapi.core...but this does not work for .netframework2.0
            // TODO change this once webjobs.script is migrated
            var functionName = HttpUtility.ParseQueryString(req.RequestUri.Query)["functionName"];

            if (String.IsNullOrEmpty(functionName) || !_listeners.ContainsKey(functionName))
            {
                _tracer.Trace(new TraceEvent(System.Diagnostics.TraceLevel.Info,
                                             $"cannot find function: '{functionName}', available function names: [{string.Join(", ", _listeners.Keys.ToArray())}]"));
                return(new HttpResponseMessage(HttpStatusCode.NotFound));
            }

            IEnumerable <string> eventTypeHeaders = null;
            string eventTypeHeader = null;

            if (req.Headers.TryGetValues("aeg-event-type", out eventTypeHeaders))
            {
                eventTypeHeader = eventTypeHeaders.First();
            }

            if (String.Equals(eventTypeHeader, "SubscriptionValidation", StringComparison.OrdinalIgnoreCase))
            {
                string jsonArray = await req.Content.ReadAsStringAsync();

                SubscriptionValidationEvent validationEvent = null;
                List <JObject> events = JsonConvert.DeserializeObject <List <JObject> >(jsonArray);
                // TODO remove unnecessary serialization
                validationEvent = ((JObject)events[0]["data"]).ToObject <SubscriptionValidationEvent>();
                SubscriptionValidationResponse validationResponse = new SubscriptionValidationResponse {
                    ValidationResponse = validationEvent.ValidationCode
                };
                var returnMessage = new HttpResponseMessage(HttpStatusCode.OK);
                returnMessage.Content = new StringContent(JsonConvert.SerializeObject(validationResponse));
                _tracer.Trace(new TraceEvent(System.Diagnostics.TraceLevel.Info,
                                             $"perform handshake with eventGrid for endpoint: {req.RequestUri}"));
                return(returnMessage);
            }
            else if (String.Equals(eventTypeHeader, "Notification", StringComparison.OrdinalIgnoreCase))
            {
                string jsonArray = await req.Content.ReadAsStringAsync();

                List <JObject> events = JsonConvert.DeserializeObject <List <JObject> >(jsonArray);

                foreach (var ev in events)
                {
                    TriggeredFunctionData triggerData = new TriggeredFunctionData
                    {
                        TriggerValue = ev
                    };

                    await _listeners[functionName].Executor.TryExecuteAsync(triggerData, CancellationToken.None);
                }

                return(new HttpResponseMessage(HttpStatusCode.Accepted));
            }
            else if (String.Equals(eventTypeHeader, "Unsubscribe", StringComparison.OrdinalIgnoreCase))
            {
                // TODO disable function?
                return(new HttpResponseMessage(HttpStatusCode.Accepted));
            }

            return(new HttpResponseMessage(HttpStatusCode.BadRequest));
        }
        internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
        {
            ValidationUtils.ArgumentNotNull(reader, "reader");

            // set serialization options onto reader
            CultureInfo previousCulture = null;

            if (_culture != null && !_culture.Equals(reader.Culture))
            {
                previousCulture = reader.Culture;
                reader.Culture  = _culture;
            }

            DateTimeZoneHandling?previousDateTimeZoneHandling = null;

            if (_dateTimeZoneHandling != null && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
            {
                previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
                reader.DateTimeZoneHandling  = _dateTimeZoneHandling.Value;
            }

            DateParseHandling?previousDateParseHandling = null;

            if (_dateParseHandling != null && reader.DateParseHandling != _dateParseHandling)
            {
                previousDateParseHandling = reader.DateParseHandling;
                reader.DateParseHandling  = _dateParseHandling.Value;
            }

            FloatParseHandling?previousFloatParseHandling = null;

            if (_floatParseHandling != null && reader.FloatParseHandling != _floatParseHandling)
            {
                previousFloatParseHandling = reader.FloatParseHandling;
                reader.FloatParseHandling  = _floatParseHandling.Value;
            }

            int?previousMaxDepth = null;

            if (_maxDepthSet && reader.MaxDepth != _maxDepth)
            {
                previousMaxDepth = reader.MaxDepth;
                reader.MaxDepth  = _maxDepth;
            }

            TraceJsonReader traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
                                          ? new TraceJsonReader(reader)
                                          : null;

            JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
            object value = serializerReader.Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);

            if (traceJsonReader != null)
            {
                TraceWriter.Trace(TraceLevel.Verbose, "Deserialized JSON: " + Environment.NewLine + traceJsonReader.GetJson(), null);
            }

            // reset reader back to previous options
            if (previousCulture != null)
            {
                reader.Culture = previousCulture;
            }
            if (previousDateTimeZoneHandling != null)
            {
                reader.DateTimeZoneHandling = previousDateTimeZoneHandling.Value;
            }
            if (previousDateParseHandling != null)
            {
                reader.DateParseHandling = previousDateParseHandling.Value;
            }
            if (previousFloatParseHandling != null)
            {
                reader.FloatParseHandling = previousFloatParseHandling.Value;
            }
            if (_maxDepthSet)
            {
                reader.MaxDepth = previousMaxDepth;
            }

            return(value);
        }
Пример #10
0
        public static async Task <HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
        {
            var url          = string.Empty;
            var stopwatch    = Stopwatch.StartNew();
            var jsonResponse = string.Empty;

            try
            {
                var reqBodyStr = await req.Content.ReadAsStringAsync();

                var reqBody = JsonConvert.DeserializeObject <URLHolder>(reqBodyStr);

                url = reqBody.Url;
                if (!string.IsNullOrEmpty(reqBody.Parameter))
                {
                    url += reqBody.Parameter;
                }

                log.Info("RSS " + url);

                // TODO: use HttpCachedService (also as means of failover if the RSS stream is down)
                string data = await client.GetStringAsync(reqBody.Url.ToString());

                var rss = XDocument.Parse(data);

                string parseFormat  = "ddd, dd MMM yyyy HH:mm:ss zzz";
                string parseFormat2 = "ddd, dd MMM yyyy HH:mm:ss Z";

                var items = rss.DescendantNodes()
                            .OfType <XElement>()
                            .Where(a => a.Name == "item")
                            .Select((elem, index) =>
                {
                    var pubDateStr = elem.Descendants("pubDate").FirstOrDefault()?.Value;
                    if (pubDateStr != null)
                    {
                        pubDateStr = pubDateStr.Trim();
                    }

                    DateTime pubDate;
                    if (!DateTime.TryParseExact(pubDateStr, parseFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out pubDate))
                    {
                        if (!DateTime.TryParseExact(pubDateStr, parseFormat2, CultureInfo.InvariantCulture, DateTimeStyles.None, out pubDate))
                        {
                            pubDate = DateTime.UtcNow;
                        }
                    }

                    return(new { elem, pubDate, index });
                })
                            .OrderByDescending(elem => elem.pubDate)
                            // limit the feed to avoid getting too many
                            .Take(15)
                            // Note: this is very important for the Dashboard
                            // The order of the items allows customers to specify their base-line policy
                            .OrderBy(elem => elem.index)
                            .Select(x => x.elem);

                var actions = items.Select(x => new
                {
                    ids      = new[] { new { id = x.Descendants("link").FirstOrDefault()?.Value } },
                    features = new
                    {
                        _title = x.Descendants("title").FirstOrDefault()?.Value
                    },
                    details = new []
                    {
                        // TODO: properly support 4.2.6.  The "atom:id" Element
                        new { guid = x.Descendants("guid").FirstOrDefault()?.Value }
                    }
                }).ToList();

                jsonResponse = JsonConvert.SerializeObject(actions);

                if (log.Level == TraceLevel.Verbose)
                {
                    log.Trace(new TraceEvent(TraceLevel.Verbose, $"Successfully transformed '{url}' '{data}' to '{jsonResponse}'"));
                }
                else
                {
                    log.Info($"Successfully transformed '{url}'");
                }
            }
            catch (HttpRequestException hre)
            {
                var msg = $"RSS Featurization failed '{url}' for '{req.RequestUri.ToString()}': '{hre.Message}'";

                log.Warning(msg);
                // TODO: maybe switch to dependency w/ status failed?
                Services.TelemetryClient.TrackEvent(msg,
                                                    new Dictionary <string, string>
                {
                    { "Service", req.RequestUri.ToString() },
                    { "Url", url },
                    { "Exception", hre.Message }
                });
            }
            catch (Exception ex)
            {
                log.Error($"Failed to process '{url}'", ex);

                Services.TelemetryClient.TrackException(
                    ex,
                    new Dictionary <string, string>
                {
                    { "Service", req.RequestUri.ToString() },
                    { "Url", url }
                });

                // swallow the error message and return empty. That way we can differentiate between real outages
                // remote errors
            }
            finally
            {
                Services.TelemetryClient.TrackEvent($"RSS {url}",
                                                    metrics: new Dictionary <string, double>
                {
                    { "requestTime", stopwatch.ElapsedMilliseconds }
                });
            }

            return(new HttpResponseMessage(System.Net.HttpStatusCode.OK)
            {
                Content = new StringContent(
                    jsonResponse,
                    new UTF8Encoding(encoderShouldEmitUTF8Identifier: false),
                    "application/json")
            });
        }
 public void Log(TraceLevel level, string message, Exception ex)
 {
     // Route all logs coming from the WebHooks SDK to the WebJobs SDK
     // as Verbose.
     _traceWriter.Trace(new TraceEvent(System.Diagnostics.TraceLevel.Verbose, message, null, ex));
 }
        private async Task <HttpResponseMessage> ProcessAsync(HttpRequestMessage req)
        {
            // webjobs.script uses req.GetQueryNameValuePairs();
            // which requires webapi.core...but this does not work for .netframework2.0
            // TODO change this once webjobs.script is migrated
            var functionName = HttpUtility.ParseQueryString(req.RequestUri.Query)["functionName"];

            if (String.IsNullOrEmpty(functionName) || !_listeners.ContainsKey(functionName))
            {
                _tracer.Trace(new TraceEvent(System.Diagnostics.TraceLevel.Info,
                                             $"cannot find function: '{functionName}', available function names: [{string.Join(", ", _listeners.Keys.ToArray())}]"));
                return(new HttpResponseMessage(HttpStatusCode.NotFound)
                {
                    Content = new StringContent($"cannot find function: '{functionName}'")
                });
            }

            IEnumerable <string> eventTypeHeaders = null;
            string eventTypeHeader = null;

            if (req.Headers.TryGetValues("aeg-event-type", out eventTypeHeaders))
            {
                eventTypeHeader = eventTypeHeaders.First();
            }

            if (String.Equals(eventTypeHeader, "SubscriptionValidation", StringComparison.OrdinalIgnoreCase))
            {
                string jsonArray = await req.Content.ReadAsStringAsync();

                SubscriptionValidationEvent validationEvent = null;
                List <JObject> events = JsonConvert.DeserializeObject <List <JObject> >(jsonArray);
                // TODO remove unnecessary serialization
                validationEvent = ((JObject)events[0]["data"]).ToObject <SubscriptionValidationEvent>();
                SubscriptionValidationResponse validationResponse = new SubscriptionValidationResponse {
                    ValidationResponse = validationEvent.ValidationCode
                };
                var returnMessage = new HttpResponseMessage(HttpStatusCode.OK);
                returnMessage.Content = new StringContent(JsonConvert.SerializeObject(validationResponse));
                _tracer.Trace(new TraceEvent(System.Diagnostics.TraceLevel.Info,
                                             $"perform handshake with eventGrid for function: {functionName}"));
                return(returnMessage);
            }
            else if (String.Equals(eventTypeHeader, "Notification", StringComparison.OrdinalIgnoreCase))
            {
                JArray events         = null;
                string requestContent = await req.Content.ReadAsStringAsync();

                var token = JToken.Parse(requestContent);
                if (token.Type == JTokenType.Array)
                {
                    // eventgrid schema
                    events = (JArray)token;
                }
                else if (token.Type == JTokenType.Object)
                {
                    // cloudevent schema
                    events = new JArray
                    {
                        token
                    };
                }

                List <Task <FunctionResult> > executions = new List <Task <FunctionResult> >();
                foreach (var ev in events)
                {
                    // assume each event is a JObject
                    TriggeredFunctionData triggerData = new TriggeredFunctionData
                    {
                        TriggerValue = ev
                    };
                    executions.Add(_listeners[functionName].Executor.TryExecuteAsync(triggerData, CancellationToken.None));
                }
                await Task.WhenAll(executions);

                // FIXME without internal queuing, we are going to process all events in parallel
                // and return 500 if there's at least one failure...which will cause EventGrid to resend the entire payload
                foreach (var execution in executions)
                {
                    if (!execution.Result.Succeeded)
                    {
                        return(new HttpResponseMessage(HttpStatusCode.InternalServerError)
                        {
                            Content = new StringContent(execution.Result.Exception.Message)
                        });
                    }
                }

                return(new HttpResponseMessage(HttpStatusCode.Accepted));
            }
            else if (String.Equals(eventTypeHeader, "Unsubscribe", StringComparison.OrdinalIgnoreCase))
            {
                // TODO disable function?
                return(new HttpResponseMessage(HttpStatusCode.Accepted));
            }

            return(new HttpResponseMessage(HttpStatusCode.BadRequest));
        }
Пример #13
0
        public static async Task <HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
        {
            var url          = string.Empty;
            var stopwatch    = Stopwatch.StartNew();
            var jsonResponse = string.Empty;

            try
            {
                var reqBodyStr = await req.Content.ReadAsStringAsync();

                var reqBody = JsonConvert.DeserializeObject <URLHolder>(reqBodyStr);

                url = reqBody.Url;
                if (!string.IsNullOrEmpty(reqBody.Parameter))
                {
                    url += reqBody.Parameter;
                }

                log.Info("RSS " + url);

                // TODO: use HttpCachedService (also as means of failover if the RSS stream is down)
                string data = await client.GetStringAsync(reqBody.Url.ToString());

                jsonResponse = ParseRSS(data);

                if (log.Level == TraceLevel.Verbose)
                {
                    log.Trace(new TraceEvent(TraceLevel.Verbose, $"Successfully transformed '{url}' '{data}' to '{jsonResponse}'"));
                }
                else
                {
                    log.Info($"Successfully transformed '{url}'");
                }
            }
            catch (HttpRequestException hre)
            {
                var msg = $"RSS Featurization failed '{url}' for '{req.RequestUri.ToString()}': '{hre.Message}'";

                log.Warning(msg);
                // TODO: maybe switch to dependency w/ status failed?
                Services.TelemetryClient.TrackEvent(msg,
                                                    new Dictionary <string, string>
                {
                    { "Service", req.RequestUri.ToString() },
                    { "Url", url },
                    { "Exception", hre.Message }
                });
            }
            catch (Exception ex)
            {
                log.Error($"Failed to process '{url}'", ex);

                Services.TelemetryClient.TrackException(
                    ex,
                    new Dictionary <string, string>
                {
                    { "Service", req.RequestUri.ToString() },
                    { "Url", url }
                });

                // swallow the error message and return empty. That way we can differentiate between real outages
                // remote errors
            }
            finally
            {
                Services.TelemetryClient.TrackEvent($"RSS {url}",
                                                    metrics: new Dictionary <string, double>
                {
                    { "requestTime", stopwatch.ElapsedMilliseconds }
                });
            }

            return(new HttpResponseMessage(System.Net.HttpStatusCode.OK)
            {
                Content = new StringContent(
                    jsonResponse,
                    new UTF8Encoding(encoderShouldEmitUTF8Identifier: false),
                    "application/json")
            });
        }
Пример #14
0
        private Dictionary <string, object> CreateScriptExecutionContext(object input, DataType dataType, TraceWriter traceWriter, FunctionInvocationContext invocationContext)
        {
            // create a TraceWriter wrapper that can be exposed to Node.js
            var log = (Func <object, Task <object> >)(p =>
            {
                var logData    = (IDictionary <string, object>)p;
                string message = (string)logData["msg"];
                if (message != null)
                {
                    try
                    {
                        TraceLevel level = (TraceLevel)logData["lvl"];
                        var evt          = new TraceEvent(level, message);
                        traceWriter.Trace(evt);
                    }
                    catch (ObjectDisposedException)
                    {
                        // if a function attempts to write to a disposed
                        // TraceWriter. Might happen if a function tries to
                        // log after calling done()
                    }
                }

                return(Task.FromResult <object>(null));
            });

            var bindings = new Dictionary <string, object>();
            var bind     = (Func <object, Task <object> >)(p =>
            {
                IDictionary <string, object> bindValues = (IDictionary <string, object>)p;
                foreach (var bindValue in bindValues)
                {
                    bindings[bindValue.Key] = bindValue.Value;
                }
                return(Task.FromResult <object>(null));
            });

            var context = new Dictionary <string, object>()
            {
                { "invocationId", invocationContext.ExecutionContext.InvocationId },
                { "log", log },
                { "bindings", bindings },
                { "bind", bind }
            };

            if (!string.IsNullOrEmpty(_entryPoint))
            {
                context["_entryPoint"] = _entryPoint;
            }

            if (input is HttpRequestMessage)
            {
                // convert the request to a json object
                HttpRequestMessage request = (HttpRequestMessage)input;
                string             rawBody = null;
                var requestObject          = CreateRequestObject(request, out rawBody);
                input = requestObject;

                if (rawBody != null)
                {
                    requestObject["rawBody"] = rawBody;
                }

                // If this is a WebHook function, the input should be the
                // request body
                HttpTriggerBindingMetadata httpBinding = _trigger as HttpTriggerBindingMetadata;
                if (httpBinding != null &&
                    !string.IsNullOrEmpty(httpBinding.WebHookType))
                {
                    requestObject.TryGetValue("body", out input);
                }

                // make the entire request object available as well
                // this is symmetric with context.res which we also support
                context["req"] = requestObject;
            }
            else if (input is TimerInfo)
            {
                // TODO: Need to generalize this model rather than hardcode
                // so other extensions can also express their Node.js object model
                TimerInfo timerInfo   = (TimerInfo)input;
                var       inputValues = new Dictionary <string, object>()
                {
                    { "isPastDue", timerInfo.IsPastDue }
                };
                if (timerInfo.ScheduleStatus != null)
                {
                    inputValues["last"] = timerInfo.ScheduleStatus.Last.ToString("s", CultureInfo.InvariantCulture);
                    inputValues["next"] = timerInfo.ScheduleStatus.Next.ToString("s", CultureInfo.InvariantCulture);
                }
                input = inputValues;
            }
            else if (input is Stream)
            {
                FunctionBinding.ConvertStreamToValue((Stream)input, dataType, ref input);
            }

            Utility.ApplyBindingData(input, invocationContext.Binder.BindingData);

            var bindingData = NormalizeBindingData(invocationContext.Binder.BindingData);

            bindingData["invocationId"] = invocationContext.ExecutionContext.InvocationId.ToString();
            context["bindingData"]      = bindingData;

            // if the input is json, try converting to an object or array
            object converted;

            if (TryConvertJson(input, out converted))
            {
                input = converted;
            }

            bindings.Add(_trigger.Name, input);

            context.Add("_triggerType", _trigger.Type);

            return(context);
        }
Пример #15
0
 private void Trace(string message, TraceLevel level)
 {
     _traceWriter?.Trace($"File watcher: ('{_path}') - {message}", level, null);
 }
Пример #16
0
 public override void Trace(TraceEvent traceEvent)
 {
     _innerWriter.Trace(traceEvent);
 }
Пример #17
0
        private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)
        {
            if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
            {
                return(true);
            }

            ReferenceLoopHandling?referenceLoopHandling = null;

            if (property != null)
            {
                referenceLoopHandling = property.ReferenceLoopHandling;
            }

            if (referenceLoopHandling == null && containerProperty != null)
            {
                referenceLoopHandling = containerProperty.ItemReferenceLoopHandling;
            }

            if (referenceLoopHandling == null && containerContract != null)
            {
                referenceLoopHandling = containerContract.ItemReferenceLoopHandling;
            }

            if (_serializeStack.IndexOf(value) != -1)
            {
                var serializerReferenceLoopHandling = referenceLoopHandling.GetValueOrDefault(Serializer._referenceLoopHandling);

                if (serializerReferenceLoopHandling == ReferenceLoopHandling.Error)
                {
                    string message;
                    if (property == null)
                    {
                        message = "Self referencing loop detected with type {0}, Path: {1}".FormatWith(CultureInfo.InvariantCulture, value.GetType(), writer.Path);
                    }
                    else
                    {
                        message = "Self referencing loop detected in {0}. Consider applying [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore] to property {1}."
                                  .FormatWith(CultureInfo.InvariantCulture, writer.Path, property.PropertyName);
                    }

                    throw new JsonSerializationException(message);
                }
                else
                {
                    string message = "Self referencing loop detected";
                    if (property != null)
                    {
                        message += " for property '{0}'".FormatWith(CultureInfo.InvariantCulture, property.PropertyName);
                    }
                    message += " with type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType());

                    switch (serializerReferenceLoopHandling)
                    {
                    case ReferenceLoopHandling.Ignore:
                        if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
                        {
                            TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Skipping serializing self referenced value."), null);
                        }

                        return(false);

                    case ReferenceLoopHandling.Serialize:
                        if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
                        {
                            TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Serializing self referenced value."), null);
                        }

                        return(true);
                    }
                }
            }

            return(true);
        }
        private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)
        {
            if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
            {
                return(true);
            }

            ReferenceLoopHandling?referenceLoopHandling = null;

            if (property != null)
            {
                referenceLoopHandling = property.ReferenceLoopHandling;
            }

            if (referenceLoopHandling == null && containerProperty != null)
            {
                referenceLoopHandling = containerProperty.ItemReferenceLoopHandling;
            }

            if (referenceLoopHandling == null && containerContract != null)
            {
                referenceLoopHandling = containerContract.ItemReferenceLoopHandling;
            }

            bool exists = (Serializer._equalityComparer != null)
                ? _serializeStack.Contains(value, Serializer._equalityComparer)
                : _serializeStack.Contains(value);

            if (exists)
            {
                string message = "Self referencing loop detected";
                if (property != null)
                {
                    message += " for property '{0}'".FormatWith(CultureInfo.InvariantCulture, property.PropertyName);
                }
                message += " with type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType());

                switch (referenceLoopHandling.GetValueOrDefault(Serializer._referenceLoopHandling))
                {
                case ReferenceLoopHandling.Error:
                    throw JsonSerializationException.Create(null, writer.ContainerPath, message, null);

                case ReferenceLoopHandling.Ignore:
                    if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
                    {
                        TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Skipping serializing self referenced value."), null);
                    }

                    return(false);

                case ReferenceLoopHandling.Serialize:
                    if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
                    {
                        TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Serializing self referenced value."), null);
                    }

                    return(true);
                }
            }

            return(true);
        }
Пример #19
0
 private void Trace(string message, TraceLevel level)
 {
     _traceWriter?.Trace($"{message} (path: '{_path}')", level, null);
 }
        private async Task <Dictionary <string, object> > CreateScriptExecutionContextAsync(object input, DataType dataType, TraceWriter traceWriter, FunctionInvocationContext invocationContext)
        {
            // create a TraceWriter wrapper that can be exposed to Node.js
            var log = (ScriptFunc)(p =>
            {
                var logData = (IDictionary <string, object>)p;
                string message = (string)logData["msg"];
                if (message != null)
                {
                    try
                    {
                        TraceLevel level = (TraceLevel)logData["lvl"];
                        var evt = new TraceEvent(level, message);

                        // Node captures the AsyncLocal value of the first invocation, which means that logs
                        // are correlated incorrectly. Here we'll overwrite that value with the correct value
                        // immediately before logging.
                        using (invocationContext.Logger.BeginScope(
                                   new Dictionary <string, object>
                        {
                            ["MS_FunctionInvocationId"] = invocationContext.ExecutionContext.InvocationId
                        }))
                        {
                            // TraceWriter already logs to ILogger
                            traceWriter.Trace(evt);
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        // if a function attempts to write to a disposed
                        // TraceWriter. Might happen if a function tries to
                        // log after calling done()
                    }
                }

                return(Task.FromResult <object>(null));
            });

            var bindings = new Dictionary <string, object>();
            var bind     = (ScriptFunc)(p =>
            {
                IDictionary <string, object> bindValues = (IDictionary <string, object>)p;
                foreach (var bindValue in bindValues)
                {
                    bindings[bindValue.Key] = bindValue.Value;
                }
                return(Task.FromResult <object>(null));
            });

            var executionContext = new Dictionary <string, object>
            {
                ["invocationId"]      = invocationContext.ExecutionContext.InvocationId,
                ["functionName"]      = invocationContext.ExecutionContext.FunctionName,
                ["functionDirectory"] = invocationContext.ExecutionContext.FunctionDirectory,
            };

            var context = new Dictionary <string, object>()
            {
                { "invocationId", invocationContext.ExecutionContext.InvocationId },
                { "executionContext", executionContext },
                { "log", log },
                { "bindings", bindings },
                { "bind", bind }
            };

            if (!string.IsNullOrEmpty(_entryPoint))
            {
                context["_entryPoint"] = _entryPoint;
            }

            // convert the request to a json object
            if (input is HttpRequestMessage request)
            {
                var requestObject = await CreateRequestObjectAsync(request).ConfigureAwait(false);

                input = requestObject;

                // If this is a WebHook function, the input should be the
                // request body
                var httpTrigger = _inputBindings.OfType <ExtensionBinding>().SingleOrDefault(p => p.Metadata.IsTrigger)?
                                  .Attributes.OfType <HttpTriggerAttribute>().SingleOrDefault();
                if (httpTrigger != null && !string.IsNullOrEmpty(httpTrigger.WebHookType))
                {
                    requestObject.TryGetValue("body", out input);
                }

                // make the entire request object available as well
                // this is symmetric with context.res which we also support
                context["req"] = requestObject;
            }
            else if (input is TimerInfo)
            {
                // TODO: Need to generalize this model rather than hardcode
                // so other extensions can also express their Node.js object model
                TimerInfo timerInfo   = (TimerInfo)input;
                var       inputValues = new Dictionary <string, object>()
                {
                    { "isPastDue", timerInfo.IsPastDue }
                };
                if (timerInfo.ScheduleStatus != null)
                {
                    inputValues["last"] = timerInfo.ScheduleStatus.Last.ToString("s", CultureInfo.InvariantCulture);
                    inputValues["next"] = timerInfo.ScheduleStatus.Next.ToString("s", CultureInfo.InvariantCulture);
                }
                input = inputValues;
            }
            else if (input is Stream)
            {
                FunctionBinding.ConvertStreamToValue((Stream)input, dataType, ref input);
            }

            Utility.ApplyBindingData(input, invocationContext.Binder.BindingData);

            var bindingData = NormalizeBindingData(invocationContext.Binder.BindingData);

            bindingData["invocationId"] = invocationContext.ExecutionContext.InvocationId.ToString();
            context["bindingData"]      = bindingData;

            // if the input is json, try converting to an object or array
            object converted;

            if (TryConvertJson(input, out converted))
            {
                input = converted;
            }

            bindings.Add(_trigger.Name, input);

            context.Add("_triggerType", _trigger.Type);

            return(context);
        }
Пример #21
0
        public async Task <BlobContent> PostAsync(TraceWriter log, string site, string id, object request, bool forceRefresh, CancellationToken cancellationToken)
        {
            await this.InitializeAsync();

            var stopwatch = Stopwatch.StartNew();
            var cacheHit  = true;
            HttpResponseMessage responseMessage = null;
            string body = null;

            try
            {
                body = request as string;
                string input;
                string contentType;
                if (body != null)
                {
                    // if this is a raw string, we need to escape for storage
                    input       = JsonConvert.SerializeObject(request);
                    contentType = "text/plain";
                }
                else
                {
                    body        = JsonConvert.SerializeObject(request);
                    input       = body;
                    contentType = "application/json";
                }

                log.Trace(new TraceEvent(TraceLevel.Verbose,
                                         $"Requesting {this.containerName} at {this.endpoint}: {body}"));

                var blobCache = new BlobCache(this.storageConnectionString);

                // lookup Azure Blob storage cache first
                // have a 5min timeout for retries
                BlobContent blobContent = null;
                if (!forceRefresh)
                {
                    blobContent = await blobCache.GetAsync(site, id, this.containerName, input, TimeSpan.FromMinutes(5), cancellationToken);
                }

                if (blobContent == null)
                {
                    cacheHit = false;

                    var stopwatchReqeust = Stopwatch.StartNew();

                    // make the actual HTTP request
                    responseMessage = await this.client.PostAsync(
                        string.Empty,
                        new StringContent(
                            body,
                            new UTF8Encoding(encoderShouldEmitUTF8Identifier: false),
                            contentType));

                    Services.TelemetryClient.TrackDependency(this.containerName, this.endpoint, this.containerName, null,
                                                             DateTime.UtcNow, stopwatchReqeust.Elapsed,
                                                             $"{responseMessage.StatusCode} {responseMessage.ReasonPhrase}", responseMessage.IsSuccessStatusCode);

                    log.Trace(new TraceEvent(TraceLevel.Verbose, $"Response: {responseMessage.StatusCode} {responseMessage.ReasonPhrase}"));

                    if (!responseMessage.IsSuccessStatusCode)
                    {
                        blobContent = new BlobContent
                        {
                            // TODO: random expiration
                            Expires = DateTime.UtcNow + TimeSpan.FromMinutes(1),
                        };
                    }
                    else
                    {
                        var responseStr = await responseMessage.Content.ReadAsStringAsync();

                        log.Trace(new TraceEvent(TraceLevel.Verbose, $"Result {this.containerName} at {this.endpoint}: {responseStr}"));

                        // once we got a response, cache for 3 days
                        // TODO: add configuration option
                        // TODO: add force refresh parameter
                        blobContent = await blobCache.PersistAsync(site, id, this.containerName, input, responseStr, TimeSpan.FromDays(3), cancellationToken);
                    }
                }

                return(blobContent);
            }
            finally
            {
                var props = new Dictionary <string, string>
                {
                    { "site", site },
                    { "id", id },
                    { "cacheHit", cacheHit.ToString() },
                    { "StatusCode", responseMessage?.StatusCode.ToString() },
                    { "Reason", responseMessage?.ReasonPhrase }
                };

                var sb = new StringBuilder(this.containerName);
                if (responseMessage != null && responseMessage.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    props.Add("Request", body);
                    sb.Append(" failed");
                }

                Services.TelemetryClient.TrackEvent(
                    sb.ToString(),
                    props,
                    metrics: new Dictionary <string, double>
                {
                    { "requestTime", stopwatch.ElapsedMilliseconds }
                });
            }
        }
        internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type objectType)
        {
            ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");

            // set serialization options onto writer
            Formatting?previousFormatting = null;

            if (_formatting != null && jsonWriter.Formatting != _formatting)
            {
                previousFormatting    = jsonWriter.Formatting;
                jsonWriter.Formatting = _formatting.Value;
            }

            DateFormatHandling?previousDateFormatHandling = null;

            if (_dateFormatHandling != null && jsonWriter.DateFormatHandling != _dateFormatHandling)
            {
                previousDateFormatHandling    = jsonWriter.DateFormatHandling;
                jsonWriter.DateFormatHandling = _dateFormatHandling.Value;
            }

            DateTimeZoneHandling?previousDateTimeZoneHandling = null;

            if (_dateTimeZoneHandling != null && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
            {
                previousDateTimeZoneHandling    = jsonWriter.DateTimeZoneHandling;
                jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.Value;
            }

            FloatFormatHandling?previousFloatFormatHandling = null;

            if (_floatFormatHandling != null && jsonWriter.FloatFormatHandling != _floatFormatHandling)
            {
                previousFloatFormatHandling    = jsonWriter.FloatFormatHandling;
                jsonWriter.FloatFormatHandling = _floatFormatHandling.Value;
            }

            StringEscapeHandling?previousStringEscapeHandling = null;

            if (_stringEscapeHandling != null && jsonWriter.StringEscapeHandling != _stringEscapeHandling)
            {
                previousStringEscapeHandling    = jsonWriter.StringEscapeHandling;
                jsonWriter.StringEscapeHandling = _stringEscapeHandling.Value;
            }

            CultureInfo previousCulture = null;

            if (_culture != null && !_culture.Equals(jsonWriter.Culture))
            {
                previousCulture    = jsonWriter.Culture;
                jsonWriter.Culture = _culture;
            }

            string previousDateFormatString = null;

            if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString)
            {
                previousDateFormatString    = jsonWriter.DateFormatString;
                jsonWriter.DateFormatString = _dateFormatString;
            }

            TraceJsonWriter traceJsonWriter = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
                                          ? new TraceJsonWriter(jsonWriter)
                                          : null;

            JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this);

            serializerWriter.Serialize(traceJsonWriter ?? jsonWriter, value, objectType);

            if (traceJsonWriter != null)
            {
                TraceWriter.Trace(TraceLevel.Verbose, "Serialized JSON: " + Environment.NewLine + traceJsonWriter.GetJson(), null);
            }

            // reset writer back to previous options
            if (previousFormatting != null)
            {
                jsonWriter.Formatting = previousFormatting.Value;
            }
            if (previousDateFormatHandling != null)
            {
                jsonWriter.DateFormatHandling = previousDateFormatHandling.Value;
            }
            if (previousDateTimeZoneHandling != null)
            {
                jsonWriter.DateTimeZoneHandling = previousDateTimeZoneHandling.Value;
            }
            if (previousFloatFormatHandling != null)
            {
                jsonWriter.FloatFormatHandling = previousFloatFormatHandling.Value;
            }
            if (previousStringEscapeHandling != null)
            {
                jsonWriter.StringEscapeHandling = previousStringEscapeHandling.Value;
            }
            if (_dateFormatStringSet)
            {
                jsonWriter.DateFormatString = previousDateFormatString;
            }
            if (previousCulture != null)
            {
                jsonWriter.Culture = previousCulture;
            }
        }
Пример #23
0
        public static async Task <HttpResponseMessage> IdentifyCustomer([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            // Get request body
            var body = await req.Content.ReadAsStringAsync();

            var imageCapture = JsonConvert.DeserializeObject <IdentifyCustomerRequest>(body, new JsonConverter[] { new GuidJsonConverter() });

            if (imageCapture == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, "No Valid Data submitted."));
            }

            // Decode data from Base64
            byte[] imageBytes = Convert.FromBase64String(imageCapture.Image);

            // Detect the faces
            Face detectedFace;

            using (var stream = new MemoryStream(imageBytes))
            {
                detectedFace = await FaceClient.Instance.DetectPrimaryFace(stream, true);

                if (detectedFace == null || detectedFace.FaceId == null)
                {
                    req.CreateResponse(HttpStatusCode.ExpectationFailed, "Error: No face was detected");
                }
            }

            // Crop the face
            var rect = new Rectangle(
                detectedFace.FaceRectangle.Left,
                detectedFace.FaceRectangle.Top,
                detectedFace.FaceRectangle.Width,
                detectedFace.FaceRectangle.Height
                );

            rect.Inflate(50, 50);

            using (var stream = new MemoryStream(imageBytes))
            {
                Bitmap bmp     = Image.FromStream(stream) as Bitmap;
                var    cropped = ImageUtils.CropBitmap(bmp, rect);
                imageBytes = cropped.ToByteArray(ImageFormat.Png);
            }

            // Store the image
            string storedUrl = StorageClient.Instance.StoreImage(imageBytes, ImagesContainerID)?.ToString();

            log.Trace(new TraceEvent(System.Diagnostics.TraceLevel.Verbose, "heres the url!: " + storedUrl));

            var response = new IdentifyCustomerResponse()
            {
                ImageUrl = storedUrl,
                Emotion  = FaceClient.Instance.ParseEmotions(detectedFace.FaceAttributes.Emotion)
            };

            // Check for existing Customers
            response.Customer = await FaceClient.Instance.IdentifyCustomerFace(detectedFace.FaceId);

            // Update the customers history with the recent photo
            if (response.Customer != null)
            {
                await FaceClient.Instance.AddCustomerFace(response.Customer, storedUrl);

                // Get their previous order
                var orders = CosmosClient.Instance.GetCustomerOrders(response.Customer.id, 1); // Could show more if we wanted
                response.PreviousOrder = orders.FirstOrDefault();
            }

            // If there are no matched customers return a new Customer with the FaceID
            else
            {
                response.Customer = new Customer()
                {
                    FaceId = detectedFace.FaceId,
                    Age    = detectedFace.FaceAttributes.Age,
                    Gender = detectedFace.FaceAttributes.Gender
                };
            }

            return(req.CreateResponse(HttpStatusCode.OK, response));
        }