public IHttpActionResult Get(ODataQueryOptions <V1FeedPackage> options) { if (!_featureFlagService.IsODataV1GetAllEnabled()) { return(BadRequest(Strings.ODataDisabled)); } if (!ODataQueryVerifier.AreODataOptionsAllowed(options, ODataQueryVerifier.V1Packages, _configurationService.Current.IsODataFilterEnabled, nameof(Get))) { return(BadRequest(ODataQueryVerifier.GetValidationFailedMessage(options))); } bool result = TryShouldIgnoreOrderById(options, out var shouldIgnoreOrderById); if (!result) { return(BadRequest("Invalid OrderBy parameter")); } var queryable = GetAll() .Where(p => !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available) .Where(SemVerLevelKey.IsUnknownPredicate()) .WithoutSortOnColumn(Version) .WithoutSortOnColumn(Id, shouldIgnoreOrderById) .ToV1FeedPackageQuery(_configurationService.GetSiteRoot(UseHttps())); return(TrackedQueryResult(options, queryable, MaxPageSize, customQuery: true)); }
public IHttpActionResult Get(ODataQueryOptions <V1FeedPackage> options) { if (!ODataQueryVerifier.AreODataOptionsAllowed(options, ODataQueryVerifier.V1Packages, _configurationService.Current.IsODataFilterEnabled, nameof(Get))) { return(BadRequest(ODataQueryVerifier.GetValidationFailedMessage(options))); } var queryable = _packagesRepository.GetAll() .Where(p => !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available) .Where(SemVerLevelKey.IsUnknownPredicate()) .WithoutSortOnColumn(Version) .WithoutSortOnColumn(Id, ShouldIgnoreOrderById(options)) .ToV1FeedPackageQuery(_configurationService.GetSiteRoot(UseHttps())); return(QueryResult(options, queryable, MaxPageSize)); }
public async Task <IHttpActionResult> Search( ODataQueryOptions <V1FeedPackage> options, [FromODataUri] string searchTerm = "", [FromODataUri] string targetFramework = "") { // Handle OData-style |-separated list of frameworks. string[] targetFrameworkList = (targetFramework ?? "").Split(new[] { '\'', '|' }, StringSplitOptions.RemoveEmptyEntries); // For now, we'll just filter on the first one. if (targetFrameworkList.Length > 0) { // Until we support multiple frameworks, we need to prefer aspnet50 over aspnetcore50. if (targetFrameworkList.Contains("aspnet50")) { targetFramework = "aspnet50"; } else { targetFramework = targetFrameworkList[0]; } } // Perform actual search var packages = GetAll() .Include(p => p.PackageRegistration) .Include(p => p.PackageRegistration.Owners) .Where(p => p.Listed && !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available) .Where(SemVerLevelKey.IsUnknownPredicate()) .OrderBy(p => p.PackageRegistration.Id).ThenBy(p => p.Version) .AsNoTracking(); // todo: search hijack should take queryOptions instead of manually parsing query options var searchService = _searchServiceFactory.GetService(); var searchAdaptorResult = await SearchAdaptor.SearchCore( searchService, GetTraditionalHttpContext().Request, packages, searchTerm, targetFramework, includePrerelease : false, semVerLevel : null); // Packages provided by search service (even when not hijacked) var query = searchAdaptorResult.Packages; bool?customQuery = null; // If intercepted, create a paged queryresult if (searchAdaptorResult.ResultsAreProvidedBySearchService) { customQuery = false; // Add explicit Take() needed to limit search hijack result set size if $top is specified var totalHits = query.LongCount(); var pagedQueryable = query .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize) .ToV1FeedPackageQuery(GetSiteRoot()); return(TrackedQueryResult( options, pagedQueryable, MaxPageSize, totalHits, (o, s, resultCount) => SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { searchTerm, targetFramework }, o, s), customQuery)); } else { customQuery = true; } if (!ODataQueryVerifier.AreODataOptionsAllowed(options, ODataQueryVerifier.V1Search, _configurationService.Current.IsODataFilterEnabled, nameof(Search))) { return(BadRequest(ODataQueryVerifier.GetValidationFailedMessage(options))); } // If not, just let OData handle things var queryable = query.ToV1FeedPackageQuery(GetSiteRoot()); return(TrackedQueryResult(options, queryable, MaxPageSize, customQuery)); }
private async Task <IHttpActionResult> GetCore(ODataQueryOptions <V1FeedPackage> options, string id, string version, bool return404NotFoundWhenNoResults) { var packages = GetAll() .Include(p => p.PackageRegistration) .Where(p => p.PackageRegistration.Id.Equals(id, StringComparison.OrdinalIgnoreCase) && !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available) .Where(SemVerLevelKey.IsUnknownPredicate()); if (!string.IsNullOrEmpty(version)) { packages = packages.Where(p => p.Version == version); } bool?customQuery = null; // try the search service try { var searchService = _searchServiceFactory.GetService(); var searchAdaptorResult = await SearchAdaptor.FindByIdAndVersionCore( searchService, GetTraditionalHttpContext().Request, packages, id, version, semVerLevel : null); // If intercepted, create a paged queryresult if (searchAdaptorResult.ResultsAreProvidedBySearchService) { customQuery = false; // Packages provided by search service packages = searchAdaptorResult.Packages; // Add explicit Take() needed to limit search hijack result set size if $top is specified var totalHits = packages.LongCount(); if (return404NotFoundWhenNoResults && totalHits == 0) { _telemetryService.TrackODataCustomQuery(customQuery); return(NotFound()); } var pagedQueryable = packages .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize) .ToV1FeedPackageQuery(GetSiteRoot()); return(TrackedQueryResult( options, pagedQueryable, MaxPageSize, totalHits, (o, s, resultCount) => SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { id }, o, s), customQuery)); } else { customQuery = true; } } catch (Exception ex) { // Swallowing Exception intentionally. If *anything* goes wrong in search, just fall back to the database. // We don't want to break package restores. We do want to know if this happens, so here goes: QuietLog.LogHandledException(ex); } if (return404NotFoundWhenNoResults && !packages.Any()) { _telemetryService.TrackODataCustomQuery(customQuery); return(NotFound()); } var queryable = packages.ToV1FeedPackageQuery(GetSiteRoot()); return(TrackedQueryResult(options, queryable, MaxPageSize, customQuery)); }
private async Task <IHttpActionResult> GetCore( ODataQueryOptions <V1FeedPackage> options, string id, string version, bool return404NotFoundWhenNoResults, bool isNonHijackEnabled) { var packages = GetAll() .Include(p => p.PackageRegistration) .Where(p => p.PackageRegistration.Id.Equals(id, StringComparison.OrdinalIgnoreCase) && !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available) .Where(SemVerLevelKey.IsUnknownPredicate()); if (!string.IsNullOrEmpty(version)) { packages = packages.Where(p => p.Version == version); } bool?customQuery = null; // try the search service try { var searchService = _searchServiceFactory.GetService(); var searchAdaptorResult = await SearchAdaptor.FindByIdAndVersionCore( searchService, GetTraditionalHttpContext().Request, packages, id, version, semVerLevel : null); // If intercepted, create a paged queryresult if (searchAdaptorResult.ResultsAreProvidedBySearchService) { customQuery = false; // Packages provided by search service packages = searchAdaptorResult.Packages; // Add explicit Take() needed to limit search hijack result set size if $top is specified var totalHits = packages.LongCount(); if (return404NotFoundWhenNoResults && totalHits == 0) { _telemetryService.TrackODataCustomQuery(customQuery); return(NotFound()); } var pagedQueryable = packages .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize) .ToV1FeedPackageQuery(GetSiteRoot()); return(TrackedQueryResult( options, pagedQueryable, MaxPageSize, totalHits, (o, s, resultCount) => SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { id }, o, s), customQuery)); } else { customQuery = true; } } catch (Exception ex) when(isNonHijackEnabled) { // Swallowing exception intentionally if we are allowing a fallback to database. If non-hijacked // queries are disabled, let the exception bubble out and the client will retry. QuietLog.LogHandledException(ex); } // If we've reached this point, the hijack to the search service has failed or is not applicable. If // non-hijacked queries are disabled, stop here. if (!isNonHijackEnabled) { return(BadRequest(Strings.ODataParametersDisabled)); } if (return404NotFoundWhenNoResults && !packages.Any()) { _telemetryService.TrackODataCustomQuery(customQuery); return(NotFound()); } var queryable = packages.ToV1FeedPackageQuery(GetSiteRoot()); return(TrackedQueryResult(options, queryable, MaxPageSize, customQuery)); }