예제 #1
0
        private static object GetParamValue(string paramString, string paramType)
        {
            if (paramString == null)
            {
                return(null);
            }
            switch (paramType ?? typeString)
            {
            case typeString:
                return(paramString);

            case typeInt:
                if (!Int32.TryParse(paramString, out int returnValue))
                {
                    throw ApiFunctionException.BadRequest($"Unable to convert supplied Parameter to integer");
                }
                return(returnValue);

            case typeStringArray:
                return(paramString.Split(","));

            default:
                throw ApiFunctionException.InternalServerError($"Parameter type {paramType} not recognised");
            }
        }
예제 #2
0
        private string BuildHostFunctionUrl(HttpRequest req, ILogger log)
        {
            var host = req.Headers["X-Forwarded-Host"].ToString();

            if (string.IsNullOrWhiteSpace(host))
            {
                throw ApiFunctionException.InternalServerError("X-Forwarded-Host header not present.");
            }

            if (string.IsNullOrWhiteSpace(_serviceTaxonomyApiSettings.CurrentValue.Scheme))
            {
                throw ApiFunctionException.InternalServerError("Scheme missing in Settings");
            }

            if (string.IsNullOrWhiteSpace(_serviceTaxonomyApiSettings.CurrentValue.ApplicationName))
            {
                throw ApiFunctionException.InternalServerError("ApplicationName missing in Settings");
            }

            var hostUriBuilder = new UriBuilder {
                Host = host, Scheme = _serviceTaxonomyApiSettings.CurrentValue.Scheme, Path = $"{_serviceTaxonomyApiSettings.CurrentValue.ApplicationName}"
            };

            log.LogInformation($"Function host is {hostUriBuilder.ToString()}");

            return(hostUriBuilder.ToString());
        }
예제 #3
0
        private async Task <JObject> GetRequestBody(HttpRequest req, ILogger log)
        {
            log.LogInformation("Attempting to read body from http request");

            string requestBodyString;

            try
            {
                requestBodyString = await _httpRequestHelper.GetBodyFromHttpRequestAsync(req);
            }
            catch (Exception ex)
            {
                throw ApiFunctionException.BadRequest("Unable to read body from request", ex);
            }

            log.LogInformation("Attempting to deserialize request body");

            JObject requestBody;

            if (string.IsNullOrWhiteSpace(requestBodyString))
            {
                requestBodyString = "{}";
            }

            try
            {
                requestBody = JObject.Parse(requestBodyString);
            }
            catch (Exception ex)
            {
                throw ApiFunctionException.UnprocessableEntityObjectResult("Unable to deserialize request body", ex);
            }

            return(requestBody);
        }
예제 #4
0
        private string GetFunctionName()
        {
            string functionToProcess = _serviceTaxonomyApiSettings.CurrentValue.Function;

            if (string.IsNullOrWhiteSpace(functionToProcess))
            {
                throw ApiFunctionException.InternalServerError("Missing function name in settings");
            }

            return(functionToProcess);
        }
        private async Task <IEnumerable <IRecord> > ExecuteCypherQuery(string query, ILogger log)
        {
            log.LogInformation($"Attempting to query neo4j with the following query: {query}");

            try
            {
                return(await _graphCluster.Run("target", new GenericCypherQuery(query)));
            }
            catch (Exception ex)
            {
                throw ApiFunctionException.InternalServerError("Unable To run query", ex);
            }
        }
예제 #6
0
        private async Task <object> ExecuteCypherQuery(Cypher cypherModel,
                                                       Dictionary <string, object> cypherQueryParameters, ILogger log)
        {
            log.LogInformation($"Attempting to query neo4j with the following query: {cypherModel.Query}");

            try
            {
                return(await _neo4JHelper.ExecuteCypherQueryInNeo4JAsync(cypherModel.Query, cypherQueryParameters));
            }
            catch (Exception ex)
            {
                throw ApiFunctionException.InternalServerError("Unable To run query", ex);
            }
        }
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Execute/{contentType}/{id:guid?}")] HttpRequest req, string contentType, Guid?id,
            ILogger log)
        {
            try
            {
                var environment = Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT");
                log.LogInformation($"Function has been triggered in {environment} environment.");

                if (string.IsNullOrWhiteSpace(contentType))
                {
                    throw ApiFunctionException.BadRequest($"Required parameter contentType not found in path.");
                }

                var queryParameters = new QueryParameters(contentType.ToLower(), id);

                bool hasApimHeader = req.Headers.TryGetValue("X-Forwarded-APIM-Url", out var headerValue);
                var  itemUri       = hasApimHeader ? $"{headerValue}{_contentApiOptions.CurrentValue.Action}/api/Execute/{contentType.ToLower()}/{id}".ToLower() : $"{_contentApiOptions.CurrentValue.Scheme}://{req.Host.Value}{req.Path.Value}".ToLower();
                var  apiHost       = hasApimHeader ? $"{headerValue}{_contentApiOptions.CurrentValue.Action}/api/Execute" : $"{_contentApiOptions.CurrentValue.Scheme}://{req.Host.Value}/api/execute".ToLower();

                var queryToExecute = this.BuildQuery(queryParameters, itemUri);

                var recordsResult = await ExecuteCypherQuery(queryToExecute.Query, log);

                if (recordsResult == null || !recordsResult.Any())
                {
                    return(new NotFoundObjectResult("Resource not found"));
                }

                log.LogInformation("request has successfully been completed with results");

                SetContentTypeHeader(req);
                return(new OkObjectResult(_jsonFormatHelper.FormatResponse(recordsResult, queryToExecute.RequestType, apiHost)));
            }
            catch (ApiFunctionException e)
            {
                log.LogError(e.ToString());
                return(e.ActionResult ?? new InternalServerErrorResult());
            }
            catch (Exception e)
            {
                log.LogError(e.ToString());
                return(new InternalServerErrorResult());
            }
        }
        public object FormatResponse(IEnumerable <IRecord> recordsResult, RequestType type, string apiHost)
        {
            switch (type)
            {
            case RequestType.GetAll:
                return(recordsResult.SelectMany(z => z.Values).Select(y => CreateSingleRootObject(ReplaceNamespaces(y.Value), apiHost, false)));

            case RequestType.GetById:
                var recordValues = recordsResult.Select(z => z.Values).FirstOrDefault()?.Values.FirstOrDefault();
                if (recordValues != null)
                {
                    return(this.CreateSingleRootObject(this.ReplaceNamespaces(recordValues), apiHost, true));
                }

                throw ApiFunctionException.InternalServerError($"Request Type: {type} records contain unformattable response");

            default:
                throw new NotSupportedException($"Request Type: {type} not supported");
            }
        }
