Exemple #1
0
        private async Task ProcessPutCommand(RestProcessParameters param, CancellationToken ct)
        {
            var restQuery        = new RestQueryString(param);
            var entityDefinition = param.Model.EntitiesByPluralName.SafeGet(restQuery.Root);

            if (entityDefinition == null)
            {
                throw new BadRequestException($"Unable to find an entity definition named {restQuery.Root}.");
            }

            if (restQuery.AdditionalQualifier.IsNullOrEmpty())
            {
                throw new BadRequestException($"A put request must apply to a specific id.");
            }

            var propertyBag = param.RequestSerializer.Deserialize(param.Context.Request.Body);

            propertyBag[MetaConstants.IdProperty] = restQuery.AdditionalQualifier;
            var entity = await EntityFactory.Hydrate(entityDefinition, propertyBag, ct);

            entity.Etag = param.Headers.IfNoneMatch();
            var result = await EntityService.Update(entity, ct);

            Respond(param, result.ToPropertyBag(), StatusCodes.Status200OK, new Dictionary <string, string>
            {
                { WebConstants.ETagHeader, entity.Etag },
                { WebConstants.LastModifiedHeader, result.LastModified.SelectOrDefault(x => x.ToUtcIso8601()) }
            });
        }
Exemple #2
0
        private async Task ProcessDeleteCommand(RestProcessParameters param, CancellationToken ct)
        {
            var restQuery        = new RestQueryString(param);
            var entityDefinition = param.Model.EntitiesByPluralName.SafeGet(restQuery.Root);

            if (entityDefinition == null)
            {
                throw new BadRequestException($"Unable to find an entity definition named {restQuery.Root}.");
            }

            if (restQuery.AdditionalQualifier.IsNullOrEmpty())
            {
                throw new BadRequestException($"A delete request must include an id.");
            }

            var result = await EntityService.Delete(entityDefinition, restQuery.AdditionalQualifier, ct);

            if (!result)
            {
                Respond(param,
                        new MessageResponse($"Unable to find a {entityDefinition.SingleName} with id {restQuery.AdditionalQualifier}."),
                        StatusCodes.Status404NotFound);
                return;
            }
            Respond(param, null, StatusCodes.Status204NoContent);
        }
Exemple #3
0
        private async Task ProcessPostCommand(RestProcessParameters param, CancellationToken ct)
        {
            var restQuery        = new RestQueryString(param);
            var entityDefinition = param.Model.EntitiesByPluralName.SafeGet(restQuery.Root);

            if (entityDefinition == null)
            {
                throw new BadRequestException($"Unable to find an entity definition named {restQuery.Root}.");
            }

            if (!restQuery.AdditionalQualifier.IsNullOrEmpty())
            {
                throw new BadRequestException($"A post request should not have an additional qualifier.");
            }

            var propertyBag = param.RequestSerializer.Deserialize(param.Context.Request.Body);
            var entity      = await EntityFactory.Create(entityDefinition, propertyBag, ct);

            var result = await EntityService.Create(entity, ct);

            Respond(param, result.ToPropertyBag(), StatusCodes.Status201Created, new Dictionary <string, string>
            {
                { WebConstants.ETagHeader, result.Etag },
                { WebConstants.LastModifiedHeader, result.LastModified.SelectOrDefault(x => x.ToUtcIso8601()) },
                {
                    "Location",
                    param.Context.Request.AbsoluteUri(
                        $"{_options.Value.MountPoint}/{entityDefinition.Model.Name}/{entityDefinition.PluralName}/{WebUtility.UrlEncode(result.Id.ToString())}")
                }
            });
        }
Exemple #4
0
        private async Task ProcessPatchCommand(RestProcessParameters param, CancellationToken ct)
        {
            var restQuery        = new RestQueryString(param);
            var entityDefinition = param.Model.EntitiesByPluralName.SafeGet(restQuery.Root);

            if (entityDefinition == null)
            {
                throw new BadRequestException($"Unable to find an entity definition named {restQuery.Root}.");
            }

            if (restQuery.AdditionalQualifier.IsNullOrEmpty())
            {
                throw new BadRequestException($"A patch request must apply to a specific id.");
            }

            if (!(param.RequestSerializer is JsonRestSerializer))
            {
                throw new BadRequestException("Only JSON Patch is supported for patching resources.");
            }

            JsonPatchDocument jsonPatchDocument;

            try
            {
                jsonPatchDocument = HiveJsonSerializer.Instance.Deserialize <JsonPatchDocument>(param.Context.Request.Body);
            }
            catch (Exception ex)
            {
                throw new BadRequestException("Malformed JSON Patch.", ex);
            }

            var entity = await EntityService.GetById(entityDefinition, restQuery.AdditionalQualifier, ct);

            if (entity == null)
            {
                Respond(param,
                        new MessageResponse($"Unable to find a {entityDefinition.SingleName} with id {restQuery.AdditionalQualifier}"),
                        StatusCodes.Status404NotFound);
                return;
            }
            jsonPatchDocument.ApplyTo(entity, new EntityPatchObjectAdapter());
            entity.Etag = param.Headers.IfNoneMatch();
            var result = await EntityService.Update(entity, ct);

            Respond(param, result.ToPropertyBag(), StatusCodes.Status200OK, new Dictionary <string, string>
            {
                { WebConstants.ETagHeader, result.Etag },
                { WebConstants.LastModifiedHeader, result.LastModified.SelectOrDefault(x => x.ToUtcIso8601()) }
            });
        }
