コード例 #1
0
        /// <summary>
        /// Log telemetry to ETW and AppInsights
        /// </summary>
        /// <returns></returns>
        private void LogRequestEvent(Uri serviceUri, RequestDescriptor descriptor)
        {
            string userName = string.Empty;

            if (descriptor.Headers != null)
            {
                descriptor.Headers.TryGetValue(_UserNameHeader, out userName);
            }

            Dictionary <string, string> properties = new Dictionary <string, string>
            {
                { "method", descriptor.Method }
            };

            // Add username to logging if its enabled
            if (_IsUserInfoLoggingEnabled)
            {
                properties.Add("username", userName ?? string.Empty);
            }

            // Log non-groups method.
            if (descriptor.Method != "groups")
            {
                if (!string.IsNullOrEmpty(descriptor.QueryString))
                {
                    properties.Add("query", descriptor.QueryString);
                }
            }

            ServiceEventSource.Current.Message($"Request: {serviceUri.ToString()}");
            _StaticLogger.LogInformation(serviceUri.ToString(), properties);
        }
コード例 #2
0
        /// <summary>
        /// Make request using reverse proxy
        /// </summary>
        /// <returns></returns>
        private async Task <ApiResult> MakeRequestUsingReverseProxy(RequestDescriptor descriptor, ServicePartitionKey servicePartitionKey)
        {
            ApiResult result     = new ApiResult();
            Uri       serviceUri = new Uri($"https://localhost:{_ReverseProxyPort}/{descriptor.Application}/{descriptor.Service}/");

            // This is logged mainly to track usage
            LogRequestEvent(serviceUri, descriptor);

            // Don't log queryString for 'groups' method as it contains sensitive info
            string queryString = (descriptor.Method == "groups" || descriptor.QueryString == null) ? string.Empty : descriptor.QueryString;

            // Generate request and receive response
            HttpRequestMessage request = CreateMicroserviceRequest(serviceUri, descriptor);

            HttpResponseMessage response = null;

            try
            {
                response = await _HttpClient.SendAsync(request);
            }
            catch (Exception ex)
            {
                // We have seen cases where SendAsync can fail. Log telemetry for those cases.

                Dictionary <string, string> properties = new Dictionary <string, string>();
                // Add endpoint uri for all requests except 'groups'
                if (!string.IsNullOrEmpty(request.RequestUri.AbsoluteUri) && descriptor.Method != "groups")
                {
                    properties.Add("endpointUri", request.RequestUri.AbsoluteUri);
                }

                ServiceEventSource.Current.Message($"Exception: {ex.ToString()}");
                _StaticLogger.LogError(ex, ex.Message, properties);
                throw;
            }

            ProxyResponse(result, response);

            // Log body for post calls/message if available. While this is not really responseCode value,
            // this is very useful for debugging.
            string responseCode = string.Format("StatusCode:{0}", response.StatusCode);

            if (!string.IsNullOrEmpty(result.Message))
            {
                responseCode = string.Format("{0}, Message:{1}", responseCode, result.Message);
            }
            // Log endpoint uri (e.g. http://10.0.0.5:20097) except groups calls.
            if (!string.IsNullOrEmpty(request.RequestUri.AbsoluteUri) && descriptor.Method != "groups")
            {
                responseCode = string.Format("{0}, EndpointUri:{1}", responseCode, request.RequestUri.AbsoluteUri);
            }

            ServiceEventSource.Current.Message($"Response: {responseCode}");
            _StaticLogger.LogInformation($"ResponseCode: {responseCode}; response.IsSuccessStatusCode: {response.IsSuccessStatusCode}");
            return(result);
        }
コード例 #3
0
        public void GetParameters()
        {
            var req = RequestDescriptor.Create(new {
                param = new {
                    x = "1ф",
                    y = "2 ф+1"
                }
            });

            Assert.AreEqual("http://127.0.0.1/?x=1ф&y=2 ф%2B1", req.Uri.ToString());
        }
コード例 #4
0
        public void GetParametersJsonMode()
        {
            var req = RequestDescriptor.Create(new
            {
                enc   = "json",
                param = new
                {
                    x = "1ф",
                    y = "2 ф+1"
                }
            });

            Assert.AreEqual("http://127.0.0.1/?{\"x\":\"1ф\"%2C\"y\":\"2 ф%2B1\"}", req.Uri.ToString());
        }
