protected DataManagementControllerBase(
            IPipelineFactory pipelineFactory,
            ISchoolYearContextProvider schoolYearContextProvider,
            IRESTErrorProvider restErrorProvider,
            IDefaultPageSizeLimitProvider defaultPageSizeLimitProvider)
        {
            //this.repository = repository;
            SchoolYearContextProvider = schoolYearContextProvider;
            _restErrorProvider        = restErrorProvider;
            _defaultPageLimitSize     = defaultPageSizeLimitProvider.GetDefaultPageSizeLimit();

            GetByIdPipeline = new Lazy <GetPipeline <TResourceReadModel, TAggregateRoot> >
                                  (pipelineFactory.CreateGetPipeline <TResourceReadModel, TAggregateRoot>);

            GetManyPipeline = new Lazy <GetManyPipeline <TResourceReadModel, TAggregateRoot> >
                                  (pipelineFactory.CreateGetManyPipeline <TResourceReadModel, TAggregateRoot>);

            // Change queries resource pipeline for deleted objects.
            GetDeletedResourcePipeline = new Lazy <GetDeletedResourcePipeline <TAggregateRoot> >
                                             (pipelineFactory.CreateGetDeletedResourcePipeline <TResourceReadModel, TAggregateRoot>);

            PutPipeline = new Lazy <PutPipeline <TResourceWriteModel, TAggregateRoot> >
                              (pipelineFactory.CreatePutPipeline <TResourceWriteModel, TAggregateRoot>);

            DeletePipeline = new Lazy <DeletePipeline>
                                 (pipelineFactory.CreateDeletePipeline <TResourceReadModel, TAggregateRoot>);
        }
