tech·nic·al·ly agile

A working Test Track Pro Adapter for the TFS Integration Platform

Discover a reliable Test Track Pro Adapter for the TFS Integration Platform, enabling seamless updates and efficient work item management. Learn more!

Published on
12 minute read
Image
https://nkdagility.com/resources/W5oq_99ThZi

A working Test Track Pro Adapter for the TFS Integration Platform  

Well, it has been a long road from misery  to hope  with a little disbelief  thrown in for good measure, but I finally have a working Adapter for the TFS Integration Platform.

Acknowledgements

Updates


With the new code, which has gone through many refactors for the sake of last ditch efforts to figure out the bug I am now able to update TFS from TTP in an incremental fashion.

A working Test Track Pro Adapter for the TFS Integration Platform  

Figure: Work Items are now being updated

  1Imports Microsoft.TeamFoundation.Migration.Toolkit
  2Imports System.ComponentModel.Design
  3Imports System.Collections.ObjectModel
  4Imports Microsoft.TeamFoundation.Migration.Toolkit.Services
  5Imports Microsoft.TeamFoundation.Migration.BusinessModel
  6Imports Microsoft.TeamFoundation.Migration.Toolkit.ErrorManagement
  7Imports System.Globalization
  8Imports System.Xml
  9Imports Microsoft.TeamFoundation.Migration.Toolkit.SyncOrchestrator
 10Imports System.Net
 11Imports System.IO
 12Imports System.ServiceModel
 13Imports System.ServiceModel.Security
 14Imports NorthwestCadence.TtpTipAdapter.TtpSoapSdk
 15Imports NorthwestCadence.TtpTipAdapter.TtpSoapSdk.api
 16
 17Public Class TtpAnalysisProvider
 18    Inherits AnalysisProviderBase
 19
 20    ' Fields
 21    Private _analysisServiceContainer As IServiceContainer
 22    Private _changeGroupService As ChangeGroupService
 23    Private _configurationService As ConfigurationService
 24    Private _conflictManagerService As ConflictManager
 25    Private _highWaterMarkDelta As HighWaterMark(Of DateTime)
 26    Private _highWaterMarkChangeSet As HighWaterMark(Of Integer)
 27    Private _supportedChangeActions As Dictionary(Of Guid, ChangeActionHandler)
 28    Private _supportedContentTypes As Collection(Of ContentType)
 29    Private _dataSourceConfig As TtpMigrationDataSource
 30    Private _highWaterMarkRevisions As New Dictionary(Of String, HighWaterMark(Of Integer))
 31    Private _tstart As DateTime = Now
 32
 33    ' Properties
 34    Public Overrides ReadOnly Property SupportedChangeActions As Dictionary(Of Guid, ChangeActionHandler)
 35        Get
 36            Return Me._supportedChangeActions
 37        End Get
 38    End Property
 39
 40    Public Overrides ReadOnly Property SupportedContentTypes As Collection(Of ContentType)
 41        Get
 42            Return Me._supportedContentTypes
 43        End Get
 44    End Property
 45
 46    Private Shared Function CreateFieldRevisionDescriptionDoc(row As TtpDefectMigrationItem) As XmlDocument
 47        Dim columns As New XElement("Columns", New Object() {New XElement("Column", New Object() {New XAttribute("DisplayName", "Author"), New XAttribute("ReferenceName", "Author"), New XAttribute("Type", "String"), New XElement("Value", row.AuthorId)}), New XElement("Column", New Object() {New XAttribute("DisplayName", "DisplayName"), New XAttribute("ReferenceName", "DisplayName"), New XAttribute("Type", "String"), New XElement("Value", row.DisplayName)}), New XElement("Column", New Object() {New XAttribute("DisplayName", "Id"), New XAttribute("ReferenceName", "Id"), New XAttribute("Type", "String"), New XElement("Value", row.Id.ToString)})})
 48        Dim column As KeyValuePair(Of String, Object)
 49        For Each column In row.Columns
 50            If Not String.IsNullOrEmpty(column.Value) Then
 51                columns.Add(New XElement("Column", New Object() {New XAttribute("DisplayName", column.Key), New XAttribute("ReferenceName", column.Key), New XAttribute("Type", "String"), New XElement("Value", column.Value)}))
 52            End If
 53        Next
 54        Dim descriptionDoc As New XElement("WorkItemChanges", New Object() {New XAttribute("Revision", row.Revision), New XAttribute("WorkItemType", row.WorItemType), New XAttribute("Author", IIf(String.IsNullOrEmpty(row.AuthorId), "", row.AuthorId)), New XAttribute("ChangeDate", row.ModifiedOn.ToString(CultureInfo.CurrentCulture)), New XAttribute("WorkItemID", row.Id.ToString), columns})
 55        Dim doc As New XmlDocument
 56        doc.LoadXml(descriptionDoc.ToString)
 57        Return doc
 58    End Function
 59
 60    Private Shared Function CreateFieldColumn(migrationActionDetails As XmlDocument, displayName As String, referenceName As String, fieldType As String, value As Object, isSkippingField As Boolean) As XmlElement
 61        Dim c As XmlElement = migrationActionDetails.CreateElement("Column")
 62        c.SetAttribute("DisplayName", displayName)
 63        c.SetAttribute("ReferenceName", referenceName)
 64        c.SetAttribute("Type", fieldType)
 65        c.SetAttribute("IsSkippingField", isSkippingField.ToString())
 66        Dim v As XmlElement = migrationActionDetails.CreateElement("Value")
 67        'object translatedValue = TranslateFieldValue(f, fieldValue);
 68        Dim translatedValue As Object = value
 69        If translatedValue Is Nothing Then
 70            v.InnerText = String.Empty
 71        Else
 72            translatedValue.ToString()
 73        End If
 74        c.AppendChild(v)
 75        Return c
 76    End Function
 77
 78    Public Overrides Sub GenerateDeltaTable()
 79        _tstart = Now
 80        Try
 81            Dim viewName As String = Me._configurationService.Filters.Item(0).Path
 82            TraceManager.TraceInformation("TtpWIT:AP:GenerateDeltaTable:View - {0}", New Object() {viewName})
 83            Me._highWaterMarkDelta.Reload()
 84            '------------------------------------------------------
 85            Dim context As TtpContext = GetTtpContext()
 86            Dim raw As List(Of TtpDefectMigrationItem) = GetTtpRawData(context, viewName)
 87            TraceManager.TraceInformation("Located {0} raw updates since {1} in {2} seconds", raw.Count, _highWaterMarkDelta.Value, Now.Subtract(_tstart).TotalSeconds)
 88            ' Find all of the data that needs to be added in this run
 89            Dim deltaNew = (From ri In raw Where ri.CreatedOn.CompareTo(_highWaterMarkDelta.Value) > 0 Or ri.Revision = 0).ToList
 90            ' Get any extra data and create the add changesets
 91            TraceManager.TraceInformation("Located {0} deltas as NEW in {1} seconds", deltaNew.Count, Now.Subtract(_tstart).TotalSeconds)
 92            deltaNew = GetDeltaWorkflow(context, deltaNew)
 93            TraceManager.TraceInformation("Updated {0} deltas with workflow in {1} seconds", deltaNew.Count, Now.Subtract(_tstart).TotalSeconds)
 94            Dim changesNew As List(Of ChangeGroup) = GetChangeGroupsForAdds(deltaNew)
 95            TraceManager.TraceInformation("Created {0} add change groups in {1} seconds", changesNew.Count, Now.Subtract(_tstart).TotalSeconds)
 96            ' Save the chnagesets to the backing store
 97            For Each c In changesNew
 98                c.Save()
 99            Next