コード例 #5
0
        public static string BuildUrl(this RequestDescriptor requestDescriptor, Dictionary <string, object> context = null)
        {
            var url = requestDescriptor.Href;

            if (requestDescriptor.Templated && context?.Count > 0)
            {
                foreach (var entry in context)
                {
                    var filter = new Regex(@"\{" + entry.Key + @"\??\}", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
                    url = filter.Replace(url, $"{UrlEncode(entry.Value.ToString())}");
                }
            }

            return(OptionalRouteFilter.Replace(url, string.Empty));
        }
コード例 #6
0
        public void FormData()
        {
            var req = RequestDescriptor.Create(new
            {
                method = "POST",
                param  = new
                {
                    x = "1ф",
                    y = "2 ф+1"
                }
            });

            Assert.AreEqual("POST", req.Method);
            Assert.AreEqual("x=1%D1%84&y=2%20%D1%84%2B1", req.PostData);
            Assert.AreEqual("http://127.0.0.1/", req.Uri.ToString());
        }
コード例 #7
0
        public void PostData()
        {
            var req = RequestDescriptor.Create(new {
                param = new {
                    a = 1,
                    b = 2
                },
                data = new {
                    x = "1ф",
                    y = "2 ф+1"
                }
            });

            Assert.AreEqual("POST", req.Method);
            Assert.AreEqual("{\"x\":\"1ф\",\"y\":\"2 ф+1\"}", req.PostData);
            Assert.AreEqual("http://127.0.0.1/?a=1&b=2", req.Uri.ToString());
        }
コード例 #8
0
        public static HttpRequestMessage BuildRequest(this RequestDescriptor requestDescriptor, Dictionary <string, object> context = null)
        {
            var fullUrl = requestDescriptor.BuildFullUri(context);

            var request = new HttpRequestMessage
            {
                RequestUri = new Uri(fullUrl, UriKind.RelativeOrAbsolute)
            };

            switch (requestDescriptor.Method)
            {
            case "POST":
                request.Method = HttpMethod.Post;
                break;

            case "DELETE":
                request.Method = HttpMethod.Delete;
                break;

            case "PUT":
                request.Method = HttpMethod.Put;
                break;

            case "HEAD":
                request.Method = HttpMethod.Head;
                break;

            case "OPTIONS":
                request.Method = HttpMethod.Options;
                break;

            case "TRACE":
                request.Method = HttpMethod.Trace;
                break;

            default:
                request.Method = HttpMethod.Get;
                break;
            }

            return(request);
        }
コード例 #9
0
        public static string BuildFullUri(this RequestDescriptor requestDescriptor, Dictionary <string, object> context = null)
        {
            var url         = requestDescriptor.BuildUrl(context);
            var queryString = requestDescriptor.BuildQueryString(context);

            var fullUrl = url;

            if (!string.IsNullOrWhiteSpace(queryString))
            {
                var joinSymbol = "?";
                if (url.IndexOf("?", StringComparison.InvariantCultureIgnoreCase) >= 0)
                {
                    joinSymbol = "&";
                }

                fullUrl = $"{url}{joinSymbol}{queryString}";
            }

            return(fullUrl);
        }
コード例 #10
0
        private async Task <ApiResult> Query(HttpRequestMessage request, string application, string service, string method, HttpMethod httpMethod)
        {
            var roles = ((ClaimsIdentity)User.Identity).Claims
                        .Where(c => c.Type == ClaimTypes.Role)
                        .Select(c => c.Value).ToList();
            var clientId = $"{ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")?.Value}.{ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid")?.Value}";

            if (roles.Intersect(_AllowedUserRoles).Any() || _ClientWhitelist.Contains(clientId))
            {
                // Merge original headers with custom headers
                // Note: currently gets only the first value for a particular header
                Dictionary <string, string> headers = request.Headers != null
                    ? request.Headers
                                                      .Where(e => e.Key.StartsWith("X-"))
                                                      .ToDictionary(e => e.Key, e => e.Value.FirstOrDefault())
                    : new Dictionary <string, string>();

                foreach (KeyValuePair <string, string> entry in FetchUserHeaders())
                {
                    headers[entry.Key] = entry.Value;
                }

                RequestDescriptor descriptor = new RequestDescriptor
                {
                    HttpMethod  = httpMethod,
                    Application = application,
                    Service     = service,
                    Method      = method,
                    QueryString = request.RequestUri.Query + string.Format("&Timeout={0}", _DefaultHttpTimeoutSecs),//set a timeout for reverseProxy
                    Body        = httpMethod == HttpMethod.Post ? (await request.Content.ReadAsStringAsync()) : null,
                    Headers     = headers
                };

                return(await MakeRequestUsingReverseProxy(descriptor, new ServicePartitionKey()));
            }
            else
            {
                return(ApiResult.CreateError(string.Join(" or ", _AllowedUserRoles) + " role required."));
            }
        }
