/// <summary> /// Initializes a new instance of the <see cref="WorkItem"/> class. /// </summary> /// <param name="client"><see cref="T:TcmCoreService.Client" /></param> /// <param name="workItemData"><see cref="T:Tridion.ContentManager.CoreService.Client.WorkItemData" /></param> protected WorkItem(Client client, WorkItemData workItemData) : base(client, workItemData) { if (workItemData == null) throw new ArgumentNullException("workItemData"); mWorkItemData = workItemData; }
/// <summary> /// Reload the <see cref="WorkItem" /> with the specified <see cref="T:Tridion.ContentManager.CoreService.Client.WorkItemData" /> /// </summary> /// <param name="workItemData"><see cref="T:Tridion.ContentManager.CoreService.Client.WorkItemData" /></param> protected void Reload(WorkItemData workItemData) { if (workItemData == null) throw new ArgumentNullException("workItemData"); mWorkItemData = workItemData; base.Reload(workItemData); }
private void ProcessWorkItemLinks(IWorkItemMigrationClient sourceStore, IWorkItemMigrationClient targetStore, WorkItemData sourceWorkItem, WorkItemData targetWorkItem) { if (targetWorkItem != null && _config.LinkMigration && sourceWorkItem.ToWorkItem().Links.Count > 0) { TraceWriteLine(LogEventLevel.Information, "Links {SourceWorkItemLinkCount} | LinkMigrator:{LinkMigration}", new Dictionary <string, object>() { { "SourceWorkItemLinkCount", sourceWorkItem.ToWorkItem().Links.Count }, { "LinkMigration", _config.LinkMigration } }); workItemLinkEnricher.Enrich(sourceWorkItem, targetWorkItem); AddMetric("RelatedLinkCount", processWorkItemMetrics, targetWorkItem.ToWorkItem().Links.Count); int fixedLinkCount = gitRepositoryEnricher.Enrich(sourceWorkItem, targetWorkItem); AddMetric("FixedGitLinkCount", processWorkItemMetrics, fixedLinkCount); } }
public override ReflectedWorkItemId CreateReflectedWorkItemId(WorkItemData workItem) { return(new TfsReflectedWorkItemId(workItem)); }
public override WorkItemData FindReflectedWorkItemByReflectedWorkItemId(WorkItemData workItemToReflect) { return(FindReflectedWorkItemByReflectedWorkItemId(CreateReflectedWorkItemId(workItemToReflect))); }
public virtual int Enrich(WorkItemData sourceWorkItem, WorkItemData targetWorkItem) { throw new InvalidOperationException("This is invalid for this Enricher type"); }
protected override void FixEmbededImages(WorkItemData wi, string oldTfsurl, string newTfsurl, string sourcePersonalAccessToken = "") { throw new NotImplementedException(); }
public void Store(WorkItemData workItem) { dataStore.Store(workItem.Key, workItem.Data); }
public abstract ReflectedWorkItemId CreateReflectedWorkItemId(WorkItemData workItem);
public WorkItemData FindReflectedWorkItem(WorkItemData workItem, bool cache) { throw new System.NotImplementedException(); }
public string CreateReflectedWorkItemId(WorkItemData wi) { throw new System.NotImplementedException(); }
ReflectedWorkItemId IWorkItemMigrationClient.GetReflectedWorkItemId(WorkItemData workItem) { throw new System.NotImplementedException(); }
public WorkItemData GetRevision(WorkItemData workItem, int revision) { throw new System.NotImplementedException(); }
public int GetReflectedWorkItemId(WorkItemData workItem) { throw new System.NotImplementedException(); }
public WorkItemData FindReflectedWorkItemByReflectedWorkItemId(WorkItemData refWi) { throw new System.NotImplementedException(); }
public void TestTestWorkItemService() { ResetCallbackFields(); var service = new TestWorkItemService{Callback = this}; var callback = (IWorkItemActivityCallback) service; var item = new WorkItemData { Type = DicomRetrieveRequest.WorkItemTypeString }; var items = new List<WorkItemData> {item}; var eventType = WorkItemsChangedEventType.Update; callback.WorkItemsChanged(eventType, items); Assert.AreEqual(0, WorkItemChangedCallbackCount); service.Subscribe(new WorkItemSubscribeRequest()); callback.WorkItemsChanged(eventType, items); Assert.AreEqual(1, WorkItemChangedCallbackCount); service.Unsubscribe(new WorkItemUnsubscribeRequest()); callback.WorkItemsChanged(eventType, items); Assert.AreEqual(1, WorkItemChangedCallbackCount); }
public int PersistFromWorkItem(WorkItemData workItem) { throw new NotImplementedException(); }
public abstract WorkItemData FindReflectedWorkItem(WorkItemData reflectedWorkItem, bool cache);
public override int Enrich(WorkItemData sourceWorkItem, WorkItemData targetWorkItem) { throw new NotImplementedException(); }
public abstract WorkItemData FindReflectedWorkItemByReflectedWorkItemId(WorkItemData reflectedWorkItem);
public abstract void PersistWorkItem(WorkItemData sourceWorkItem);
public abstract ReflectedWorkItemId GetReflectedWorkItemId(WorkItemData workItem);
public virtual void ProcessorExecutionBeforeProcessWorkItem(IProcessor processor, WorkItemData workitem) { Log.LogDebug("{WorkItemProcessorEnricher}::ProcessorExecutionBeforeProcessWorkItem::NoAction", this.GetType().Name); }
public abstract WorkItemData GetRevision(WorkItemData workItem, int revision);
public override WorkItemData PersistWorkItem(WorkItemData workItem) { throw new NotImplementedException(); }
public abstract WorkItemData PersistWorkItem(WorkItemData workItem);
private async Task ProcessWorkItemAsync(WorkItemData sourceWorkItem, int retryLimit = 5, int retries = 0) { var witStopWatch = Stopwatch.StartNew(); var startTime = DateTime.Now; processWorkItemMetrics = new Dictionary <string, double>(); processWorkItemParamiters = new Dictionary <string, string>(); AddParameter("SourceURL", processWorkItemParamiters, Engine.Source.WorkItems.Config.AsTeamProjectConfig().Collection.ToString()); AddParameter("SourceWorkItem", processWorkItemParamiters, sourceWorkItem.Id); AddParameter("TargetURL", processWorkItemParamiters, Engine.Target.WorkItems.Config.AsTeamProjectConfig().Collection.ToString()); AddParameter("TargetProject", processWorkItemParamiters, Engine.Target.WorkItems.Project.Name); AddParameter("RetryLimit", processWorkItemParamiters, retryLimit.ToString()); AddParameter("RetryNumber", processWorkItemParamiters, retries.ToString()); Log.LogDebug("######################################################################################"); Log.LogDebug("ProcessWorkItem: {sourceWorkItemId}", sourceWorkItem.Id); Log.LogDebug("######################################################################################"); try { if (sourceWorkItem.Type != "Test Plan" && sourceWorkItem.Type != "Test Suite") { var targetWorkItem = Engine.Target.WorkItems.FindReflectedWorkItem(sourceWorkItem, false); /////////////////////////////////////////////// TraceWriteLine(LogEventLevel.Information, "Work Item has {sourceWorkItemRev} revisions and revision migration is set to {ReplayRevisions}", new Dictionary <string, object>() { { "sourceWorkItemRev", sourceWorkItem.Rev }, { "ReplayRevisions", _config.ReplayRevisions } } ); List <RevisionItem> revisionsToMigrate = revisionManager.GetRevisionsToMigrate(sourceWorkItem, targetWorkItem); if (targetWorkItem == null) { targetWorkItem = ReplayRevisions(revisionsToMigrate, sourceWorkItem, null); AddMetric("Revisions", processWorkItemMetrics, revisionsToMigrate.Count); } else { if (revisionsToMigrate.Count == 0) { ProcessWorkItemAttachments(sourceWorkItem, targetWorkItem, false); ProcessWorkItemLinks(Engine.Source.WorkItems, Engine.Target.WorkItems, sourceWorkItem, targetWorkItem); TraceWriteLine(LogEventLevel.Information, "Skipping as work item exists and no revisions to sync detected"); processWorkItemMetrics.Add("Revisions", 0); } else { TraceWriteLine(LogEventLevel.Information, "Syncing as there are {revisionsToMigrateCount} revisions detected", new Dictionary <string, object>() { { "revisionsToMigrateCount", revisionsToMigrate.Count } }); targetWorkItem = ReplayRevisions(revisionsToMigrate, sourceWorkItem, targetWorkItem); AddMetric("Revisions", processWorkItemMetrics, revisionsToMigrate.Count); AddMetric("SyncRev", processWorkItemMetrics, revisionsToMigrate.Count); } } AddParameter("TargetWorkItem", processWorkItemParamiters, targetWorkItem.ToWorkItem().Revisions.Count.ToString()); /////////////////////////////////////////////// ProcessHTMLFieldAttachements(targetWorkItem); /////////////////////////////////////////////// /////////////////////////////////////////////////////// if (targetWorkItem != null && targetWorkItem.ToWorkItem().IsDirty) { targetWorkItem.SaveToAzureDevOps(); } if (targetWorkItem != null) { targetWorkItem.ToWorkItem().Close(); } if (sourceWorkItem != null) { sourceWorkItem.ToWorkItem().Close(); } } else { TraceWriteLine(LogEventLevel.Warning, "SKIP: Unable to migrate {sourceWorkItemTypeName}/{sourceWorkItemId}. Use the TestPlansAndSuitesMigrationContext after you have migrated all Test Cases. ", new Dictionary <string, object>() { { "sourceWorkItemTypeName", sourceWorkItem.Type }, { "sourceWorkItemId", sourceWorkItem.Id } }); } } catch (WebException ex) { Log.LogError(ex, "Some kind of internet pipe blockage"); if (retries < retryLimit) { TraceWriteLine(LogEventLevel.Warning, "WebException: Will retry in {retrys}s ", new Dictionary <string, object>() { { "retrys", retries } }); System.Threading.Thread.Sleep(new TimeSpan(0, 0, retries)); retries++; TraceWriteLine(LogEventLevel.Warning, "RETRY {Retrys}/{RetryLimit} ", new Dictionary <string, object>() { { "Retrys", retries }, { "RetryLimit", retryLimit } }); await ProcessWorkItemAsync(sourceWorkItem, retryLimit, retries); } else { TraceWriteLine(LogEventLevel.Error, "ERROR: Failed to create work item. Retry Limit reached "); } } catch (Exception ex) { Log.LogError(ex, ex.ToString()); Telemetry.TrackRequest("ProcessWorkItem", startTime, witStopWatch.Elapsed, "502", false); throw ex; } witStopWatch.Stop(); _elapsedms += witStopWatch.ElapsedMilliseconds; processWorkItemMetrics.Add("ElapsedTimeMS", _elapsedms); var average = new TimeSpan(0, 0, 0, 0, (int)(_elapsedms / _current)); var remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * _count)); TraceWriteLine(LogEventLevel.Information, "Average time of {average:%s}.{average:%fff} per work item and {remaining:%h} hours {remaining:%m} minutes {remaining:%s}.{remaining:%fff} seconds estimated to completion", new Dictionary <string, object>() { { "average", average }, { "remaining", remaining } }); Telemetry.TrackEvent("WorkItemMigrated", processWorkItemParamiters, processWorkItemMetrics); Telemetry.TrackRequest("ProcessWorkItem", startTime, witStopWatch.Elapsed, "200", true); _current++; _count--; }
public static void SaveMigratedWorkItem(this IEmbededImagesRepairEnricher context, WorkItemData workItem) { if (workItem == null) { throw new ArgumentNullException(nameof(workItem)); } workItem.ToWorkItem().Fields["System.ChangedBy"].Value = "Migration"; workItem.ToWorkItem().Save(); }
private WorkItemData ReplayRevisions(List <RevisionItem> revisionsToMigrate, WorkItemData sourceWorkItem, WorkItemData targetWorkItem) { try { var skipToFinalRevisedWorkItemType = _config.SkipToFinalRevisedWorkItemType; var finalDestType = revisionsToMigrate.Last().Type; if (skipToFinalRevisedWorkItemType && Engine.TypeDefinitionMaps.Items.ContainsKey(finalDestType)) { finalDestType = Engine.TypeDefinitionMaps.Items[finalDestType].Map(); } //If work item hasn't been created yet, create a shell if (targetWorkItem == null) { var targetType = revisionsToMigrate.First().Type; if (Engine.TypeDefinitionMaps.Items.ContainsKey(targetType)) { targetType = Engine.TypeDefinitionMaps.Items[targetType].Map(); } targetWorkItem = CreateWorkItem_Shell(Engine.Target.WorkItems.Project, sourceWorkItem, skipToFinalRevisedWorkItemType ? finalDestType : targetType); } if (_config.AttachRevisionHistory) { revisionManager.AttachSourceRevisionHistoryJsonToTarget(sourceWorkItem, targetWorkItem); } foreach (var revision in revisionsToMigrate) { var currentRevisionWorkItem = sourceWorkItem.GetRevision(revision.Number); TraceWriteLine(LogEventLevel.Information, " Processing Revision [{RevisionNumber}]", new Dictionary <string, object>() { { "RevisionNumber", revision.Number } }); // Decide on WIT var destType = currentRevisionWorkItem.Type; if (Engine.TypeDefinitionMaps.Items.ContainsKey(destType)) { destType = Engine.TypeDefinitionMaps.Items[destType].Map(); } PopulateWorkItem(currentRevisionWorkItem, targetWorkItem, destType); // Todo: Ensure all field maps use WorkItemData.Fields to apply a correct mapping Engine.FieldMaps.ApplyFieldMappings(currentRevisionWorkItem, targetWorkItem); // Todo: Think about an "UpdateChangedBy" flag as this is expensive! (2s/WI instead of 1,5s when writing "Migration") var changedBy = targetWorkItem.ToWorkItem().Fields["System.ChangedBy"].Value.ToString(); targetWorkItem.ToWorkItem().Fields["System.ChangedBy"].Value = revision.Fields["System.ChangedBy"].Value; targetWorkItem.ToWorkItem().Fields["System.History"].Value = revision.Fields["System.History"].Value; var reflectedUri = (TfsReflectedWorkItemId)Engine.Source.WorkItems.CreateReflectedWorkItemId(sourceWorkItem); if (!targetWorkItem.ToWorkItem().Fields.Contains(Engine.Target.Config.AsTeamProjectConfig().ReflectedWorkItemIDFieldName)) { var ex = new InvalidOperationException("ReflectedWorkItemIDField Field Missing"); Log.LogError(ex, " The WorkItemType {WorkItemType} does not have a Field called {ReflectedWorkItemID}", targetWorkItem.Type, Engine.Target.Config.AsTeamProjectConfig().ReflectedWorkItemIDFieldName); throw ex; } targetWorkItem.ToWorkItem().Fields[Engine.Target.Config.AsTeamProjectConfig().ReflectedWorkItemIDFieldName].Value = reflectedUri.ToString(); targetWorkItem.SaveToAzureDevOps(); TraceWriteLine(LogEventLevel.Information, " Saved TargetWorkItem {TargetWorkItemId}. Replayed revision {RevisionNumber} of {RevisionsToMigrateCount}", new Dictionary <string, object>() { { "TargetWorkItemId", targetWorkItem.Id }, { "RevisionNumber", revision.Number }, { "RevisionsToMigrateCount", revisionsToMigrate.Count } }); // Change this back to the original value as this object is mutated, and this value is needed elsewhere. targetWorkItem.ToWorkItem().Fields["System.ChangedBy"].Value = changedBy; } if (targetWorkItem != null) { ProcessWorkItemAttachments(sourceWorkItem, targetWorkItem, false); if (!string.IsNullOrEmpty(targetWorkItem.Id)) { ProcessWorkItemLinks(Engine.Source.WorkItems, Engine.Target.WorkItems, sourceWorkItem, targetWorkItem); } if (_config.GenerateMigrationComment) { var reflectedUri = targetWorkItem.ToWorkItem().Fields[Engine.Target.Config.AsTeamProjectConfig().ReflectedWorkItemIDFieldName].Value; var history = new StringBuilder(); history.Append( $"This work item was migrated from a different project or organization. You can find the old version at <a href=\"{reflectedUri}\">{reflectedUri}</a>."); targetWorkItem.ToWorkItem().History = history.ToString(); } targetWorkItem.SaveToAzureDevOps(); attachmentEnricher.CleanUpAfterSave(); TraceWriteLine(LogEventLevel.Information, "...Saved as {TargetWorkItemId}", new Dictionary <string, object> { { "TargetWorkItemId", targetWorkItem.Id } }); } } catch (Exception ex) { TraceWriteLine(LogEventLevel.Information, "...FAILED to Save"); Log.LogInformation("==============================================================="); if (targetWorkItem != null) { foreach (Field f in targetWorkItem.ToWorkItem().Fields) { TraceWriteLine(LogEventLevel.Information, "{FieldReferenceName} ({FieldName}) | {FieldValue}", new Dictionary <string, object>() { { "FieldReferenceName", f.ReferenceName }, { "FieldName", f.Name }, { "FieldValue", f.Value } }); } } Log.LogInformation("==============================================================="); Log.LogError(ex.ToString(), ex); Log.LogInformation("==============================================================="); } return(targetWorkItem); }
private void UpdateWorkItemFrom(WorkItemData source, WorkItemData target) { _innerList.Remove(source); _innerList.Add(target); }
public WorkItemData CreateNewFrom(WorkItemData source) { _innerList.Add(source); return(source); }
public void Delete(WorkItemData workItem) { dataStore.Delete(workItem.Key); }
private void TestActivityMonitorSubscriptions(IWorkItemActivityMonitor monitor, IWorkItemActivityCallback callback) { ResetCallbackFields(); var item = new WorkItemData { Type = DicomRetrieveRequest.WorkItemTypeString }; var items = new List<WorkItemData> { item }; var eventType = WorkItemsChangedEventType.Update; SubscribeAndPause(monitor, WorkItemChanged1); WaitForEvents(() => callback.WorkItemsChanged(eventType, items), 1); Assert.AreEqual(1, WorkItemChanged1Count); Assert.AreEqual(0, WorkItemChanged2Count); Assert.AreEqual(0, WorkItemChanged3Count); SubscribeAndPause(monitor, WorkItemChanged2); WaitForEvents(() => callback.WorkItemsChanged(eventType, items), 2); Assert.AreEqual(2, WorkItemChanged1Count); Assert.AreEqual(1, WorkItemChanged2Count); Assert.AreEqual(0, WorkItemChanged3Count); item.Type = DicomSendRequest.WorkItemTypeString; callback.WorkItemsChanged(eventType, items); Thread.Sleep(100); Assert.AreEqual(3, WorkItemChanged1Count); Assert.AreEqual(2, WorkItemChanged2Count); Assert.AreEqual(0, WorkItemChanged3Count); UnsubscribeAndPause(monitor, WorkItemChanged1); callback.WorkItemsChanged(eventType, items); Thread.Sleep(100); Assert.AreEqual(3, WorkItemChanged1Count); Assert.AreEqual(3, WorkItemChanged2Count); Assert.AreEqual(0, WorkItemChanged3Count); SubscribeAndPause(monitor, WorkItemChanged1); UnsubscribeAndPause(monitor, WorkItemChanged2); SubscribeAndPause(monitor, WorkItemChanged3); WaitForEvents(() => callback.WorkItemsChanged(eventType, items), 2); Assert.AreEqual(4, WorkItemChanged1Count); Assert.AreEqual(3, WorkItemChanged2Count); Assert.AreEqual(1, WorkItemChanged3Count); //TODO (Marmot): Expand to include multiple filters, etc. }
public int EnrichToWorkItem(WorkItemData workItem) { throw new NotImplementedException(); }