Пример #2
0
        public virtual async Task <IHttpActionResult> GetAll(
            [FromUri] UrlQueryParametersRequest urlQueryParametersRequest,
            [FromUri] TGetByExampleRequest request = default(TGetByExampleRequest))
        {
            var defaultPageSizeLimit = defaultPageSizeLimitProvider.GetDefaultPageSizeLimit();

            //respond quickly to DOS style requests (should we catch these earlier?  e.g. attribute filter?)
            if (urlQueryParametersRequest.Limit != null &&
                (urlQueryParametersRequest.Limit <= 0 || urlQueryParametersRequest.Limit > defaultPageSizeLimit))
            {
                return(BadRequest($"Limit must be omitted or set to a value between 1 and max value defined in configuration file (defaultPageSizeLimit)."));
            }

            var internalRequestAsResource = new TResourceReadModel();
            var internalRequest           = internalRequestAsResource as TEntityInterface;

            if (request != null)
            {
                MapAll(request, internalRequest);
            }

            //TODO: Add support for If-None-Match; current implementation cannot verify value without going to the db
            // Read the incoming ETag header, if present
            TryGetRequestHeader("If-None-Match", out string etagValue);

            var queryParameters = new QueryParameters(urlQueryParametersRequest);

            // Execute the pipeline (synchronously)
            var result = await getManyPipeline.Value
                         .ProcessAsync(
                new GetManyContext <TResourceReadModel, TAggregateRoot>(internalRequestAsResource, queryParameters),
                new CancellationToken());

            // Handle exception result
            if (result.Exception != null)
            {
                Logger.Error("GetAllRequest", result.Exception);
                return(CreateActionResultFromException(result.Exception));
            }

            var response = Request.CreateResponse(HttpStatusCode.OK, result.Resources);

            // Return multiple results

            if (queryParameters.TotalCount)
            {
                response.Headers.Add("Total-Count", result.ResultMetadata.TotalCount.ToString());
            }

            return(new ResponseMessageResult(response).WithContentType(GetReadContentType()));
        }
        public PagedAggregateIdsCriteriaProvider(
            ISessionFactory sessionFactory,
            IDescriptorsCache descriptorsCache,
            IDefaultPageSizeLimitProvider defaultPageSizeLimitProvider)
            : base(sessionFactory, descriptorsCache)
        {
            _identifierColumnNames = new Lazy <string[]>(
                () =>
            {
                var persister = (AbstractEntityPersister)SessionFactory.GetClassMetadata(typeof(TEntity));

                if (persister.IdentifierColumnNames != null && persister.IdentifierColumnNames.Length > 0)
                {
                    return(persister.IdentifierColumnNames);
                }

                return(new[] { "Id" });
            });

            _defaultPageLimitSize = defaultPageSizeLimitProvider.GetDefaultPageSizeLimit();
        }
        public IDictionary <string, Parameter> Create(bool isCompositeContext)
        {
            var parameters = new Dictionary <string, Parameter>
            {
                {
                    "offset", new Parameter
                    {
                        name        = "offset",
                        description = "Indicates how many items should be skipped before returning results.",
                        @in         = "query",
                        type        = "integer",
                        format      = "int32",
                        required    = false,
                        @default    = 0
                    }
                },
                {
                    "limit", new Parameter
                    {
                        name        = "limit",
                        description =
                            "Indicates the maximum number of items that should be returned in the results.",
                        @in      = "query",
                        type     = "integer",
                        format   = "int32",
                        minimum  = 0,
                        maximum  = _defaultPageSizeLimitProvider.GetDefaultPageSizeLimit(),
                        required = false,
                        @default = 25
                    }
                },
                {
                    "MinChangeVersion", new Parameter
                    {
                        name        = "minChangeVersion",
                        description =
                            "Used in synchronization to set sequence minimum ChangeVersion",
                        @in      = "query",
                        type     = "integer",
                        format   = "int64",
                        required = false
                    }
                },
                {
                    "MaxChangeVersion", new Parameter
                    {
                        name        = "maxChangeVersion",
                        description =
                            "Used in synchronization to set sequence maximum ChangeVersion",
                        @in      = "query",
                        type     = "integer",
                        format   = "int64",
                        required = false
                    }
                },
                {
                    "If-None-Match", new Parameter
                    {
                        name        = "If-None-Match",
                        description =
                            "The previously returned ETag header value, used here to prevent the unnecessary data transfer of an unchanged resource.",
                        @in      = "header",
                        type     = "string",
                        required = false
                    }
                },
                {
                    "fields", new Parameter
                    {
                        name        = "fields",
                        @in         = "query",
                        description =
                            "Specifies a subset of properties that should be returned for each entity (e.g. \"property1,collection1(collProp1,collProp2)\").",
                        type     = "string",
                        required = false
                    }
                },
                {
                    "queryExpression", new Parameter
                    {
                        @in         = "query",
                        name        = "q",
                        description =
                            "Specifies a query filter expression for the request. Currently only supports range-based queries on dates and numbers (e.g. \"schoolId:[255901000...255901002]\" and \"BeginDate:[2016-03-07...2016-03-10]\").",
                        type     = "string",
                        required = false
                    }
                }
            };

            if (!isCompositeContext)
            {
                parameters.Add(
                    "totalCount", new Parameter
                {
                    name        = "totalCount",
                    description =
                        "Indicates if the total number of items available should be returned in the 'Total-Count' header of the response.  If set to false, 'Total-Count' header will not be provided.",
                    @in      = "query",
                    type     = "boolean",
                    required = false,
                    @default = false
                }
                    );
            }

            return(parameters);
        }
        public virtual IHttpActionResult Get()
        {
            string    json      = null;
            RESTError restError = null;

            try
            {
                var routeDataValues = ActionContext.RequestContext.RouteData.Values;

                string organizationCode        = (string)routeDataValues["organizationCode"];
                string compositeCategory       = (string)routeDataValues["compositeCategory"];
                string compositeCollectionName = (string)routeDataValues["compositeName"];
                string compositeResourceName   = CompositeTermInflector.MakeSingular(compositeCollectionName);

                // Try to find the composite definition that matches the incoming URIs composite category/name
                if (!_compositeMetadataProvider.TryGetCompositeDefinition(
                        organizationCode,
                        compositeCategory,
                        compositeResourceName,
                        out XElement compositeDefinition))
                {
                    return(NotFound());
                }

                // Prepare query string parameters
                var rawQueryStringParameters = ActionContext.Request.RequestUri.ParseQueryString();

                var queryStringParameters =
                    rawQueryStringParameters.AllKeys.ToDictionary <string, string, object>(

                        // Replace underscores with periods for appropriate processing
                        kvp => kvp.Replace('_', '.'),
                        kvp => rawQueryStringParameters[kvp],
                        StringComparer.InvariantCultureIgnoreCase);

                var defaultPageSizeLimit = _defaultPageSizeLimitProvider.GetDefaultPageSizeLimit();

                //respond quickly to DOS style requests (should we catch these earlier?  e.g. attribute filter?)
                if (queryStringParameters.TryGetValue("limit", out object limitAsObject))
                {
                    if (int.TryParse(limitAsObject.ToString(), out int limit) &&
                        (limit <= 0 || limit > defaultPageSizeLimit))
                    {
                        return(BadRequest($"Limit must be omitted or set to a value between 1 and max value defined in configuration file (defaultPageSizeLimit)."));
                    }
                }

                // Process specification for route and query string parameters
                var specificationParameters = GetCompositeSpecificationParameters(
                    compositeDefinition, routeDataValues, queryStringParameters);

                // Ensure all matched route key values were used by the current composite
                var suppliedSpecificationParameters =
                    routeDataValues
                    .Where(kvp => !StandardApiRouteKeys.Contains(kvp.Key));

                var unusedSpecificationParameters =
                    suppliedSpecificationParameters
                    .Where(kvp => !specificationParameters.ContainsKey(kvp.Key));

                if (unusedSpecificationParameters.Any())
                {
                    return(new StatusCodeResult(HttpStatusCode.NotFound, this));
                }

                AddInherentSupportForIdParameter(specificationParameters);

                json = _compositeResourceResponseProvider.GetJson(
                    compositeDefinition,
                    specificationParameters,
                    queryStringParameters,
                    GetNullValueHandling());
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                restError = _restErrorProvider.GetRestErrorFromException(ex);
            }

            if (restError != null)
            {
                return(string.IsNullOrWhiteSpace(restError.Message)
                    ? new StatusCodeResult((HttpStatusCode)restError.Code, this)
                    : new StatusCodeResult((HttpStatusCode)restError.Code, this).WithError(restError.Message));
            }

            return(new ResponseMessageResult(
                       new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(json, Encoding.UTF8, "application/json")
            }));
        }