예제 #9
0
        private static Dictionary <string, object> GetCypherPathParameters(Cypher cypherModel, PathString pathString, ILogger log)
        {
            log.LogInformation("Attempting to read parameters from path");

            var cypherPathStatementParameters = new Dictionary <string, object>();

            if (cypherModel.QueryParams == null)
            {
                return(cypherPathStatementParameters);
            }

            var pathParams = cypherModel.QueryParams.Where(x => x.PathOrdinalPosition.HasValue);

            if (!pathParams.Any())
            {
                return(cypherPathStatementParameters);
            }

            var pathParameters = pathString.Value.Replace("/Execute/", string.Empty).Split('/');

            foreach (var cypherParam in pathParams)
            {
                try
                {
                    var parameterValue = pathParameters[cypherParam.PathOrdinalPosition.Value];

                    if (string.IsNullOrWhiteSpace(parameterValue))
                    {
                        throw ApiFunctionException.InternalServerError($"Required parameter {cypherParam.Name} has no value in path");
                    }

                    cypherPathStatementParameters.Add(cypherParam.Name, parameterValue);
                }
                catch (Exception)
                {
                    throw ApiFunctionException.BadRequest($"Required parameter {cypherParam.Name} not found in path parameters");
                }
            }

            return(cypherPathStatementParameters);
        }
예제 #10
0
        private async Task <Cypher> GetCypherQuery(string functionName, ExecutionContext context, bool development, ILogger log, string apiVersion)
        {
            log.LogInformation("Generating file name and dir to read json config");

            var queryFileNameAndDir = $@"{(development ? context.FunctionAppDirectory : context.FunctionDirectory)}\CypherQueries\{apiVersion}\{functionName}.json";

            string cypherQueryJsonConfig;

            log.LogInformation($"Attempting to read json config from {queryFileNameAndDir}");

            try
            {
                cypherQueryJsonConfig = await _fileHelper.ReadAllTextFromFileAsync(queryFileNameAndDir);
            }
            catch (Exception ex)
            {
                throw ApiFunctionException.InternalServerError($"Unable to read query file for requested function: {functionName} version: {apiVersion}", ex);
            }

            log.LogInformation("Attempting to deserialize json config to cypher model");

            Cypher cypherModel;

            try
            {
                cypherModel = JsonConvert.DeserializeObject <Cypher>(cypherQueryJsonConfig);
            }
            catch (Exception ex)
            {
                throw ApiFunctionException.InternalServerError("Unable to deserialize query file", ex);
            }

            if (cypherModel?.Query == null)
            {
                throw ApiFunctionException.InternalServerError("Null deserialized cypher model");
            }

            return(cypherModel);
        }
예제 #11
0
        private static Dictionary <string, object> GetCypherQueryParameters(Cypher cypherModel, IQueryCollection queryCollection, JObject requestBody, ILogger log, Dictionary <string, object> existingParameters)
        {
            log.LogInformation("Attempting to read json body object");

            if (cypherModel.QueryParams == null)
            {
                return(existingParameters);
            }

            var queryParams = queryCollection.ToDictionary(p => p.Key, p => p.Value.Last(), StringComparer.OrdinalIgnoreCase);

            foreach (var cypherParam in cypherModel.QueryParams)
            {
                // let query param override param in message body
                if (!existingParameters.ContainsKey(cypherParam.Name))
                {
                    try
                    {
                        object foundParamValue = GetParamValue(queryParams.GetValueOrDefault(cypherParam.Name), cypherParam.Type)
                                                 ?? requestBody.GetValue(cypherParam.Name, StringComparison.OrdinalIgnoreCase)?.ToObject(Type.GetType(cypherParam.Type ?? typeString))
                                                 ?? cypherParam.Default;
                        if (foundParamValue == null)
                        {
                            throw ApiFunctionException.BadRequest($"Required parameter {cypherParam.Name} not found in request body or query params");
                        }

                        existingParameters.Add(cypherParam.Name, foundParamValue);
                    }
                    catch (Exception ex)
                    {
                        throw ApiFunctionException.BadRequest("Unable to process supplied parameters", ex);
                    }
                }
            }

            return(existingParameters);
        }