コード例 #11
0
        public static string BuildQueryString(this RequestDescriptor requestDescriptor, Dictionary <string, object> context = null)
        {
            var parts = new List <string>();

            if (context?.Count > 0)
            {
                if (context.TryGetValue("hostOrigin", out var hostOrigin))
                {
                    parts.Add($"hostOrigin={UrlEncode(hostOrigin.ToString())}");
                }

                foreach (var property in requestDescriptor.Properties ?? Enumerable.Empty <RequestDescriptorProperty>())
                {
                    if (context.TryGetValue(property.Name, out var propertyValue))
                    {
                        parts.Add($"{property.Name}={UrlEncode(propertyValue.ToString())}");
                    }
                }
            }

            return(string.Join("&", parts));
        }
コード例 #12
0
ファイル: MysqlDatabase.cs プロジェクト: Natlink/Dust.ORM
        public override List <T> Get(RequestDescriptor request, int row = -1)
        {
            List <T> res       = new List <T>();
            T        a         = null;
            string   condition = "WHERE `" + request.PropertyName + "`";

            switch (request.Op)
            {
            case RequestOperator.Equal: condition += " = "; break;

            case RequestOperator.NotEqual: condition += " != "; break;

            case RequestOperator.Greater: condition += " > "; break;

            case RequestOperator.GreaterOrEqual: condition += " >= "; break;

            case RequestOperator.Less: condition += " < "; break;

            case RequestOperator.LessOrEqual: condition += " <= "; break;

            case RequestOperator.And: condition += " AND "; break;

            case RequestOperator.Or: condition += " OR "; break;
            }
            condition += "'" + request.Value + "' ";
            var reader = ExecuteReader("SELECT * FROM `" + Descriptor.ModelTypeName + "` " + condition + (row == -1 ? "" : "LIMIT " + row + "," + Config.GetAllSize));

            do
            {
                a = Read(reader);
                if (a != null)
                {
                    res.Add(a);
                }
            } while (a != null);
            return(res);
        }
コード例 #13
0
        /// <summary>
        /// Create request to other microservices
        /// </summary>
        /// <returns></returns>
        private HttpRequestMessage CreateMicroserviceRequest(Uri serviceUri, RequestDescriptor descriptor)
        {
            // Construct URI base path
            UriBuilder apiUri = new UriBuilder(new Uri(serviceUri, $"api/{descriptor.Method}"));

            // Add query string to URI if one was given
            if (!string.IsNullOrEmpty(descriptor.QueryString))
            {
                // Have to slice the ? off
                apiUri.Query = descriptor.QueryString.Substring(1);
            }

            // Build HTTP request
            HttpRequestMessage request = new HttpRequestMessage
            {
                RequestUri = apiUri.Uri,
                Method     = descriptor.HttpMethod
            };

            // Attach body if one was given. Assumes body is application/json.
            if (!string.IsNullOrEmpty(descriptor.Body))
            {
                request.Content = new StringContent(descriptor.Body, Encoding.UTF8, "application/json");
            }

            // Attach headers if any are given
            if (descriptor.Headers != null)
            {
                foreach (KeyValuePair <string, string> entry in descriptor.Headers)
                {
                    request.Headers.Add(entry.Key, entry.Value);
                }
            }

            return(request);
        }
