diff --git a/BuildRevisionCounter/BuildRevisionCounter.csproj b/BuildRevisionCounter/BuildRevisionCounter.csproj index 1aab1c0..431239c 100644 --- a/BuildRevisionCounter/BuildRevisionCounter.csproj +++ b/BuildRevisionCounter/BuildRevisionCounter.csproj @@ -46,11 +46,21 @@ ..\packages\Microsoft.Owin.Host.SystemWeb.3.0.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll - - ..\packages\mongocsharpdriver.1.10.0\lib\net35\MongoDB.Bson.dll + + ..\packages\MongoDB.Bson.2.0.0\lib\net45\MongoDB.Bson.dll + True - - ..\packages\mongocsharpdriver.1.10.0\lib\net35\MongoDB.Driver.dll + + ..\packages\MongoDB.Driver.2.0.0\lib\net45\MongoDB.Driver.dll + True + + + ..\packages\MongoDB.Driver.Core.2.0.0\lib\net45\MongoDB.Driver.Core.dll + True + + + ..\packages\mongocsharpdriver.2.0.0\lib\net45\MongoDB.Driver.Legacy.dll + True ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll diff --git a/BuildRevisionCounter/Controllers/CounterController.cs b/BuildRevisionCounter/Controllers/CounterController.cs index 9715e7b..46404fd 100644 --- a/BuildRevisionCounter/Controllers/CounterController.cs +++ b/BuildRevisionCounter/Controllers/CounterController.cs @@ -1,10 +1,8 @@ using BuildRevisionCounter.Model; using MongoDB.Driver; -using MongoDB.Driver.Builders; using System; using System.Net; using System.Threading.Tasks; -using System.Web; using System.Web.Http; using BuildRevisionCounter.Security; @@ -18,16 +16,16 @@ public class CounterController : ApiController static CounterController() { - _storage = new MongoDBStorage(); + _storage = MongoDBStorage.Instance; } [HttpGet] [Route("{revisionName}")] [Authorize(Roles = "admin, editor, anonymous")] - public long Current([FromUri] string revisionName) + public async Task Current([FromUri] string revisionName) { - var q = Query.Where(_ => _.Id == revisionName); - var revision = _storage.Revisions.FindOne(q); + var q = Builders.Filter.Eq(_ => _.Id, revisionName); + var revision = await _storage.Revisions.Find(q).FirstOrDefaultAsync(); if (revision == null) throw new HttpResponseException(HttpStatusCode.NotFound); @@ -38,20 +36,21 @@ public long Current([FromUri] string revisionName) [HttpPost] [Route("{revisionName}")] [Authorize(Roles = "buildserver")] - public long Bumping([FromUri] string revisionName) + public async Task Bumping([FromUri] string revisionName) { - var result = _storage.Revisions.FindAndModify(new FindAndModifyArgs() + var options = new FindOneAndUpdateOptions { - Query = Query.Where(_ => _.Id == revisionName), - Upsert = true, - Update = Update - .SetOnInsert(_ => _.Created, DateTime.UtcNow) - .Inc(_ => _.NextNumber, 1) - .Set(_ => _.Updated, DateTime.UtcNow), - VersionReturned = FindAndModifyDocumentVersion.Modified - }); - - var revision = result.GetModifiedDocumentAs(); + IsUpsert = true, + ReturnDocument = ReturnDocument.After + }; + + var revision = await _storage.Revisions.FindOneAndUpdateAsync( + Builders.Filter.Eq(r => r.Id, revisionName), + Builders.Update + .SetOnInsert(l => l.Created, DateTime.UtcNow) + .Inc(l => l.NextNumber, 1) + .Set(l => l.Updated, DateTime.UtcNow), + options); return revision.NextNumber; } diff --git a/BuildRevisionCounter/MongoDBStorage.cs b/BuildRevisionCounter/MongoDBStorage.cs index b180884..6917658 100644 --- a/BuildRevisionCounter/MongoDBStorage.cs +++ b/BuildRevisionCounter/MongoDBStorage.cs @@ -13,25 +13,57 @@ namespace BuildRevisionCounter { public class MongoDBStorage { - public readonly MongoCollection Revisions; - public readonly MongoCollection Users; + private static readonly Object SLock = new Object(); + private static MongoDBStorage _instance = null; - public MongoDBStorage() + private readonly IMongoClient _client; + private readonly IMongoDatabase _database; + + private MongoDBStorage() { string connectionString = ConfigurationManager.ConnectionStrings["MongoDBStorage"].ConnectionString; - var database = MongoDatabase.Create(connectionString); + var url = new MongoUrl(connectionString); - Revisions = database.GetCollection("revisions"); - Users = database.GetCollection("users"); + _client = new MongoClient(url); + _database = _client.GetDatabase(url.DatabaseName); CreateAdmin(); } + public static MongoDBStorage Instance + { + get + { + if (_instance == null) + { + lock (SLock) + { + if (_instance == null) + _instance = new MongoDBStorage(); + } + } + return _instance; + } + } + + public IMongoCollection Revisions + { + get { return _database.GetCollection("revisions"); } + } + + public IMongoCollection Users + { + get { return _database.GetCollection("users"); } + } + private void CreateAdmin() { - if (!Users.AsQueryable().Any()) + var anyUser = Users.Find(l => true).SingleOrDefaultAsync(); + anyUser.Wait(); + + if (anyUser.Result == null) { - Users.Insert(new UserModel + Users.InsertOneAsync(new UserModel { Name = "admin", Password = "admin", diff --git a/BuildRevisionCounter/Security/BasicAuthenticationAttribute.cs b/BuildRevisionCounter/Security/BasicAuthenticationAttribute.cs index b2aac03..bf15562 100644 --- a/BuildRevisionCounter/Security/BasicAuthenticationAttribute.cs +++ b/BuildRevisionCounter/Security/BasicAuthenticationAttribute.cs @@ -6,7 +6,8 @@ using System.Threading; using System.Threading.Tasks; using System.Web.Http.Filters; -using BuildRevisionCounter.Model; +using BuildRevisionCounter.Model; +using MongoDB.Driver; using MongoDB.Driver.Builders; namespace BuildRevisionCounter.Security @@ -25,9 +26,9 @@ public class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter private static readonly MongoDBStorage _storage; - static BasicAuthenticationAttribute() - { - _storage = new MongoDBStorage(); + static BasicAuthenticationAttribute() + { + _storage = MongoDBStorage.Instance; } public bool AllowMultiple { get { return false; } } @@ -54,7 +55,7 @@ public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationTok return Task.FromResult(0); } - context.Principal = Authenticate(user, password); + context.Principal = Authenticate(user, password).Result; if (context.Principal == null) context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request); @@ -62,10 +63,10 @@ public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationTok return Task.FromResult(0); } - private IPrincipal Authenticate(string userName, string password) + private async Task Authenticate(string userName, string password) { - IPrincipal principal = null; - var user = _storage.Users.FindOne(Query.Where(u => u.Name == userName)); + IPrincipal principal = null; + var user = await _storage.Users.Find(l => l.Name == userName).SingleOrDefaultAsync(); if (user != null && user.Password == password) { principal = new GenericPrincipal(new GenericIdentity(userName), user.Roles); diff --git a/BuildRevisionCounter/Web.config b/BuildRevisionCounter/Web.config index 9c4d3df..210bf89 100644 --- a/BuildRevisionCounter/Web.config +++ b/BuildRevisionCounter/Web.config @@ -1,7 +1,7 @@  - + diff --git a/BuildRevisionCounter/packages.config b/BuildRevisionCounter/packages.config index a8f8967..aedcab5 100644 --- a/BuildRevisionCounter/packages.config +++ b/BuildRevisionCounter/packages.config @@ -5,7 +5,10 @@ - + + + + \ No newline at end of file