Exemple #5
0
        private static void FillOperators(IQuery query, RestQueryString restQuery, RestProcessParameters param)
        {
            if (restQuery.QueryStringValues.ContainsKey(RestConstants.LimitOperator))
            {
                var maxResults = restQuery.QueryStringValues[RestConstants.LimitOperator].First().IntSafeInvariantParse();
                query.SetMaxResults(maxResults);
            }

            if (restQuery.QueryStringValues.ContainsKey(RestConstants.OrderOperator))
            {
                var orderby      = restQuery.QueryStringValues[RestConstants.OrderOperator].FirstOrDefault();
                var orderbyMatch = OrderByRegex.Match(orderby);
                if (orderbyMatch.Success)
                {
                    switch (orderbyMatch.Groups["asc"].Value.IsNullOrEmpty() ? "asc" : orderbyMatch.Groups["asc"].Value)
                    {
                    case "asc":
                        query.AddOrder(Order.Asc(orderbyMatch.Groups["prop"].Value));
                        break;

                    case "desc":
                        query.AddOrder(Order.Desc(orderbyMatch.Groups["prop"].Value));
                        break;
                    }
                }
            }

            if (restQuery.QueryStringValues.ContainsKey(RestConstants.IncludeOperator))
            {
                foreach (var value in restQuery.QueryStringValues[RestConstants.IncludeOperator])
                {
                    query.Include(value);
                }
            }

            if (restQuery.QueryStringValues.ContainsKey(RestConstants.SelectOperator))
            {
                query.SetProjection(Projection.Properties(restQuery.QueryStringValues[RestConstants.SelectOperator]));
            }

            if (param.Context.Request.Headers.ContainsKey(RestConstants.ContinuationTokenHeader))
            {
                var continuationToken = param.Context.Request.Headers[RestConstants.ContinuationTokenHeader].FirstOrDefault();
                query.SetContinuationToken(continuationToken);
            }
        }
Exemple #6
0
        private IQuery CreateQuery(IEntityDefinition entityDefinition, RestQueryString restQuery, RestProcessParameters param)
        {
            var query = EntityService.CreateQuery(entityDefinition);

            foreach (
                var queryStringValue in
                restQuery.QueryStringValues.Where(x => !x.Key.StartsWith(RestConstants.ReservedOperatorsPrefix)))
            {
                RecursiveFillQuery(query, null, queryStringValue.Key, queryStringValue.Value);
            }

            FillOperators(query, restQuery, param);

            if (restQuery.PathValues.Count == 0)
            {
                return(query);
            }

            if (restQuery.PathValues.Count > 1)
            {
                throw new BadRequestException("Multi-level query expressions in path is not supported.");
            }

            var pathValue = restQuery.PathValues.First();

            var targetEntityDef = entityDefinition.Model.EntitiesByPluralName.SafeGet(pathValue.Key);

            if (targetEntityDef == null)
            {
                throw new NotFoundException($"Unable to find an entity definition named {pathValue.Key}");
            }

            var targetPropertyDefinition = entityDefinition.Properties.SafeGet(targetEntityDef.SingleName);

            if (targetPropertyDefinition != null)
            {
                var subQuery = query.GetOrCreateSubQuery(targetPropertyDefinition.Name);
                RecursiveFillQuery(subQuery, null, MetaConstants.IdProperty, pathValue.Value);
            }

            return(query);
        }
Exemple #7
0
        private async Task ProcessQuery(RestProcessParameters param, CancellationToken ct)
        {
            var restQuery        = new RestQueryString(param);
            var entityDefinition = param.Model.EntitiesByPluralName.SafeGet(restQuery.Root);

            if (entityDefinition == null)
            {
                throw new NotFoundException($"Unable to find an entity definition named {restQuery.Root}.");
            }

            if (!restQuery.AdditionalQualifier.IsNullOrEmpty())
            {
                var result = await EntityService.GetById(entityDefinition, restQuery.AdditionalQualifier, ct);

                if (result == null)
                {
                    Respond(param,
                            new MessageResponse($"Unable to find a {entityDefinition.SingleName} with id {restQuery.AdditionalQualifier}"),
                            StatusCodes.Status404NotFound);
                    return;
                }

                var ifNoneMatch = param.Headers.IfNoneMatch();
                if (string.Equals(ifNoneMatch, result.Etag, StringComparison.Ordinal))
                {
                    Respond(param, null, StatusCodes.Status304NotModified, new Dictionary <string, string>
                    {
                        { WebConstants.ETagHeader, result.Etag },
                        { WebConstants.LastModifiedHeader, result.LastModified.SelectOrDefault(x => x.ToUtcIso8601()) }
                    });
                }
                else
                {
                    Respond(param, result.ToPropertyBag(), StatusCodes.Status200OK, new Dictionary <string, string>
                    {
                        { WebConstants.ETagHeader, result.Etag },
                        { WebConstants.LastModifiedHeader, result.LastModified.SelectOrDefault(x => x.ToUtcIso8601()) }
                    });
                }
            }
            else
            {
                var query = CreateQuery(entityDefinition, restQuery, param);
                if (query.MaxResults.HasValue)
                {
                    var result = await query.ToContinuationEnumerable <IEntity>(ct);

                    Respond(param, result.Select(x => x.ToPropertyBag()).ToArray(), StatusCodes.Status200OK,
                            new Dictionary <string, string>
                    {
                        { RestConstants.ContinuationTokenHeader, result.ContinuationToken }
                    });
                }
                else
                {
                    var result = await query.ToEnumerable <IEntity>(ct);

                    Respond(param, result.Select(x => x.ToPropertyBag()).ToArray(), StatusCodes.Status200OK);
                }
            }
        }