100            TraceManager.TraceInformation("Saved {0} add change groups in {1} seconds", changesNew.Count, Now.Subtract(_tstart).TotalSeconds)
101            ' Find all of the data that needs to be edited in this run
102            Dim deltaEdit = (From ri In raw Where (ri.ModifiedOn.CompareTo(_highWaterMarkDelta.Value) > 0 And Not ri.CreatedOn.CompareTo(_highWaterMarkDelta.Value) > 0) Or ri.Revision > 0).ToList
103            ' Get any extra data and create the edit changesets
104            TraceManager.TraceInformation("Located {0} deltas as EDIT in {1} seconds", deltaEdit.Count, Now.Subtract(_tstart).TotalSeconds)
105            deltaEdit = GetDeltaWorkflow(context, deltaEdit)
106            TraceManager.TraceInformation("Updated {0} deltas with workflow in {1} seconds", deltaEdit.Count, Now.Subtract(_tstart).TotalSeconds)
107            Dim changesEdit As List(Of ChangeGroup) = GetChangeGroupsForEdits(deltaEdit)
108            TraceManager.TraceInformation("Created {0} edit change groups in {1} seconds", changesEdit.Count, Now.Subtract(_tstart).TotalSeconds)
109            ' Save the chnagesets to the backing store
110            For Each c In changesEdit
111                c.Save()
112            Next
113            TraceManager.TraceInformation("Saved {0} edit change groups in {1} seconds", changesEdit.Count, Now.Subtract(_tstart).TotalSeconds)
114            '------------------------------------------------------
115            ' Update the High water mark and send the changes through
116            Me._highWaterMarkDelta.Update(DateTime.Now)
117            Me._changeGroupService.PromoteDeltaToPending()
118        Catch ex As Exception
119            TraceManager.TraceException(ex)
120        End Try
121    End Sub
122
123    Public Overrides Sub InitializeClient()
124        TraceManager.TraceInformation("TtpWIT:AP:InitializeClient")
125    End Sub
126
127    Private Shared Function InitializeMigrationDataSource() As TtpMigrationDataSource
128        Return New TtpMigrationDataSource
129    End Function
130
131    Public Overrides Sub InitializeServices(ByVal analysisService As IServiceContainer)
132        TraceManager.TraceInformation("TtpWIT:AP:InitializeServices")
133        If (analysisService Is Nothing) Then
134            Throw New ArgumentNullException("analysisService")
135        End If
136        Me._analysisServiceContainer = analysisService
137        Me._configurationService = DirectCast(analysisService.GetService(GetType(ConfigurationService)), ConfigurationService)
138        Dim migrationSourceConfiguration As MigrationSource = Me._configurationService.MigrationSource
139        _dataSourceConfig = TtpAnalysisProvider.InitializeMigrationDataSource
140        Dim customSetting As CustomSetting
141        Dim username As String = ""
142        Dim password As String = ""
143        Dim IsWorkflowIncluded As Boolean = True
144        Dim hwmDateOveride As DateTime = DateTime.MinValue
145        For Each customSetting In Me._configurationService.MigrationSource.CustomSettings.CustomSetting
146            If customSetting.SettingKey.Equals("Username", StringComparison.OrdinalIgnoreCase) Then
147                username = customSetting.SettingValue
148            End If
149            If customSetting.SettingKey.Equals("Password", StringComparison.OrdinalIgnoreCase) Then
150                password = customSetting.SettingValue
151            End If
152            If customSetting.SettingKey.Equals("OverrideHWM", StringComparison.OrdinalIgnoreCase) Then
153                If Not DateTime.TryParse(customSetting.SettingValue, hwmDateOveride) Then
154                    Throw New InvalidCastException("Date is not in the correct format: OverrideHWM")
155                End If
156            End If
157            If customSetting.SettingKey.Equals("IsWorkflowIncluded", StringComparison.OrdinalIgnoreCase) Then
158                If Not Boolean.TryParse(customSetting.SettingValue, IsWorkflowIncluded) Then
159                    Throw New InvalidCastException("Date is not in the correct format: IsWorkflowIncluded")
160                End If
161            End If
162        Next
163
164        _dataSourceConfig.Credentials = New NetworkCredential(username, password)
165        _dataSourceConfig.DatabaseName = migrationSourceConfiguration.SourceIdentifier
166        _dataSourceConfig.FilterName = IIf(migrationSourceConfiguration.ServerIdentifier = "[enterFiltername]", "", migrationSourceConfiguration.ServerIdentifier)
167        _dataSourceConfig.Url = migrationSourceConfiguration.ServerUrl
168        _dataSourceConfig.IsWorkflowIncluded = IsWorkflowIncluded
169
170
171        Me._supportedContentTypes = New Collection(Of ContentType)
172        Me.SupportedContentTypes.Add(WellKnownContentType.WorkItem)
173
174        Dim handler As New TtpChangeActionHandlers(Me)
175
176        Me._supportedChangeActions = New Dictionary(Of Guid, ChangeActionHandler)
177        Me.SupportedChangeActions.Add(WellKnownChangeActionId.Add, New ChangeActionHandler(AddressOf handler.BasicActionHandler))
178        Me.SupportedChangeActions.Add(WellKnownChangeActionId.Edit, New ChangeActionHandler(AddressOf handler.BasicActionHandler))
179        Me.SupportedChangeActions.Add(WellKnownChangeActionId.Delete, New ChangeActionHandler(AddressOf handler.BasicActionHandler))
180        Me._highWaterMarkDelta = New HighWaterMark(Of DateTime)("HWMDelta")
181        Me._highWaterMarkChangeSet = New HighWaterMark(Of Integer)("LastChangeSet")
182        Me._configurationService.RegisterHighWaterMarkWithSession(Me._highWaterMarkDelta)
183        Me._configurationService.RegisterHighWaterMarkWithSession(Me._highWaterMarkChangeSet)
184
185        If hwmDateOveride > DateTime.MinValue Then
186            _highWaterMarkDelta.Update(hwmDateOveride)
187        End If
188
189        Me._changeGroupService = DirectCast(Me._analysisServiceContainer.GetService(GetType(ChangeGroupService)), ChangeGroupService)
190
191        Me._changeGroupService.RegisterDefaultSourceSerializer(New TtpDefectMigrationItemSerializer)
192    End Sub
193
194    Public Overrides Sub RegisterConflictTypes(ByVal conflictManager As ConflictManager)
195        TraceManager.TraceInformation("TtpWIT:AP:RegisterConflictTypes")
196        Me._conflictManagerService = DirectCast(Me._analysisServiceContainer.GetService(GetType(ConflictManager)), ConflictManager)
197        Me._conflictManagerService.RegisterConflictType(New GenericConflictType)
198        Me._conflictManagerService.RegisterConflictType(New TtpGeneralConflictType, ConflictsSyncOrchOptions.Continue)
199    End Sub
200
201    Public Overrides Sub RegisterSupportedChangeActions(ByVal changeActionRegistrationService As ChangeActionRegistrationService)
202        TraceManager.TraceInformation("TtpWIT:AP:RegisterSupportedChangeActions")
203        changeActionRegistrationService = DirectCast(Me._analysisServiceContainer.GetService(GetType(ChangeActionRegistrationService)), ChangeActionRegistrationService)
204        Dim supportedChangeAction As KeyValuePair(Of Guid, ChangeActionHandler)
205        For Each supportedChangeAction In Me.SupportedChangeActions
206            Dim contentType As ContentType
207            For Each contentType In Me.SupportedContentTypes
208                changeActionRegistrationService.RegisterChangeAction(supportedChangeAction.Key, contentType.ReferenceName, supportedChangeAction.Value)
209            Next
210        Next
211    End Sub
212
213    Public Overrides Sub RegisterSupportedContentTypes(contentTypeRegistrationService As Microsoft.TeamFoundation.Migration.Toolkit.Services.ContentTypeRegistrationService)
214
215    End Sub
216
217    Private Function GetTtpContext() As TtpContext
218        TraceManager.TraceInformation("-GetTtpContext")
219        Dim TtpServer As Uri = New Uri(String.Format("{0}/scripts/ttsoapcgi.exe", _dataSourceConfig.Url))
220        TraceManager.TraceInformation(ChrW(9) & "-GetTtpContext Loading Ttp  {0}", New Object() {TtpServer})
221        Dim context As TtpContext = Nothing
222        Try
223            context = TtpSoapSdkApi.CreateContext(TtpServer, _dataSourceConfig.DatabaseName, _dataSourceConfig.Credentials.UserName, _dataSourceConfig.Credentials.Password)
224            TraceManager.TraceInformation("-GetTtpContext Connected to '{0}' on '{1}' in {2}", context.Project.database, TtpServer, Now.Subtract(_tstart).ToFriendly)
225        Catch ex As Exception
226            TraceManager.TraceException(ex)
227        End Try
228        Return context
229    End Function
230
231    Private Function GetTtpRawData(context As TtpContext, filter As String) As List(Of TtpDefectMigrationItem)
232        Dim raw As New List(Of TtpDefectMigrationItem)
233        Try
234            Dim columns As List(Of CTableColumn) = context.GetColumns("Defect")
235            TraceManager.TraceInformation("-GetTtpRawData '{0}' columns in {1}", columns.Count, Now.Subtract(_tstart).ToFriendly)
236            TraceManager.TraceInformation("-GetTtpRawData Atempting get on all data")
237            Dim rows As CRecordListSoap = context.GetRecords("Defect", filter, columns)
238            TraceManager.TraceInformation("-GetTtpRawData Found {0} records in {1} seconds", rows.records.Count, Now.Subtract(_tstart).TotalSeconds)
239            Dim currentRecord As Integer = 1
240            Dim countRecords = rows.records.Count
241            For Each record In rows.records
242                ' item has been modified since HWM & before deltra table start time
243                Try
244                    Dim DefectMI As TtpDefectMigrationItem = TtpDefectMigrationItem.ConvertCDefectToTtpDefectMigrationItem(_configurationService, columns.ToArray, record)
245                    '----------------
246                    raw.Add(DefectMI)
247                    TraceManager.TraceInformation("-GetTtpRawData  {0} of {1} - '{2}' Number '{3}' has loaded in {4} seconds", currentRecord, countRecords, DefectMI.WorItemType, DefectMI.Id, Now.Subtract(_tstart).TotalSeconds)
248                Catch ex As Exception
249                    TraceManager.TraceError("-GetTtpRawData  {0} of {1} - '{2}' Number '{3}' has {4} processing in {5} seconds", currentRecord, countRecords, "unknown", "unknown", "failed", Now.Subtract(_tstart).TotalSeconds)
250                    TraceManager.TraceException(ex)
251                End Try
252                currentRecord = currentRecord + 1
253            Next
254        Catch ex As Exception
255            TraceManager.TraceException(ex)
256        End Try
257        Return raw
258    End Function
259
260    Private Function GetDeltaWorkflow(context As TtpContext, ByVal deltas As List(Of TtpDefectMigrationItem)) As List(Of TtpDefectMigrationItem)
261        Try
262            Dim currentRecord As Integer = 1
263            Dim countRecords = deltas.Count
264            For Each di In deltas
265                ' item has been modified since HWM & before deltra table start time
266                If _dataSourceConfig.IsWorkflowIncluded Then
267                    di.ImportDefectData(context)
268                    TraceManager.TraceInformation("-GetDeltaWorkflow  {0} of {1} - '{2}' Number '{3}' has {4} processing revision {5} in {6} seconds", currentRecord, countRecords, di.WorItemType, di.Id, "UPDATED", di.Revision, Now.Subtract(_tstart).TotalSeconds)
269                Else
270                    TraceManager.TraceInformation("-GetDeltaWorkflow  {0} of {1} - '{2}' Number '{3}' has {4} processing revision {5} in {6} seconds", currentRecord, countRecords, di.WorItemType, di.Id, "SKIPPED", di.Revision, Now.Subtract(_tstart).TotalSeconds)
271                End If
272                currentRecord = currentRecord + 1
273            Next
274        Catch ex As Exception
275            TraceManager.TraceException(ex)
276        End Try
277        Return deltas
278    End Function
279
280    Private Function GetChangeGroupsForAdds(ByVal deltas As List(Of TtpDefectMigrationItem)) As List(Of ChangeGroup)
281        Dim changes As New List(Of ChangeGroup)
282        Try
283            Dim currentRecord As Integer = 1
284            Dim countRecords = deltas.Count
285            For Each delta In deltas
286                ' item has been modified since HWM & before deltra table start time
287                Try
288                    ' Create and add acction group
289                    delta.ResetRevision()
290                    Dim changeGroup As ChangeGroup = Me._changeGroupService.CreateChangeGroupForDeltaTable(String.Format("{0}:{1}", delta.Id, delta.Revision))
291                    changeGroup.Status = ChangeStatus.Delta
292                    changeGroup.Owner = Nothing
293                    changeGroup.Comment = String.Format(CultureInfo.CurrentCulture, "Changeset {0}", _highWaterMarkChangeSet.Value)
294                    changeGroup.ChangeTimeUtc = DateTime.UtcNow
295                    changeGroup.Status = ChangeStatus.Delta
296                    changeGroup.ExecutionOrder = 0
297
298                    changeGroup.CreateAction( _
299                            WellKnownChangeActionId.Add, _
300                            delta, _
301                            delta.Id, _
302                            _dataSourceConfig.DatabaseName, _
303                            delta.Revision, _
304                            " ", _
305                            WellKnownContentType.WorkItem.ReferenceName, _
306                            TtpAnalysisProvider.CreateFieldRevisionDescriptionDoc(delta) _
307                            )
308                    changes.Add(changeGroup)
309                    _highWaterMarkChangeSet.Update((_highWaterMarkChangeSet.Value + 1))
310                    ' DONE
311                Catch ex As Exception
312                    TraceManager.TraceError("-GetChangeGroups  {0} of {1} - '{2}' Number '{3}' has {4} processing in {5} seconds", currentRecord, countRecords, "unknown", "unknown", "failed", Now.Subtract(_tstart).TotalSeconds)
313                    TraceManager.TraceException(ex)
314                End Try
315                currentRecord = currentRecord + 1
316            Next
317        Catch ex As Exception
318            TraceManager.TraceException(ex)
319        End Try
320        Return changes
321    End Function
322
323    Private Function GetChangeGroupsForEdits(ByVal deltas As List(Of TtpDefectMigrationItem)) As List(Of ChangeGroup)
324        Dim changes As New List(Of ChangeGroup)
325        Try
326            Dim currentRecord As Integer = 1
327            Dim countRecords = deltas.Count
328            For Each delta In deltas
329                ' item has been modified since HWM & before deltra table start time
330                Try
331                    ' Create and add acction group
332                    delta.IncrementRevision()
333                    Dim changeGroup As ChangeGroup = Me._changeGroupService.CreateChangeGroupForDeltaTable(String.Format("{0}:{1}", delta.Id, delta.Revision))
334                    changeGroup.Status = ChangeStatus.Delta
335                    changeGroup.Owner = Nothing
336                    changeGroup.Comment = String.Format(CultureInfo.CurrentCulture, "Changeset {0}", _highWaterMarkChangeSet.Value)
337                    changeGroup.ChangeTimeUtc = DateTime.UtcNow
338                    changeGroup.Status = ChangeStatus.Delta
339                    changeGroup.ExecutionOrder = 0
340
341                    changeGroup.CreateAction( _
342                            WellKnownChangeActionId.Edit, _
343                            delta, _
344                            delta.Id, _
345                            _dataSourceConfig.DatabaseName, _
346                            delta.Revision, _
347                            " ", _
348                            WellKnownContentType.WorkItem.ReferenceName, _
349                            TtpAnalysisProvider.CreateFieldRevisionDescriptionDoc(delta) _
350                            )
351                    changes.Add(changeGroup)
352                    _highWaterMarkChangeSet.Update((_highWaterMarkChangeSet.Value + 1))
353                    ' DONE
354                Catch ex As Exception
355                    TraceManager.TraceError("-GetChangeGroups  {0} of {1} - '{2}' Number '{3}' has {4} processing in {5} seconds", currentRecord, countRecords, "unknown", "unknown", "failed", Now.Subtract(_tstart).TotalSeconds)
356                    TraceManager.TraceException(ex)
357                End Try
358                currentRecord = currentRecord + 1
359            Next
360        Catch ex As Exception
361            TraceManager.TraceException(ex)
362        End Try
363        Return changes
364    End Function
365
366End Class

