public async Task RemoveExpirationWhenDisabled() { // Arrange var configuration = new Configuration() { ExpirationEnabled = false, ExpirationDays = 1, ExpirationRegex = @"\d" }; var dbFeature = new DbFeature { Version = "1.0.0" }; var additionalMetadata = new Dictionary <string, object> { { Constants.Documents.Metadata.Expires, DateTime.UtcNow } }; var expectedUploadDate = await PersistDocument("testdocument1", dbFeature, additionalMetadata); // Act var sut = new ExpirationManager(DocumentStoreProvider); await sut.ApplyExpirationPolicyAsync(configuration); WaitForIndexing(DocumentStore); // Assert await AssertMetadata("testdocument1", expectedUploadDate, null); }
public async Task <DbFeature> InsertOrUpdateFeatureAsync(Feature feature, string productName, string groupName, string version) { _logger.LogInformation("Persisting feature {FeatureTitle} version {Version} for product {ProductName} and group {GroupName}", feature.Title, version, productName, groupName); var hash = feature.CalculateHash(); DbFeature dbFeature; using (var session = _storeProvider.Store.OpenAsyncSession()) { dbFeature = await session.LoadAsync <DbFeature>(DbFeatureExtensions.GetIdentifier(productName, groupName, feature.Title, hash)); if (dbFeature != null) { // Add the new version to the list var versions = new List <string>(dbFeature.Versions); versions.Add(version); // Prevent duplicates dbFeature.Versions = versions.Distinct().ToArray(); } else { // Create a new feature var processor = new FeatureProcessor(); string parentTitle = processor.DetermineParent(feature); dbFeature = new DbFeature(feature, productName, groupName, parentTitle, version); await session.StoreAsync(dbFeature, dbFeature.GetIdentifier()); } await session.SaveChangesAsync(); } return(dbFeature); }
public async Task <HttpResponseMessage> PostAsync(Feature feature, string productName, string groupName, string title, string version) { if (!feature.Title.Equals(title, StringComparison.OrdinalIgnoreCase)) { return(Request.CreateResponse(HttpStatusCode.BadRequest, "The title provided by the POST data and the title in uri do not match!")); } var response = Request.CreateResponse(HttpStatusCode.Created); DbFeature dbFeature = null; try { dbFeature = await _featureManager.InsertOrUpdateFeatureAsync(feature, productName, groupName, version); } catch (Exception exception) { response = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, exception); } // Run the analysis for this feature if (dbFeature != null) { try { await _analyzer.AnalyzeAndPeristResultsAsync(productName, version, dbFeature); } catch { // Don't do anything, a broken analysis is no reason to report an error } } return(response); }
public async Task InsertOrUpdateFeatureAsync(Feature feature, string productName, string groupName, string version) { var processor = new FeatureProcessor(); string parentTitle = processor.DetermineParent(feature); DbFeature dbFeature = new DbFeature(feature, productName, groupName, parentTitle, version); var configuration = await ConfigurationManager.GetOrCreateConfigurationAsync(); using (var session = Database.DocumentStore.OpenAsyncSession()) { // Using the store method when the feature already exists in the database will override it completely, this is acceptable await session.StoreAsync(dbFeature, dbFeature.GetIdentifier()); if (configuration.ExpirationEnabled && Regex.IsMatch(version, configuration.ExpirationRegex)) { // Set the expiration in the metadata session.Advanced.GetMetadataFor(dbFeature)["Raven-Expiration-Date"] = new RavenJValue(DateTime.UtcNow.Date.AddDays(configuration.ExpirationDays)); } await session.SaveChangesAsync(); } }
/// <summary> /// Generates a <see cref="DbFeature" /> instance. /// </summary> /// <param name="product">Name of the product containing the feature.</param> /// <param name="group">Name of the group containing the feature.</param> /// <param name="title">Title of the feature.</param> /// <param name="version">Version of the feature.</param> /// <param name="tags">Optional additional tags for the feature.</param> /// <returns>A <see cref="DbFeature" /> instance with the provided values set.</returns> public static DbFeature GenerateDbFeature(string product, string group, string title, string version, params string[] tags) { var feature = new DbFeature { Product = product, Group = group, Title = title, Version = version }; feature.Tags = new List <string>(tags); return(feature); }
public async Task InsertOrUpdateFeatureAsync(Feature feature, string productName, string groupName, string version) { var processor = new FeatureProcessor(); string parentTitle = processor.DetermineParent(feature); DbFeature dbFeature = new DbFeature(feature, productName, groupName, parentTitle, version); using (var session = Database.DocumentStore.OpenAsyncSession()) { // Using the store method when the feature already exists in the database will override it completely, this is acceptable await session.StoreAsync(dbFeature, dbFeature.GetIdentifier()); await session.SaveChangesAsync(); } }
private static DbFeature CreateDbFeature(string featureName, params string[] directInvocationSignatures) { var result = new DbFeature() { Product = "TestProduct", Group = "TestGroup", Title = featureName, Version = "0.0.0", }; if (directInvocationSignatures != null && directInvocationSignatures.Length > 0) { result.DirectInvocationSignatures = new List <string>(directInvocationSignatures); } return(result); }
public async Task CanGetTags() { // Arrange var documentStoreProvider = DocumentStoreProvider; await documentStoreProvider.Store.ExecuteIndexAsync(new Features_ByProductAndBranch()); var feature1 = new DbFeature { Product = "MyProduct", Group = "MyGroup", Title = "MyFirstFeature", Version = "0.0.0" }; var feature2 = new DbFeature { Product = "MyProduct", Group = "MyGroup", Title = "MySecondFeature", Version = "0.0.0" }; feature1.Tags = new List <string> { "tag1", "tag2" }; feature2.Tags = new List <string> { "tag2", "tag3" }; using (var session = documentStoreProvider.Store.OpenAsyncSession()) { await session.StoreAsync(feature1, feature1.GetIdentifier()); await session.StoreAsync(feature2, feature2.GetIdentifier()); await session.SaveChangesAsync(); } WaitForIndexing(documentStoreProvider.Store); // Act var sut = new ProductManager(documentStoreProvider, logger); var result = await sut.GetTagsAsync("MyProduct"); // Assert result.ShouldNotBeNull(); result.Count().ShouldBe(3); result.SequenceEqual(new List <string> { "tag1", "tag2", "tag3" }); }
public async Task CanPersistDbFeatures() { // Arrange var documentStoreProvider = DocumentStoreProvider; var expectedFeature1 = new DbFeature() { Title = "MyFirstFeature", Product = "MyProduct", Group = "MyGroup", Versions = new [] { "0.0.0", "0.1.0" } }; var expectedFeature2 = new DbFeature() { Title = "MySecondFeature", Product = "MyProduct", Group = "MyGroup", Versions = new [] { "0.0.0" } }; // Act var sut = new FeatureManager(documentStoreProvider, logger); await sut.PersistDbFeatures(new[] { expectedFeature1, expectedFeature2 }); // Assert using (var session = documentStoreProvider.Store.OpenAsyncSession()) { var actualFeatures = await session.Query <DbFeature>().ToListAsync(); actualFeatures.ShouldNotBeNull(); actualFeatures.Count.ShouldBe(2); var actualFeature1 = actualFeatures.FirstOrDefault(); actualFeature1.ShouldNotBeNull(); actualFeature1.GetIdentifier().ShouldBe(expectedFeature1.GetIdentifier()); var actualFeature2 = actualFeatures.LastOrDefault(); actualFeature2.ShouldNotBeNull(); actualFeature2.GetIdentifier().ShouldBe(expectedFeature2.GetIdentifier()); } }
public async Task CanDeleteProductVersion() { // Arrange var documentStoreProvider = DocumentStoreProvider; await documentStoreProvider.Store.ExecuteIndexAsync(new Features_ByTitleProductAndGroup()); var existingFeature1 = new DbFeature { Product = "MyProduct", Group = "MyGroup", Title = "MyFirstFeature", Version = "0.0.0" }; var existingFeature2 = new DbFeature { Product = "MyProduct", Group = "MyGroup", Title = "MyFirstFeature", Version = "1.0.0" }; using (var session = documentStoreProvider.Store.OpenAsyncSession()) { await session.StoreAsync(existingFeature1, existingFeature1.GetIdentifier()); await session.StoreAsync(existingFeature2, existingFeature2.GetIdentifier()); await session.SaveChangesAsync(); } WaitForIndexing(documentStoreProvider.Store); // Act var sut = new ProductManager(documentStoreProvider, logger); await sut.DeleteProductAsync("MyProduct", "0.0.0"); // Assert using (var session = documentStoreProvider.Store.OpenAsyncSession()) { var actualFeature1 = await session.LoadAsync <DbFeature>(existingFeature1.GetIdentifier()); var actualFeature2 = await session.LoadAsync <DbFeature>(existingFeature2.GetIdentifier()); actualFeature1.ShouldBeNull(); actualFeature2.ShouldNotBeNull(); } }
public async Task <ActionResult <Feature> > PostAsync([FromBody] Feature feature, string productName, string groupName, string title, string version) { if (!feature.Title.Equals(title, StringComparison.OrdinalIgnoreCase)) { return(BadRequest("The title provided by the POST data and the title in uri do not match!")); } DbFeature dbFeature = await _featureManager.InsertOrUpdateFeatureAsync(feature, productName, groupName, version); // Run the analysis for this feature if (dbFeature != null) { try { await _analyzer.AnalyzeAndPeristResultsAsync(productName, version, dbFeature); } catch { // Don't do anything, a broken analysis is no reason to report an error } } return(Accepted()); }
public async Task <DbFeature> InsertOrUpdateFeatureAsync(Feature feature, string productName, string groupName, string version) { _logger.LogInformation("Persisting feature {FeatureTitle} version {Version} for product {ProductName} and group {GroupName}", feature.Title, version, productName, groupName); var processor = new FeatureProcessor(); string parentTitle = processor.DetermineParent(feature); DbFeature dbFeature = new DbFeature(feature, productName, groupName, parentTitle, version); var configuration = await _configurationManager.GetOrCreateConfigurationAsync(); using (var session = _storeProvider.Store.OpenAsyncSession()) { // Using the store method when the feature already exists in the database will override it completely, this is acceptable await session.StoreAsync(dbFeature, dbFeature.GetIdentifier()); session.SetExpirationAccordingToConfiguration(dbFeature, version, configuration); await session.SaveChangesAsync(); } return(dbFeature); }