private async Task SyncPlatforms() { using (ProvisioningAppDBContext context = GetContext()) { // Find the platforms file ITemplateFile file = (await _cloneProvider.GetAsync(SYSTEM_PATH, WriteLog)).FindFile(PLATFORMS_NAME); if (file == null) { throw new InvalidOperationException($"Cannot find file {PLATFORMS_NAME}"); } // Deserialize the json var platforms = await file.DownloadAsJsonAsync(new { platforms = new[] { new { id = "", displayName = "" } } }); var existingDbPlatforms = context.Platforms.ToDictionary(c => c.Id, StringComparer.OrdinalIgnoreCase); foreach (var platform in platforms.platforms) { // Update platform, if already exists if (existingDbPlatforms.TryGetValue(platform.id, out Platform dbPlatform)) { dbPlatform.DisplayName = platform.displayName; context.Entry(dbPlatform).State = EntityState.Modified; } else { // Add new platform dbPlatform = new Platform { Id = platform.id, DisplayName = platform.displayName, }; context.Entry(dbPlatform).State = EntityState.Added; } existingDbPlatforms.Remove(platform.id); } // Remove exceed platforms var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbPlatform in existingDbPlatforms) { await context.Entry(dbPlatform.Value).Collection(p => p.Packages).LoadAsync(); foreach (var dbPackage in dbPlatform.Value.Packages.ToArray()) { objectStateManager.ChangeRelationshipState(dbPlatform.Value, dbPackage, p => p.Packages, EntityState.Deleted); } context.Entry(dbPlatform.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
private async Task SyncCategories() { using (ProvisioningAppDBContext context = GetContext()) { // Find the category file ITemplateFile file = (await _cloneProvider.GetAsync(SYSTEM_PATH, WriteLog)).FindFile(CATEGORIES_NAME); if (file == null) { throw new InvalidOperationException($"Cannot find file {CATEGORIES_NAME}"); } // Deserialize the json var categories = await file.DownloadAsJsonAsync(new { categories = new[] { new { id = "", displayName = "" } } }); var existingDbCategories = context.Categories.ToDictionary(c => c.Id, StringComparer.OrdinalIgnoreCase); foreach (var category in categories.categories) { // Update category, if already exists if (existingDbCategories.TryGetValue(category.id, out Category dbCategory)) { dbCategory.DisplayName = category.displayName; context.Entry(dbCategory).State = EntityState.Modified; } else { // Add new category dbCategory = new Category { Id = category.id, DisplayName = category.displayName }; context.Entry(dbCategory).State = EntityState.Added; } existingDbCategories.Remove(category.id); } // Remove exceed categories var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbCategory in existingDbCategories) { await context.Entry(dbCategory.Value).Collection(d => d.Packages).LoadAsync(); foreach (var dbPackage in dbCategory.Value.Packages.ToArray()) { objectStateManager.ChangeRelationshipState(dbCategory.Value, dbPackage, d => d.Packages, EntityState.Deleted); } context.Entry(dbCategory.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
private async Task SyncFirstReleaseTenants() { using (ProvisioningAppDBContext context = GetContext()) { // Find the category file ITemplateFile file = (await _cloneProvider.GetAsync(SYSTEM_PATH, WriteLog)).FindFile(TENANTS_NAME); if (file == null) { throw new InvalidOperationException($"Cannot find file {TENANTS_NAME}"); } // Deserialize the json var tenantsList = await file.DownloadAsJsonAsync(new { tenants = new[] { new { id = "", tenantName = "", referenceOwner = "" } } }); var existingDbTenants = context.Tenants.ToDictionary(t => t.Id, StringComparer.OrdinalIgnoreCase); foreach (var tenant in tenantsList.tenants) { // Update tenant, if already exists if (existingDbTenants.TryGetValue(tenant.id, out Tenant dbTenant)) { dbTenant.TenantName = tenant.tenantName; dbTenant.ReferenceOwner = tenant.referenceOwner; context.Entry(dbTenant).State = EntityState.Modified; } else { // Add new tenant dbTenant = new Tenant { Id = tenant.id, TenantName = tenant.tenantName, ReferenceOwner = tenant.referenceOwner }; context.Entry(dbTenant).State = EntityState.Added; } existingDbTenants.Remove(tenant.id); } // Remove exceed categories var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbTenant in existingDbTenants) { context.Entry(dbTenant.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
private async Task SyncContentPages() { using (ProvisioningAppDBContext context = GetContext()) { // Find the content pages files var files = await _cloneProvider.GetAsync(CONTENT_PATH, WriteLog); if (files == null || files.Count() == 0) { throw new InvalidOperationException($"Cannot find files in folder {CONTENT_PATH}"); } // Consider system pages only var existingDbContentPages = context.ContentPages .ToList() .Where(cp => cp.Id.StartsWith("system", StringComparison.InvariantCultureIgnoreCase)) .ToDictionary(cp => cp.Id, StringComparer.OrdinalIgnoreCase); foreach (ITemplateFile file in files) { // Get the file content String fileContent = await GetHtmlContentAsync(CONTENT_PATH, file.Path.Substring(file.Path.LastIndexOf('/') + 1)); // Update Content Page, if already exists if (existingDbContentPages.TryGetValue(file.Path, out ContentPage dbContentPage)) { dbContentPage.Content = fileContent; context.Entry(dbContentPage).State = EntityState.Modified; } else { // Add new Content Page dbContentPage = new ContentPage { Id = file.Path, Content = fileContent, }; context.Entry(dbContentPage).State = EntityState.Added; } existingDbContentPages.Remove(file.Path); } // Remove leftover pages var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbContentPage in existingDbContentPages) { context.Entry(dbContentPage.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
//private static async Task CleanupKeyVault() //{ // // Get the reference date for removal of keys (expired at least 2 hours ago) // var referenceDateTime = DateTime.Now.AddHours(-2); // // This job cleans up the expired keys from the Azure Key Vault // var vault = new KeyVaultService(); // // Get all the keys stored in Key Vault // var allKeys = await vault.ListKeysAsync(); // // Check for expired keys // foreach (var key in allKeys) // { // var currentKey = await vault.GetFullKeyAsync(key); // if (currentKey.Attributes.Expires <= referenceDateTime) // { // // The key is expired, let's remove it // await vault.RemoveKeyAsync(key); // // Log the action // Console.WriteLine($"Deleted key {key} that expired on {currentKey.Attributes.Expires}"); // } // else // { // Console.WriteLine($"Key {key} is not yet expired"); // } // // Delay to avoid throttling // System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1)); // } //} //private static async Task CleanupSqlVault() //{ // Console.WriteLine("Cleaning up SQL Vault"); // // This job cleans up the expired keys from the Sql Azure Database // var sqlVault = new SqlServerVaultService(); // await sqlVault.CleanupTokensAsync(); // Console.WriteLine("Cleaned SQL Vault"); //} private static async Task CleanupSqlServer() { // Get the expired actions var dbContext = new ProvisioningAppDBContext(); var now = DateTime.Now; var expiredItems = dbContext.ProvisioningActionItems.Where(i => i.ExpiresOn <= now); // And delete any expired item foreach (var i in expiredItems) { Console.WriteLine($"Deleting action item {i.Id} because it is expired"); // Delete it dbContext.ProvisioningActionItems.Remove(i); } await dbContext.SaveChangesAsync(); }
private async Task SyncTemplatesAsync(string path, PackageType type) { using (ProvisioningAppDBContext context = GetContext()) { var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; // Find packages inside folder IEnumerable <ITemplateItem> items = await _cloneProvider.GetAsync(path, WriteLog); var packages = await FindPackagesAsync(items, context); var existingDbPackages = context.Packages .Include(c => c.Categories) .Include(c => c.TargetPlatforms) // .Where(p => p.PackageType == type) .ToDictionary(c => c.Id); foreach (DomainModel.Package package in packages) { package.PackageType = type; // Update package, if already exists if (existingDbPackages.TryGetValue(package.Id, out DomainModel.Package dbPackage)) { // Copy info into existing item dbPackage.DisplayName = package.DisplayName; dbPackage.Author = package.Author; dbPackage.AuthorLink = package.AuthorLink; dbPackage.Description = package.Description; dbPackage.ImagePreviewUrl = package.ImagePreviewUrl; dbPackage.PackageUrl = package.PackageUrl; dbPackage.Version = package.Version; // New properties for Wave2 dbPackage.Promoted = package.Promoted; dbPackage.Preview = package.Preview; dbPackage.PropertiesMetadata = package.PropertiesMetadata; // Keep times applied from the DB // dbPackage.TimesApplied = package.TimesApplied; // New properties for Wave 4 dbPackage.Instructions = package.Instructions; dbPackage.ProvisionRecap = package.ProvisionRecap; // New properties for Wave 5 dbPackage.SortOrder = package.SortOrder; dbPackage.SortOrderPromoted = package.SortOrderPromoted; dbPackage.RepositoryRelativeUrl = package.RepositoryRelativeUrl; dbPackage.Abstract = package.Abstract; // New properties for Wave 6 dbPackage.ForceNewSite = package.ForceNewSite; dbPackage.MatchingSiteBaseTemplateId = package.MatchingSiteBaseTemplateId; // New properties for Wave 7 dbPackage.Visible = package.Visible; // New properties for Wave 8 dbPackage.PackageProperties = package.PackageProperties; // Wave 12 - Allowed to move from one type to another dbPackage.PackageType = package.PackageType; dbPackage.ForceExistingSite = package.ForceExistingSite; context.Entry(dbPackage).State = EntityState.Modified; // Add new categories foreach (var c in package.Categories.Except(dbPackage.Categories).ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage, c, d => d.Categories, EntityState.Added); } // Remove old categories foreach (var c in dbPackage.Categories.Except(package.Categories).ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage, c, d => d.Categories, EntityState.Deleted); } // Add new platforms foreach (var c in package.TargetPlatforms.Except(dbPackage.TargetPlatforms).ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage, c, d => d.TargetPlatforms, EntityState.Added); } // Remove old platforms foreach (var c in dbPackage.TargetPlatforms.Except(package.TargetPlatforms).ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage, c, d => d.TargetPlatforms, EntityState.Deleted); } existingDbPackages.Remove(dbPackage.Id); } else { // Add new package context.Entry(package).State = EntityState.Added; } } // Remove leftover packages from current category foreach (var dbPackage in existingDbPackages.Where(p => p.Value.PackageType == type)) { await context.Entry(dbPackage.Value).Collection(d => d.Categories).LoadAsync(); foreach (var dbCategory in dbPackage.Value.Categories.ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage.Value, dbCategory, d => d.Categories, EntityState.Deleted); } context.Entry(dbPackage.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
private async Task SyncPageTemplates() { using (ProvisioningAppDBContext context = GetContext()) { // Find the category file var pageTemplatesFolders = await _cloneProvider.GetAsync(PAGE_TEMPLATES_PATH, WriteLog); if (pageTemplatesFolders == null || pageTemplatesFolders.Count() == 0) { throw new InvalidOperationException($"Cannot find Page Template folders in folder {PAGE_TEMPLATES_PATH}"); } var existingDbPageTemplates = context.PageTemplates.ToDictionary(cp => cp.Id, StringComparer.OrdinalIgnoreCase); foreach (ITemplateFolder pageTemplateFolder in pageTemplatesFolders) { // Prepare content variables String htmlContent = null; String cssContent = null; // Get the page template folder content files var pageTemplateFiles = await _cloneProvider.GetAsync(pageTemplateFolder.Path, WriteLog); if (pageTemplateFiles == null || pageTemplateFiles.Count() == 0) { throw new InvalidOperationException($"Cannot find template files in Page Template folder {pageTemplateFolder.Path}"); } foreach (ITemplateFile pageTemplateFile in pageTemplateFiles) { // If the content file is an HTML file if (pageTemplateFile.Path.EndsWith(".html", StringComparison.InvariantCultureIgnoreCase)) { // Set the HTML content htmlContent = await GetFileContentAsync(pageTemplateFolder.Path, pageTemplateFile.Path.Substring(pageTemplateFile.Path.LastIndexOf('/') + 1)); } else if (pageTemplateFile.Path.EndsWith(".css", StringComparison.InvariantCultureIgnoreCase)) { // Set the CSS content cssContent = await GetFileContentAsync(pageTemplateFolder.Path, pageTemplateFile.Path.Substring(pageTemplateFile.Path.LastIndexOf('/') + 1)); } if (!String.IsNullOrEmpty(htmlContent) && !String.IsNullOrEmpty(cssContent)) { // If we have both HTML and CSS content, just break the foreach loop break; } } // Update Page Template, if already exists if (existingDbPageTemplates.TryGetValue(pageTemplateFolder.Path, out PageTemplate dbPageTemplate)) { dbPageTemplate.Html = htmlContent; dbPageTemplate.Css = cssContent; context.Entry(dbPageTemplate).State = EntityState.Modified; } else { // Add new Content Page dbPageTemplate = new PageTemplate { Id = pageTemplateFolder.Path, Html = htmlContent, Css = cssContent, }; context.Entry(dbPageTemplate).State = EntityState.Added; } existingDbPageTemplates.Remove(pageTemplateFolder.Path); } // Remove exceed categories var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbPageTemplate in existingDbPageTemplates) { context.Entry(dbPageTemplate.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }