Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added curated feed API service

  • Loading branch information...
commit 411471cda8c1b89fe7d019c61812e13901961aac 1 parent 7697c51
@half-ogre half-ogre authored
View
10 Facts/Services/FeedServiceFacts.cs
@@ -22,7 +22,7 @@ public void V1FeedSearchDoesNotReturnPrereleasePackages()
configuration.SetupGet(c => c.SiteRoot).Returns("https://localhost:8081/");
var searchService = new Mock<ISearchService>(MockBehavior.Strict);
searchService.Setup(s => s.SearchWithRelevance(It.IsAny<IQueryable<Package>>(), It.IsAny<String>())).Returns<IQueryable<Package>, string>((_, __) => _);
- var v1Service = new V1Feed(repo.Object, configuration.Object, searchService.Object);
+ var v1Service = new V1Feed(null, repo.Object, configuration.Object, searchService.Object);
// Act
var result = v1Service.Search(null, null);
@@ -49,7 +49,7 @@ public void V1FeedSearchDoesNotReturnUnlistedPackages()
searchService.Setup(s => s.SearchWithRelevance(It.IsAny<IQueryable<Package>>(), It.IsAny<String>())).Returns<IQueryable<Package>, string>((_, __) => _);
var configuration = new Mock<IConfiguration>(MockBehavior.Strict);
configuration.SetupGet(c => c.SiteRoot).Returns("http://test.nuget.org/");
- var v1Service = new V1Feed(repo.Object, configuration.Object, searchService.Object);
+ var v1Service = new V1Feed(null, repo.Object, configuration.Object, searchService.Object);
// Act
var result = v1Service.Search(null, null);
@@ -77,7 +77,7 @@ public void V2FeedSearchDoesNotReturnPrereleasePackagesIfFlagIsFalse()
searchService.Setup(s => s.SearchWithRelevance(It.IsAny<IQueryable<Package>>(), It.IsAny<String>())).Returns<IQueryable<Package>, string>((_, __) => _);
var configuration = new Mock<IConfiguration>(MockBehavior.Strict);
configuration.SetupGet(c => c.SiteRoot).Returns("https://staged.nuget.org/");
- var v2Service = new V2Feed(repo.Object, configuration.Object, searchService.Object);
+ var v2Service = new V2Feed(null, repo.Object, configuration.Object, searchService.Object);
// Act
var result = v2Service.Search(null, null, includePrerelease: false);
@@ -103,7 +103,7 @@ public void V1FeedFindPackagesByIdReturnsUnlistedPackagesButNotPrereleasePackage
}.AsQueryable());
var configuration = new Mock<IConfiguration>(MockBehavior.Strict);
configuration.SetupGet(c => c.SiteRoot).Returns("https://localhost:8081/");
- var v1Service = new V1Feed(repo.Object, configuration.Object, null);
+ var v1Service = new V1Feed(null, repo.Object, configuration.Object, null);
// Act
var result = v1Service.FindPackagesById("Foo");
@@ -127,7 +127,7 @@ public void V2FeedFindPackagesByIdReturnsUnlistedAndPrereleasePackages()
}.AsQueryable());
var configuration = new Mock<IConfiguration>(MockBehavior.Strict);
configuration.SetupGet(c => c.SiteRoot).Returns("https://localhost:8081/");
- var v2Service = new V2Feed(repo.Object, configuration.Object, null);
+ var v2Service = new V2Feed(null, repo.Object, configuration.Object, null);
// Act
var result = v2Service.FindPackagesById("Foo");
View
5 Website/App_Start/Routes.cs
@@ -187,6 +187,11 @@ public static void RegisterRoutes(RouteCollection routes)
constraints: new { httpMethod = new HttpMethodConstraint("DELETE") });
routes.MapServiceRoute(
+ RouteName.V2ApiCuratedFeed,
+ "api/v2/curated-feed",
+ typeof(V2CuratedFeed));
+
+ routes.MapServiceRoute(
RouteName.V2ApiFeed,
"api/v2/",
typeof(V2Feed));
View
17 Website/DataServices/FeedServiceBase.cs
@@ -14,26 +14,37 @@ namespace NuGetGallery
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public abstract class FeedServiceBase<TPackage> : DataService<FeedContext<TPackage>>, IDataServiceStreamProvider, IServiceProvider
{
+ private readonly IEntitiesContext entities;
private readonly IEntityRepository<Package> packageRepo;
private readonly IConfiguration configuration;
private readonly ISearchService searchService;
public FeedServiceBase()
- : this(DependencyResolver.Current.GetService<IEntityRepository<Package>>(),
+ : this(DependencyResolver.Current.GetService<IEntitiesContext>(),
+ DependencyResolver.Current.GetService<IEntityRepository<Package>>(),
DependencyResolver.Current.GetService<IConfiguration>(),
DependencyResolver.Current.GetService<ISearchService>())
{
}
- protected FeedServiceBase(IEntityRepository<Package> packageRepo, IConfiguration configuration, ISearchService searchService)
+ protected FeedServiceBase(
+ IEntitiesContext entities,
+ IEntityRepository<Package> packageRepo,
+ IConfiguration configuration,
+ ISearchService searchService)
{
- // TODO: See if there is a way to do proper DI with data services
+ this.entities = entities;
this.packageRepo = packageRepo;
this.configuration = configuration;
this.searchService = searchService;
}
+ protected IEntitiesContext Entities
+ {
+ get { return entities; }
+ }
+
protected IEntityRepository<Package> PackageRepo
{
get { return packageRepo; }
View
4 Website/DataServices/V1Feed.svc.cs
@@ -17,8 +17,8 @@ public V1Feed()
}
- public V1Feed(IEntityRepository<Package> repo, IConfiguration configuration, ISearchService searchSvc)
- : base(repo, configuration, searchSvc)
+ public V1Feed(IEntitiesContext entities, IEntityRepository<Package> repo, IConfiguration configuration, ISearchService searchSvc)
+ : base(entities, repo, configuration, searchSvc)
{
}
View
1  Website/DataServices/V2CuratedFeed.svc
@@ -0,0 +1 @@
+<%@ ServiceHost Language="C#" Debug="true" Service="NuGetGallery.V2Feed" CodeBehind="V2CuratedFeed.svc.cs" %>
View
82 Website/DataServices/V2CuratedFeed.svc.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Data.Entity;
+using System.Data.Services;
+using System.Linq;
+using System.ServiceModel.Web;
+using System.Web;
+using System.Web.Mvc;
+using System.Web.Routing;
+
+namespace NuGetGallery
+{
+ public class V2CuratedFeed : FeedServiceBase<V2FeedPackage>
+ {
+ private const int FeedVersion = 2;
+
+ public V2CuratedFeed()
+ {
+
+ }
+
+ public V2CuratedFeed(IEntitiesContext entities, IEntityRepository<Package> repo, IConfiguration configuration, ISearchService searchSvc)
+ : base(entities, repo, configuration, searchSvc)
+ {
+ }
+
+ protected override FeedContext<V2FeedPackage> CreateDataSource()
+ {
+ var packages = GetPackages();
+
+ return new FeedContext<V2FeedPackage>
+ {
+ Packages = packages.ToV2FeedPackageQuery(Configuration.SiteRoot)
+ };
+ }
+
+ [WebGet]
+ public IQueryable<V2FeedPackage> FindPackagesById(string id)
+ {
+ return GetPackages()
+ .Where(p => p.PackageRegistration.Id.Equals(id, StringComparison.OrdinalIgnoreCase))
+ .ToV2FeedPackageQuery(Configuration.SiteRoot);
+ }
+
+ public IQueryable<Package> GetPackages()
+ {
+ string curatedFeed = HttpContext.Current.Request.QueryString["name"];
+ if (curatedFeed == null)
+ throw new Exception();
+
+ return Entities.CuratedFeeds
+ .Where(cf => cf.Name == curatedFeed)
+ .Include(cf => cf.Packages.Select(cp => cp.PackageRegistration.Packages))
+ .SelectMany(cf => cf.Packages.SelectMany(cp => cp.PackageRegistration.Packages.Select(p => p)));
+ }
+
+ [WebGet]
+ public IQueryable<V2FeedPackage> Search(string searchTerm, string targetFramework, bool includePrerelease)
+ {
+ var packages = GetPackages();
+
+ packages = packages.Where(p => p.Listed);
+ if (!includePrerelease)
+ {
+ packages = packages.Where(p => !p.IsPrerelease);
+ }
+ return packages.Search(searchTerm).ToV2FeedPackageQuery(Configuration.SiteRoot);
+ }
+
+ public override Uri GetReadStreamUri(
+ object entity,
+ DataServiceOperationContext operationContext)
+ {
+ var package = (V2FeedPackage)entity;
+ var httpContext = new HttpContextWrapper(HttpContext.Current);
+ var urlHelper = new UrlHelper(new RequestContext(httpContext, new RouteData()));
+
+ string url = urlHelper.PackageDownload(FeedVersion, package.Id, package.Version);
+
+ return new Uri(url, UriKind.Absolute);
+ }
+ }
+}
View
4 Website/DataServices/V2Feed.svc.cs
@@ -18,8 +18,8 @@ public V2Feed()
}
- public V2Feed(IEntityRepository<Package> repo, IConfiguration configuration, ISearchService searchSvc)
- : base(repo, configuration, searchSvc)
+ public V2Feed(IEntitiesContext entities, IEntityRepository<Package> repo, IConfiguration configuration, ISearchService searchSvc)
+ : base(entities, repo, configuration, searchSvc)
{
}
View
1  Website/RouteNames.cs
@@ -2,6 +2,7 @@
{
public static class RouteName
{
+ public const string V2ApiCuratedFeed = "V2ApiCuratedFeed";
public const string V1ApiFeed = "V1ApiFeed";
public const string V2ApiFeed = "V2ApiFeed";
public const string ApiFeed = "ApiFeed";
View
4 Website/Website.csproj
@@ -169,6 +169,9 @@
<Compile Include="Controllers\AppController.cs" />
<Compile Include="Controllers\CuratedFeedsController.cs" />
<Compile Include="Controllers\CuratedPackagesController.cs" />
+ <Compile Include="DataServices\V2CuratedFeed.svc.cs">
+ <DependentUpon>V2CuratedFeed.svc</DependentUpon>
+ </Compile>
<Compile Include="DataServices\V1FeedPackage.cs">
<SubType>Code</SubType>
</Compile>
@@ -683,6 +686,7 @@
<Content Include="Content\Images\userIconWhite.png" />
<Content Include="Content\Images\xmark.png" />
<Content Include="Content\Images\sendMessageGraphic.png" />
+ <Content Include="DataServices\V2CuratedFeed.svc" />
<Content Include="DataServices\V1Feed.svc" />
<Content Include="DataServices\V2Feed.svc" />
<Content Include="DynamicData\Content\GridViewPager.ascx" />
Please sign in to comment.
Something went wrong with that request. Please try again.