Permalink
Fetching contributors…
Cannot retrieve contributors at this time
426 lines (362 sloc) 16.9 KB
using System;
using System.Collections.Generic;
using System.Linq;
using Funq;
using NUnit.Framework;
using ServiceStack.DataAnnotations;
using ServiceStack.Text;
using Amazon.DynamoDBv2;
using ServiceStack.Aws.DynamoDb;
namespace ServiceStack.WebHost.Endpoints.Tests
{
public class AutoQueryDataDynamoTests : AutoQueryDataTests
{
public override ServiceStackHost CreateAppHost()
{
return new AutoQueryDataDynamoAppHost();
}
[Test]
public void Does_perform_QUERY_operation_when_querying_hash_key()
{
var response = client.Get(new QueryDataRockstarAlbums
{
RockstarId = 3,
Genre = "Grunge",
});
Assert.That(response.Results.Count, Is.EqualTo(4));
Assert.That(response.Results.Map(x => x.RockstarId).Distinct(),
Is.EquivalentTo(new[] { 3 }));
}
[Test]
public void Does_perform_SCAN_operation_when_not_querying_hash_key()
{
var response = client.Get(new QueryDataRockstarAlbums
{
Genre = "Grunge",
});
Assert.That(response.Results.Count, Is.EqualTo(5));
Assert.That(response.Results.Map(x => x.RockstarId).Distinct(),
Is.EquivalentTo(new[] { 3, 5 }));
}
[Test]
public void Can_query_on_ForeignKey_and_RockstarAlbumGenreIndex()
{
QueryResponse<RockstarAlbumGenreGlobalIndex> response;
response = client.Get(new QueryDataRockstarAlbumGenreIndex { Genre = "Grunge", Include = "Total" }); //Hash
Assert.That(response.Results.Count, Is.EqualTo(5));
Assert.That(response.Total, Is.EqualTo(5));
response = client.Get(new QueryDataRockstarAlbumGenreIndex { Genre = "Grunge", Id = 3, Include = "Total" }); //Hash + Range
Assert.That(response.Results.Count, Is.EqualTo(1));
Assert.That(response.Total, Is.EqualTo(1));
Assert.That(response.Results[0].Name, Is.EqualTo("Nevermind"));
//Hash + Range BETWEEN
response = client.Get(new QueryDataRockstarAlbumGenreIndex
{
Genre = "Grunge",
IdBetween = new[] { 2, 3 },
Include = "Total"
});
Assert.That(response.Results.Count, Is.EqualTo(2));
Assert.That(response.Total, Is.EqualTo(2));
//Hash + Range BETWEEN + Filter
response = client.Get(new QueryDataRockstarAlbumGenreIndex
{
Genre = "Grunge",
IdBetween = new[] { 2, 3 },
Name = "Nevermind",
Include = "Total"
});
Assert.That(response.Results.Count, Is.EqualTo(1));
Assert.That(response.Total, Is.EqualTo(1));
Assert.That(response.Results[0].Id, Is.EqualTo(3));
response.PrintDump();
}
[Test]
public void Can_query_on_ForeignKey_and_RockstarAlbumGenreIndex_Mapped()
{
QueryResponse<RockstarAlbum> response;
response = client.Get(new QueryDataRockstarAlbumGenreIndexMapped { Genre = "Grunge", Include = "Total" }); //Hash
Assert.That(response.Results.Count, Is.EqualTo(5));
Assert.That(response.Total, Is.EqualTo(5));
response = client.Get(new QueryDataRockstarAlbumGenreIndexMapped { Genre = "Grunge", Id = 3, Include = "Total" }); //Hash + Range
Assert.That(response.Results.Count, Is.EqualTo(1));
Assert.That(response.Total, Is.EqualTo(1));
Assert.That(response.Results[0].Name, Is.EqualTo("Nevermind"));
//Hash + Range BETWEEN
response = client.Get(new QueryDataRockstarAlbumGenreIndexMapped
{
Genre = "Grunge",
IdBetween = new[] { 2, 3 },
Include = "Total"
});
Assert.That(response.Results.Count, Is.EqualTo(2));
Assert.That(response.Total, Is.EqualTo(2));
//Hash + Range BETWEEN + Filter
response = client.Get(new QueryDataRockstarAlbumGenreIndexMapped
{
Genre = "Grunge",
IdBetween = new[] { 2, 3 },
Name = "Nevermind",
Include = "Total"
});
Assert.That(response.Results.Count, Is.EqualTo(1));
Assert.That(response.Total, Is.EqualTo(1));
Assert.That(response.Results[0].Id, Is.EqualTo(3));
response.PrintDump();
}
[Test]
public void Can_query_MovieTitleIndex_Ratings()
{
var response = client.Get(new QueryDataMovieTitleIndex { Ratings = new[] { "G", "PG-13" } });
Assert.That(response.Results.Count, Is.EqualTo(5));
var url = Config.ListeningOn + "moviesdataindex/search?ratings=G,PG-13";
response = url.AsJsonInto<MovieTitleIndex>();
Assert.That(response.Results.Count, Is.EqualTo(5));
response = client.Get(new QueryDataMovieTitleIndex
{
Ids = new[] { 1, 2 },
ImdbIds = new[] { "tt0071562", "tt0060196" },
Ratings = new[] { "G", "PG-13" }
});
Assert.That(response.Results.Count, Is.EqualTo(9));
url = Config.ListeningOn + "moviesdataindex?ratings=G,PG-13&ids=1,2&imdbIds=tt0071562,tt0060196";
response = url.AsJsonInto<MovieTitleIndex>();
Assert.That(response.Results.Count, Is.EqualTo(9));
}
[Test]
public void Does_implicitly_OrderBy_PrimaryKey_when_limits_is_specified_SearchDataMovieTitleIndex()
{
var movies = client.Get(new SearchDataMovieTitleIndex { Take = 100 });
var ids = movies.Results.Map(x => x.Id);
var orderedIds = ids.OrderBy(x => x);
Assert.That(ids, Is.EqualTo(orderedIds));
var rockstars = client.Get(new SearchDataMovieTitleIndex { Take = 100 });
ids = rockstars.Results.Map(x => x.Id);
orderedIds = ids.OrderBy(x => x);
Assert.That(ids, Is.EqualTo(orderedIds));
}
[Test]
public void Can_OrderBy_queries_SearchDataMovieTitleIndex()
{
var movies = client.Get(new SearchDataMovieTitleIndex { Take = 100, OrderBy = "ImdbId" });
var ids = movies.Results.Map(x => x.ImdbId);
var orderedIds = ids.OrderBy(x => x).ToList();
Assert.That(ids, Is.EqualTo(orderedIds));
movies = client.Get(new SearchDataMovieTitleIndex { Take = 100, OrderBy = "Rating,ImdbId" });
ids = movies.Results.Map(x => x.ImdbId);
orderedIds = movies.Results.OrderBy(x => x.Rating).ThenBy(x => x.ImdbId).Map(x => x.ImdbId);
Assert.That(ids, Is.EqualTo(orderedIds));
movies = client.Get(new SearchDataMovieTitleIndex { Take = 100, OrderByDesc = "ImdbId" });
ids = movies.Results.Map(x => x.ImdbId);
orderedIds = ids.OrderByDescending(x => x).ToList();
Assert.That(ids, Is.EqualTo(orderedIds));
movies = client.Get(new SearchDataMovieTitleIndex { Take = 100, OrderByDesc = "Rating,ImdbId" });
ids = movies.Results.Map(x => x.ImdbId);
orderedIds = movies.Results.OrderByDescending(x => x.Rating)
.ThenByDescending(x => x.ImdbId).Map(x => x.ImdbId);
Assert.That(ids, Is.EqualTo(orderedIds));
movies = client.Get(new SearchDataMovieTitleIndex { Take = 100, OrderBy = "Rating,-ImdbId" });
ids = movies.Results.Map(x => x.ImdbId);
orderedIds = movies.Results.OrderBy(x => x.Rating)
.ThenByDescending(x => x.ImdbId).Map(x => x.ImdbId);
Assert.That(ids, Is.EqualTo(orderedIds));
movies = client.Get(new SearchDataMovieTitleIndex { Take = 100, OrderByDesc = "Rating,-ImdbId" });
ids = movies.Results.Map(x => x.ImdbId);
orderedIds = movies.Results.OrderByDescending(x => x.Rating)
.ThenBy(x => x.ImdbId).Map(x => x.ImdbId);
Assert.That(ids, Is.EqualTo(orderedIds));
var url = Config.ListeningOn + "moviesdata/search?take=100&orderBy=Rating,ImdbId";
movies = url.AsJsonInto<MovieTitleIndex>();
ids = movies.Results.Map(x => x.ImdbId);
orderedIds = movies.Results.OrderBy(x => x.Rating).ThenBy(x => x.ImdbId).Map(x => x.ImdbId);
Assert.That(ids, Is.EqualTo(orderedIds));
url = Config.ListeningOn + "moviesdata/search?take=100&orderByDesc=Rating,ImdbId";
movies = url.AsJsonInto<MovieTitleIndex>();
ids = movies.Results.Map(x => x.ImdbId);
orderedIds = movies.Results.OrderByDescending(x => x.Rating)
.ThenByDescending(x => x.ImdbId).Map(x => x.ImdbId);
Assert.That(ids, Is.EqualTo(orderedIds));
}
[Test]
public void Cached_DynamoQuery_does_cached_duplicate_requests_when_MaxAge()
{
var request = new QueryCacheMaxAgeDataRockstars();
var client = new CachedServiceClient(new JsonServiceClient(Config.ListeningOn));
var response = client.Get(request);
Assert.That(client.CacheHits, Is.EqualTo(0));
Assert.That(response.Results.Count, Is.EqualTo(Rockstars.Count));
response = client.Get(request);
Assert.That(client.CacheHits, Is.EqualTo(1));
Assert.That(response.Results.Count, Is.EqualTo(Rockstars.Count));
response = client.Get(new QueryCacheMaxAgeDataRockstars { Age = 27 });
Assert.That(client.CacheHits, Is.EqualTo(1));
Assert.That(response.Results.Count, Is.EqualTo(Rockstars.Count(x => x.Age == 27)));
}
[Test]
public void Cached_DynamoQuery_does_cached_duplicate_requests_when_MaxAge_Custom_Cached()
{
var request = new CustomQueryCacheMaxAgeDataRockstars();
var client = new CachedServiceClient(new JsonServiceClient(Config.ListeningOn));
var response = client.Get(request);
Assert.That(client.CacheHits, Is.EqualTo(0));
Assert.That(response.Results.Count, Is.EqualTo(Rockstars.Count));
response = client.Get(request);
Assert.That(client.CacheHits, Is.EqualTo(1));
Assert.That(response.Results.Count, Is.EqualTo(Rockstars.Count));
response = client.Get(new CustomQueryCacheMaxAgeDataRockstars { Age = 27 });
Assert.That(client.CacheHits, Is.EqualTo(1));
Assert.That(response.Results.Count, Is.EqualTo(Rockstars.Count(x => x.Age == 27)));
}
[Test]
public void Cached_DynamoQuery_does_return_NotModified_when_MustRevalidate()
{
var request = new QueryCacheMustRevalidateDataRockstars();
var client = new CachedServiceClient(new JsonServiceClient(Config.ListeningOn));
var response = client.Get(request);
Assert.That(client.NotModifiedHits, Is.EqualTo(0));
Assert.That(response.Results.Count, Is.EqualTo(Rockstars.Count));
response = client.Get(request);
Assert.That(client.NotModifiedHits, Is.EqualTo(1));
Assert.That(response.Results.Count, Is.EqualTo(Rockstars.Count));
response = client.Get(new QueryCacheMustRevalidateDataRockstars { Age = 27 });
Assert.That(client.CacheHits, Is.EqualTo(0));
Assert.That(client.NotModifiedHits, Is.EqualTo(1));
Assert.That(response.Results.Count, Is.EqualTo(Rockstars.Count(x => x.Age == 27)));
}
[Test]
public void Does_throw_on_SCAN_when_not_allowScans()
{
var results = client.Get(new QueryScannedTable { Id = 1 });
Assert.Throws<WebServiceException>(() =>
client.Get(new QueryScannedTable { Name = "foo" })
);
}
}
public class AutoQueryDataDynamoAppHost : AutoQueryDataAppHost
{
public override void Configure(Container container)
{
base.Configure(container);
container.Register(c => new PocoDynamo(
new AmazonDynamoDBClient("keyId", "key", new AmazonDynamoDBConfig
{
ServiceURL = "http://localhost:8000",
}))
.RegisterTable<Rockstar>()
.RegisterTable<RockstarAlbum>()
.RegisterTable<Adhoc>()
.RegisterTable<Movie>()
.RegisterTable<AllFields>()
.RegisterTable<PagingTest>()
.RegisterTable<ScannedTable>()
);
var dynamo = container.Resolve<IPocoDynamo>();
//dynamo.DeleteAllTables();
dynamo.InitSchema();
dynamo.PutItems(SeedRockstars);
dynamo.PutItems(SeedAlbums);
dynamo.PutItems(SeedAdhoc);
dynamo.PutItems(SeedMovies);
dynamo.PutItems(SeedAllFields);
dynamo.PutItems(SeedPagingTest);
var feature = this.GetPlugin<AutoQueryDataFeature>();
feature.AddDataSource(ctx => ctx.DynamoDbSource<Rockstar>());
feature.AddDataSource(ctx => ctx.DynamoDbSource<RockstarAlbum>());
feature.AddDataSource(ctx => ctx.DynamoDbSource<RockstarAlbumGenreGlobalIndex>());
feature.AddDataSource(ctx => ctx.DynamoDbSource<Adhoc>());
feature.AddDataSource(ctx => ctx.DynamoDbSource<Movie>());
feature.AddDataSource(ctx => ctx.DynamoDbSource<MovieTitleIndex>());
feature.AddDataSource(ctx => ctx.DynamoDbSource<AllFields>());
feature.AddDataSource(ctx => ctx.DynamoDbSource<PagingTest>());
feature.AddDataSource(ctx => ctx.DynamoDbSource<ScannedTable>(allowScans: false));
}
}
public class ScannedTable
{
public int Id { get; set; }
public string Name { get; set; }
}
public class QueryScannedTable : QueryData<ScannedTable>
{
public int? Id { get; set; }
public string Name { get; set; }
}
[Route("/moviesdataindex/search")]
[QueryData(QueryTerm.And)] //Default
public class SearchDataMovieTitleIndex : QueryData<MovieTitleIndex> { }
[Route("/moviesdataindex")]
[QueryData(QueryTerm.Or)]
public class QueryDataMovieTitleIndex : QueryData<MovieTitleIndex>
{
public int[] Ids { get; set; }
public string[] ImdbIds { get; set; }
public string[] Ratings { get; set; }
}
public class MovieTitleIndex : IGlobalIndex<Movie>
{
[HashKey]
public string Title { get; set; }
[RangeKey]
public decimal Score { get; set; }
public int Id { get; set; }
public string ImdbId { get; set; }
public string Rating { get; set; }
public string Director { get; set; }
public DateTime ReleaseDate { get; set; }
public string TagLine { get; set; }
public List<string> Genres { get; set; }
}
[Route("/querydata/rockstaralbumindex")]
public class QueryDataRockstarAlbumGenreIndex : QueryData<RockstarAlbumGenreGlobalIndex>
{
public int? Id { get; set; }
public int? RockstarId { get; set; }
public string Name { get; set; }
public string Genre { get; set; }
public int[] IdBetween { get; set; }
}
[Route("/querydata/rockstaralbumindex/mapped")]
public class QueryDataRockstarAlbumGenreIndexMapped : QueryData<RockstarAlbumGenreGlobalIndex, RockstarAlbum>
{
public int? Id { get; set; }
public int? RockstarId { get; set; }
public string Name { get; set; }
public string Genre { get; set; }
public int[] IdBetween { get; set; }
}
public class RockstarAlbumGenreGlobalIndex : IGlobalIndex<RockstarAlbum>
{
[HashKey]
public string Genre { get; set; }
[RangeKey]
public int Id { get; set; }
public string Name { get; set; }
public int RockstarId { get; set; }
}
[CacheResponse(Duration = 10, MaxAge = 10)]
[Route("/querydata/cachemaxage/rockstars")]
public class QueryCacheMaxAgeDataRockstars : QueryData<Rockstar>
{
public int? Age { get; set; }
}
[CacheResponse(Duration = 10, MaxAge = 0, CacheControl = CacheControl.MustRevalidate)]
[Route("/querydata/cachemustrevalidate/rockstars")]
public class QueryCacheMustRevalidateDataRockstars : QueryData<Rockstar>
{
public int? Age { get; set; }
}
[Route("/custom/querydata/cachemaxage/rockstars")]
public class CustomQueryCacheMaxAgeDataRockstars : QueryData<Rockstar>
{
public int? Age { get; set; }
}
[CacheResponse(Duration = 10, MaxAge = 10)]
public class MyCachedAutoQueryServices : Service
{
public IAutoQueryData AutoQuery { get; set; }
public object Any(CustomQueryCacheMaxAgeDataRockstars query)
{
return AutoQuery.Execute(query, AutoQuery.CreateQuery(query, Request));
}
}
}