コード例 #14
0
ファイル: ExempleDatabase.cs プロジェクト: Natlink/Dust.ORM
        public override List <T> Get(RequestDescriptor request, int row = -1)
        {
            List <T> res    = new List <T>();
            T        a      = null;
            var      reader = new TestDataReader(Datas.Values.ToArray());

            PropertyDescriptor descriptor = null;

            try
            {
                foreach (var p in Descriptor.Props)
                {
                    if (p.Name.Equals(request.PropertyName))
                    {
                        descriptor = p;
                        break;
                    }
                }
                if (descriptor == null)
                {
                    return(res);
                }
                do
                {
                    a = Read(reader);
                    if (a != null)
                    {
                        bool   match = false;
                        object value = Descriptor.GetValue(a, descriptor.Name);
                        switch (request.Op)
                        {
                        case RequestOperator.Equal: match = value == null ? value == request.Value : value.Equals(request.Value); break;

                        case RequestOperator.NotEqual: match = value == null ? value != request.Value : !value.Equals(request.Value); break;

                        case RequestOperator.Greater: match = (double)value > (double)request.Value; break;

                        case RequestOperator.GreaterOrEqual: match = (double)value >= (double)request.Value; break;

                        case RequestOperator.Less: match = (double)value < (double)request.Value; break;

                        case RequestOperator.LessOrEqual: match = (double)value <= (double)request.Value; break;

                        case RequestOperator.And: match = (bool)value && (bool)request.Value; break;

                        case RequestOperator.Or: match = (bool)value || (bool)request.Value; break;
                        }
                        if (match)
                        {
                            res.Add(a);
                        }
                    }
                } while (a != null);
            }
            catch (Exception e)
            {
                throw new RequestException(request, descriptor, a, "Error in request processing:\n" + e.ToString());
            }
            if (row != -1)
            {
                if (res.Count >= row)
                {
                    res.RemoveRange(0, row);
                }
                if (Config.GetAllSize < res.Count)
                {
                    res.RemoveRange(Config.GetAllSize, res.Count - Config.GetAllSize);
                }
            }
            return(res);
        }
コード例 #15
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="client"></param>
 /// <param name="descriptor"></param>
 /// <param name="token"></param>
 /// <returns></returns>
 public static async Task SendAsync(this IHttpClientWrapper client, RequestDescriptor descriptor, CancellationToken token = default)
 {
     await client.SendAndWrapAsync(descriptor, token);
 }
コード例 #16
0
        private static void AddTimeoutHeader(this ClientConfiguration configuration, HttpRequestMessage request, RequestDescriptor requestDescriptor = null)
        {
            request.Headers.Remove("Timeout");
            var timeoutMs = configuration.DefaultTimeoutMs.ToString(CultureInfo.InvariantCulture);

            if (requestDescriptor != null && requestDescriptor.TimeoutMs > 0)
            {
                timeoutMs = requestDescriptor.TimeoutMs.ToString(CultureInfo.InvariantCulture);
            }

            request.Headers.Add("Timeout", timeoutMs);
        }
コード例 #17
0
        private static HttpRequestMessage BuildRequestWithHeaders(this ClientConfiguration configuration, RequestDescriptor requestDescriptor, string hostOrigin, Dictionary <string, object> context = null)
        {
            var safeContext = context ?? new Dictionary <string, object>();

            if (hostOrigin != null)
            {
                safeContext["hostOrigin"] = hostOrigin;
            }

            var request = requestDescriptor.BuildRequest(safeContext);

            configuration.AddConfigurationVersionIdHeader(request);
            configuration.AddTimeoutHeader(request, requestDescriptor);

            return(request);
        }
コード例 #18
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TOutData"></typeparam>
        /// <param name="client"></param>
        /// <param name="descriptor"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static async Task <TOutData> SendAsync <TOutData>(this IHttpClientWrapper client, RequestDescriptor descriptor, CancellationToken token = default)
        {
            var response = await client.SendAndWrapAsync <TOutData>(descriptor, token);

            return(response.Data);
        }
コード例 #19
0
 public RequestException(RequestDescriptor request, PropertyDescriptor property, DataModel model, string message) : base(message)
 {
     Request  = request;
     Property = property;
     Model    = model;
 }