/// <summary> /// Gets the PersistedDatasetCache using the specified <see cref="PersistedDataset.AccessKey" /> /// </summary> /// <param name="accessKey">The access key.</param> /// <returns></returns> public static PersistedDatasetCache GetFromAccessKey(string accessKey) { int persistedDatasetId; if (AccessKeyIdLookup.TryGetValue(accessKey, out persistedDatasetId)) { return(Get(persistedDatasetId)); } PersistedDatasetCache persistedDatasetCache = null; using (var rockContext = new RockContext()) { var persistedDataset = new PersistedDatasetService(rockContext).GetFromAccessKeyNoTracking(accessKey); if (persistedDataset != null) { persistedDatasetCache = Get(persistedDataset.Id); } } if (persistedDatasetCache != null) { AccessKeyIdLookup.AddOrUpdate(persistedDatasetCache.AccessKey, persistedDatasetCache.Id, (k, v) => persistedDatasetCache.Id); } return(persistedDatasetCache); }
/// <summary> /// Handles the Click event of the lbRefresh control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param> protected void lbRefresh_Click(object sender, RowEventArgs e) { var rockContext = new RockContext(); PersistedDatasetService persistedDatasetService = new PersistedDatasetService(rockContext); PersistedDataset persistedDataset = persistedDatasetService.Get(e.RowKeyId); persistedDataset.UpdateResultData(); rockContext.SaveChanges(); BindGrid(); }
/// <summary> /// Shows the detail. /// </summary> /// <param name="persistedDatasetId">The persisted dataset identifier.</param> public void ShowDetail(int persistedDatasetId) { if (persistedDatasetId > 0) { lActionTitle.Text = ActionTitle.Edit(PersistedDataset.FriendlyTypeName).FormatAsHtmlTitle(); } else { lActionTitle.Text = ActionTitle.Add(PersistedDataset.FriendlyTypeName).FormatAsHtmlTitle(); } var rockContext = new RockContext(); var persistedDatasetService = new PersistedDatasetService(rockContext); PersistedDataset persistedDataset; if (persistedDatasetId > 0) { persistedDataset = persistedDatasetService.Get(persistedDatasetId); } else { persistedDataset = new PersistedDataset(); } hfPersistedDatasetId.Value = persistedDatasetId.ToString(); nbEditModeMessage.Text = string.Empty; if (persistedDataset.IsSystem) { ceBuildScript.ReadOnly = true; ceBuildScript.Enabled = false; tbAccessKey.Enabled = false; nbEditModeMessage.Text = EditModeMessage.System(Category.FriendlyTypeName); } tbName.Text = persistedDataset.Name; cbIsActive.Checked = persistedDataset.IsActive; tbAccessKey.Text = persistedDataset.AccessKey; tbDescription.Text = persistedDataset.Description; ceBuildScript.Text = persistedDataset.BuildScript; lcpEnabledLavacommands.SelectedLavaCommands = persistedDataset.EnabledLavaCommands.SplitDelimitedValues().ToList(); nbRefreshIntervalHours.Text = persistedDataset.RefreshIntervalMinutes.HasValue ? TimeSpan.FromMinutes(persistedDataset.RefreshIntervalMinutes.Value).TotalHours.ToString("F") : string.Empty; nbMemoryCacheDurationHours.Text = persistedDataset.MemoryCacheDurationMS.HasValue ? TimeSpan.FromMilliseconds(persistedDataset.MemoryCacheDurationMS.Value).TotalHours.ToString("F") : string.Empty; dtpExpireDateTime.SelectedDate = persistedDataset.ExpireDateTime; etpEntityType.SelectedEntityTypeId = persistedDataset.EntityTypeId; cbAllowManualRefresh.Checked = persistedDataset.AllowManualRefresh; }
/// <summary> /// Handles the Click event of the lbPreview control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param> protected void lbPreview_Click(object sender, RowEventArgs e) { var rockContext = new RockContext(); PersistedDatasetService persistedDatasetService = new PersistedDatasetService(rockContext); PersistedDataset persistedDataset = persistedDatasetService.GetNoTracking(e.RowKeyId); if (persistedDataset.LastRefreshDateTime == null) { persistedDataset.UpdateResultData(); } // limit preview size (default is 1MB) var maxPreviewSizeMB = this.GetAttributeValue(AttributeKey.MaxPreviewSizeMB).AsDecimalOrNull() ?? 1; // make sure they didn't put in a negative number maxPreviewSizeMB = Math.Max(1, maxPreviewSizeMB); var maxPreviewSizeLength = ( int )(maxPreviewSizeMB * 1024 * 1024); lPreviewJson.Text = (string.Format("<pre>{0}</pre>", persistedDataset.ResultData)).Truncate(maxPreviewSizeLength); nbPreviewMessage.Visible = false; nbPreviewMaxLengthWarning.Visible = false; try { var preViewObject = persistedDataset.ResultData.FromJsonDynamic(); if (persistedDataset.ResultData.Length > maxPreviewSizeLength) { nbPreviewMaxLengthWarning.Text = string.Format("JSON size is {0}. Showing first {1}.", persistedDataset.ResultData.Length.FormatAsMemorySize(), maxPreviewSizeLength.FormatAsMemorySize()); nbPreviewMaxLengthWarning.Visible = true; } nbPreviewMessage.Text = string.Format("Time to build Dataset: {0:F0}ms", persistedDataset.TimeToBuildMS); nbPreviewMessage.Details = null; nbPreviewMessage.NotificationBoxType = NotificationBoxType.Success; nbPreviewMessage.Visible = true; } catch (Exception ex) { nbPreviewMessage.Text = "Error building Dataset object from the JSON generated from the Build Script"; nbPreviewMessage.Details = ex.Message; nbPreviewMessage.NotificationBoxType = NotificationBoxType.Danger; nbPreviewMessage.Visible = true; } mdPreview.Show(); }
/// <summary> /// Handles the DeleteClick event of the gList control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs"/> instance containing the event data.</param> protected void gList_DeleteClick(object sender, Rock.Web.UI.Controls.RowEventArgs e) { var rockContext = new RockContext(); PersistedDatasetService persistedDatasetService = new PersistedDatasetService(rockContext); PersistedDataset persistedDataset = persistedDatasetService.Get(e.RowKeyId); if (persistedDataset != null) { string errorMessage; if (!persistedDatasetService.CanDelete(persistedDataset, out errorMessage)) { mdGridWarning.Show(errorMessage, ModalAlertType.Information); return; } persistedDatasetService.Delete(persistedDataset); rockContext.SaveChanges(); } BindGrid(); }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { RockContext rockContext = new RockContext(); PersistedDatasetService persistedDatasetService = new PersistedDatasetService(rockContext); // Use AsNoTracking() since these records won't be modified, and therefore don't need to be tracked by the EF change tracker var qry = persistedDatasetService.Queryable().AsNoTracking(); var sortProperty = gList.SortProperty; if (gList.AllowSorting && sortProperty != null) { qry = qry.Sort(sortProperty); } else { qry = qry.OrderBy(a => a.Name).ThenBy(a => a.AccessKey); } gList.SetLinqDataSource(qry); gList.DataBind(); }
public static void Initialize(TestContext context) { var rockContext = new RockContext(); // Add Followings for Ted Decker. var followingService = new FollowingService(rockContext); var tedDeckerGuid = TestGuids.TestPeople.TedDecker.AsGuid(); var benJonesGuid = TestGuids.TestPeople.BenJones.AsGuid(); var billMarbleGuid = TestGuids.TestPeople.BillMarble.AsGuid(); var personService = new PersonService(rockContext); var tedDeckerAliasId = personService.Get(tedDeckerGuid).PrimaryAliasId.GetValueOrDefault(); var personEntityTypeId = EntityTypeCache.GetId(SystemGuid.EntityType.PERSON).GetValueOrDefault(); followingService.GetOrAddFollowing(personEntityTypeId, personService.Get(benJonesGuid).Id, tedDeckerAliasId, null); followingService.GetOrAddFollowing(personEntityTypeId, personService.Get(billMarbleGuid).Id, tedDeckerAliasId, null); rockContext.SaveChanges(); // Add a Persisted Dataset containing some test people. var datasetLava = @" [ {%- person where:'Guid == `<benJonesGuid>` || Guid == `<billMarbleGuid>` || Guid == `<alishaMarbleGuid>`' iterator:'People' -%} {%- for item in People -%} { `Id`: {{ item.Id | ToJSON }}, `FirstName`: {{ item.NickName | ToJSON }}, `LastName`: {{ item.LastName | ToJSON }}, `FullName`: {{ item.FullName | ToJSON }}, } {%- unless forloop.last -%},{%- endunless -%} {%- endfor -%} {%- endperson -%} ] "; datasetLava = datasetLava.Replace("<benJonesGuid>", TestGuids.TestPeople.BenJones) .Replace("<billMarbleGuid>", TestGuids.TestPeople.BillMarble) .Replace("<alishaMarbleGuid>", TestGuids.TestPeople.AlishaMarble); // Create a Persisted Dataset. const string PersistedDataSetPeopleGuid = "99FF9EFA-D9E3-48DE-AD08-C67389FF688F"; datasetLava = datasetLava.Replace("`", @""""); var ps = new PersistedDatasetService(rockContext); var pds = ps.Get(PersistedDataSetPeopleGuid.AsGuid()); if (pds == null) { pds = new PersistedDataset(); pds.Guid = PersistedDataSetPeopleGuid.AsGuid(); ps.Add(pds); } pds.Name = "Persons"; pds.AccessKey = "persons"; pds.Description = "A persisted dataset created for testing purposes."; pds.BuildScriptType = PersistedDatasetScriptType.Lava; pds.BuildScript = datasetLava; pds.EnabledLavaCommands = "RockEntity"; pds.EntityTypeId = EntityTypeCache.Get(typeof(Person), createIfNotFound: false, rockContext).Id; pds.UpdateResultData(); rockContext.SaveChanges(); }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void btnSave_Click(object sender, EventArgs e) { if (!Page.IsValid) { return; } var rockContext = new RockContext(); PersistedDatasetService persistedDatasetService = new PersistedDatasetService(rockContext); PersistedDataset persistedDataset; int persistedDatasetId = hfPersistedDatasetId.Value.AsInteger(); if (persistedDatasetId == 0) { persistedDataset = new PersistedDataset(); persistedDatasetService.Add(persistedDataset); } else { persistedDataset = persistedDatasetService.Get(persistedDatasetId); } var accessKey = tbAccessKey.Text; if (accessKey.IsNullOrWhiteSpace()) { nbAccessKeyWarning.Visible = true; nbAccessKeyWarning.Text = "Access Key cannot be blank"; return; } var accessKeyAlreadyExistsForDataSet = persistedDatasetService.Queryable().Where(a => a.AccessKey == accessKey && a.Id != persistedDataset.Id).AsNoTracking().FirstOrDefault(); if (accessKeyAlreadyExistsForDataSet != null) { nbAccessKeyWarning.Visible = true; nbAccessKeyWarning.Text = string.Format("Access Key must be unique. {0} is using '{1}' as the access key", accessKeyAlreadyExistsForDataSet.Name, accessKey); return; } persistedDataset.Name = tbName.Text; persistedDataset.IsActive = cbIsActive.Checked; persistedDataset.AccessKey = tbAccessKey.Text; persistedDataset.Description = tbDescription.Text; persistedDataset.BuildScript = ceBuildScript.Text; persistedDataset.EnabledLavaCommands = lcpEnabledLavacommands.SelectedLavaCommands.AsDelimited(","); var refreshIntervalHours = nbRefreshIntervalHours.Text.AsDoubleOrNull(); if (refreshIntervalHours.HasValue) { persistedDataset.RefreshIntervalMinutes = ( int )TimeSpan.FromHours(refreshIntervalHours.Value).TotalMinutes; } else { persistedDataset.RefreshIntervalMinutes = null; } var memoryCacheDurationHours = nbMemoryCacheDurationHours.Text.AsDoubleOrNull(); if (memoryCacheDurationHours.HasValue) { persistedDataset.MemoryCacheDurationMS = ( int )TimeSpan.FromHours(memoryCacheDurationHours.Value).TotalMilliseconds; } else { persistedDataset.MemoryCacheDurationMS = null; } persistedDataset.ExpireDateTime = dtpExpireDateTime.SelectedDate; persistedDataset.EntityTypeId = etpEntityType.SelectedEntityTypeId; persistedDataset.AllowManualRefresh = cbAllowManualRefresh.Checked; // just in case anything has changed, null out the LastRefreshDateTime and TimeToBuild to mark this as needing to be refreshed the next time the Persisted Dataset job runs persistedDataset.LastRefreshDateTime = null; persistedDataset.TimeToBuildMS = null; rockContext.SaveChanges(); NavigateToParentPage(); }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; StringBuilder results = new StringBuilder(); int updatedDatasetCount = 0; int updatedDatasetTotalCount; var errors = new List <string>(); List <Exception> exceptions = new List <Exception>(); using (var rockContext = new RockContext()) { var currentDateTime = RockDateTime.Now; var persistedDatasetQuery = new PersistedDatasetService(rockContext).Queryable(); updatedDatasetTotalCount = persistedDatasetQuery.Count(); // exclude datasets that are no longer active persistedDatasetQuery = persistedDatasetQuery.Where(a => a.IsActive && (a.ExpireDateTime == null || a.ExpireDateTime > currentDateTime)); // exclude datasets that are already up-to-date based on the Refresh Interval and LastRefreshTime persistedDatasetQuery = persistedDatasetQuery .Where(a => a.LastRefreshDateTime == null || (System.Data.Entity.SqlServer.SqlFunctions.DateAdd("mi", a.RefreshIntervalMinutes.Value, a.LastRefreshDateTime.Value) < currentDateTime)); var expiredPersistedDatasetsList = persistedDatasetQuery.ToList(); foreach (var persistedDataset in expiredPersistedDatasetsList) { var name = persistedDataset.Name; try { context.UpdateLastStatusMessage($"Updating {persistedDataset.Name}"); persistedDataset.UpdateResultData(); rockContext.SaveChanges(); updatedDatasetCount++; } catch (Exception ex) { // Capture and log the exception because we're not going to fail this job // unless all the data views fail. var errorMessage = $"An error occurred while trying to update persisted dataset '{name}' so it was skipped. Error: {ex.Message}"; errors.Add(errorMessage); var ex2 = new Exception(errorMessage, ex); exceptions.Add(ex2); ExceptionLogService.LogException(ex2, null); continue; } } } int notUpdatedCount = updatedDatasetTotalCount - updatedDatasetCount; // Format the result message results.AppendLine($"Updated {updatedDatasetCount} {"persisted dataset".PluralizeIf( updatedDatasetCount != 1 )}."); if (notUpdatedCount > 0) { results.AppendLine($"Skipped {notUpdatedCount} {"persisted dataset".PluralizeIf( updatedDatasetCount != 1 )} that are already up-to-date or inactive."); } context.Result = results.ToString(); if (errors.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append("Errors: "); errors.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errorMessage = sb.ToString(); context.Result += errorMessage; // We're not going to throw an aggregate exception unless there were no successes. // Otherwise the status message does not show any of the success messages in // the last status message. if (updatedDatasetCount == 0) { throw new AggregateException(exceptions.ToArray()); } } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; StringBuilder results = new StringBuilder(); int updatedDatasetCount = 0; int updatedDatasetTotalCount; var errors = new List <string>(); List <Exception> exceptions = new List <Exception>(); using (var rockContext = new RockContext()) { var currentDateTime = RockDateTime.Now; var persistedDatasetQuery = new PersistedDatasetService(rockContext).Queryable(); updatedDatasetTotalCount = persistedDatasetQuery.Count(); // exclude datasets that are no longer active persistedDatasetQuery = persistedDatasetQuery.Where(a => a.IsActive && (a.ExpireDateTime == null || a.ExpireDateTime > currentDateTime)); // exclude datasets that are already up-to-date based on the Refresh Interval and LastRefreshTime persistedDatasetQuery = persistedDatasetQuery .Where(a => a.LastRefreshDateTime == null || (System.Data.Entity.SqlServer.SqlFunctions.DateAdd("mi", a.RefreshIntervalMinutes.Value, a.LastRefreshDateTime.Value) < currentDateTime)); var expiredPersistedDatasetsList = persistedDatasetQuery.ToList(); foreach (var persistedDataset in expiredPersistedDatasetsList) { var name = persistedDataset.Name; try { context.UpdateLastStatusMessage($"Updating {persistedDataset.Name}"); persistedDataset.UpdateResultData(); rockContext.SaveChanges(); updatedDatasetCount++; } catch (Exception ex) { // Capture and log the exception because we're not going to fail this job // unless all the data views fail. var errorMessage = $"An error occurred while trying to update persisted dataset '{name}' so it was skipped. Error: {ex.Message}"; errors.Add(string.Format(@"{0} failed", name)); var ex2 = new Exception(errorMessage, ex); exceptions.Add(ex2); ExceptionLogService.LogException(ex2, null); continue; } } } int notUpdatedCount = updatedDatasetTotalCount - updatedDatasetCount; // Format the result message results.AppendLine($"<i class='fa fa-circle text-success'></i> Updated {updatedDatasetCount} {"persisted dataset".PluralizeIf( updatedDatasetCount != 1 )}"); if (notUpdatedCount > 0) { results.AppendLine($"<i class='fa fa-circle text-success'></i> Skipped {notUpdatedCount} {"up-to-date/inactive dataset".PluralizeIf( updatedDatasetCount != 1 )}"); } foreach (var error in errors) { results.AppendLine($"<i class='fa fa-circle text-danger'></i> {error}"); } context.Result = results.ToString(); if (exceptions.Any()) { var exceptionList = new AggregateException("One or more exceptions occurred in UpdatePersistedDatasets.", exceptions); throw new RockJobWarningException("UpdatePersistedDatasets completed with warnings", exceptionList); } }