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.
1[06/06/2011 10:12:14] MigrationConsole.exe Information: 0 : WorkItemTracking: Processing ChangeGroup #3214, change 3143:2
2[06/06/2011 10:12:15] MigrationConsole.exe Information: 0 : WorkItemTracking: Unresolved conflict:
3[06/06/2011 10:12:15] Session: adea805d-51df-489a-b2fd-9717b4af3703
4[06/06/2011 10:12:15] Source: 6e3bdf70-f1ae-4cd5-8ee4-133c8aee0857
5[06/06/2011 10:12:15] Message: Cannot find applicable resolution rule.
6[06/06/2011 10:12:15] Conflict Type: TFS WIT history not found conflict type
7[06/06/2011 10:12:15] Conflict Type Reference Name: 1722df87-ab61-4ad0-8b41-531d3d804089
8[06/06/2011 10:12:15] Conflict Details: <?xml version="1.0"?>
9[06/06/2011 10:12:15] <WorkItemHistoryNotFoundConflictTypeDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
10[06/06/2011 10:12:15] <SourceWorkItemID>3143</SourceWorkItemID>
11[06/06/2011 10:12:15] <SourceWorkItemRevision>2</SourceWorkItemRevision>
12[06/06/2011 10:12:15] <SourceMigrationSourceId>c513f930-2602-400d-a0bf-a2a3ab434df5</SourceMigrationSourceId>
13[06/06/2011 10:12:15] <TargetMigrationSourceId>6e3bdf70-f1ae-4cd5-8ee4-133c8aee0857</TargetMigrationSourceId>
14[06/06/2011 10:12:15] </WorkItemHistoryNotFoundConflictTypeDetails>
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.
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.
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.
No related videos found.
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.
We partner with businesses across diverse industries, including finance, insurance, healthcare, pharmaceuticals, technology, engineering, transportation, hospitality, entertainment, legal, government, and military sectors.
NIT A/S