Figure: Full source for the Analysis Provider

 1Private Function GetChangeGroupsForEdits(ByVal deltas As List(Of TtpDefectMigrationItem)) As List(Of ChangeGroup)
 2    Dim changes As New List(Of ChangeGroup)
 3    Try
 4        Dim currentRecord As Integer = 1
 5        Dim countRecords = deltas.Count
 6        For Each delta In deltas
 7            ' item has been modified since HWM & before deltra table start time
 8            Try
 9                ' Create and add acction group
10                delta.IncrementRevision()
11                Dim changeGroup As ChangeGroup = Me._changeGroupService.CreateChangeGroupForDeltaTable(String.Format("{0}:{1}", delta.Id, delta.Revision))
12                changeGroup.Status = ChangeStatus.Delta
13                changeGroup.Owner = Nothing
14                changeGroup.Comment = String.Format(CultureInfo.CurrentCulture, "Changeset {0}", _highWaterMarkChangeSet.Value)
15                changeGroup.ChangeTimeUtc = DateTime.UtcNow
16                changeGroup.Status = ChangeStatus.Delta
17                changeGroup.ExecutionOrder = 0
18
19                changeGroup.CreateAction( _
20                        WellKnownChangeActionId.Edit, _
21                        delta, _
22                        delta.Id, _
23                        _dataSourceConfig.DatabaseName, _
24                        delta.Revision, _
25                        " ", _
26                        WellKnownContentType.WorkItem.ReferenceName, _
27                        TtpAnalysisProvider.CreateFieldRevisionDescriptionDoc(delta) _
28                        )
29                changes.Add(changeGroup)
30                _highWaterMarkChangeSet.Update((_highWaterMarkChangeSet.Value + 1))
31                ' DONE
32            Catch ex As Exception
33                TraceManager.TraceError("-GetChangeGroups  {0} of {1} - '{2}' Number '{3}' has {4} processing in {5} seconds", currentRecord, countRecords, "unknown", "unknown", "failed", Now.Subtract(_tstart).TotalSeconds)
34                TraceManager.TraceException(ex)
35            End Try
36            currentRecord = currentRecord + 1
37        Next
38    Catch ex As Exception
39        TraceManager.TraceException(ex)
40    End Try
41    Return changes
42End Function

Figure: New code to get change groups

I am not exactly positive what made the difference as much of my debugging efforts were hampered by the nasty query bug in TTP  , but I am very glad that it is working. It looks like I do not need to have consecutive Revision’s although as I have already implemented the code for it I am not going to change it at this stage in the game.

It is now a mater of configuration, but I am creating a table with all of the values of the 120+ fields as well as a neat table for the workflow and inserting it into the history.

A working Test Track Pro Adapter for the TFS Integration Platform  

Figure: Loooong history built from TTP Data

This history shows all of the values for the fields at the point in time that the data was migrated.

All in, I am quite happy with the process and will be implementing in production really soon. Still some testing to do, but all looks good so far.

Software Development
Comments

Related blog posts

No related videos found.

Connect with Martin Hinshelwood

If you've made it this far, it's worth connecting with our principal consultant and coach, Martin Hinshelwood, for a 30-minute 'ask me anything' call.

Our Happy Clients​

We partner with businesses across diverse industries, including finance, insurance, healthcare, pharmaceuticals, technology, engineering, transportation, hospitality, entertainment, legal, government, and military sectors.​

Kongsberg Maritime Logo
Brandes Investment Partners L.P. Logo
Boeing Logo
ProgramUtvikling Logo

NIT A/S

Freadom Logo
Schlumberger Logo
DFDS Logo
ALS Life Sciences Logo
Capita Secure Information Solutions Ltd Logo
Cognizant Microsoft Business Group (MBG) Logo
Alignment Healthcare Logo
Philips Logo
Qualco Logo
Ericson Logo
Jack Links Logo
Deliotte Logo
Boxit Document Solutions Logo
Washington Department of Enterprise Services Logo
Ghana Police Service Logo
Nottingham County Council Logo
New Hampshire Supreme Court Logo
Royal Air Force Logo
Department of Work and Pensions (UK) Logo
Xceptor - Process and Data Automation Logo
Alignment Healthcare Logo
Lockheed Martin Logo
YearUp.org Logo
Big Data for Humans Logo
Akaditi Logo