Understanding TFS with AX 2012 (II)

After describing how AX gets its files from TFS, let us next look a little bit at the code behind the scene and understand why some of the issues are appearing, and what can be done to fix it.
The standard classes for working with TFS are:


This is a standard callstack for doing a file synchronize:

[c] \Classes\SysImportElements\import 11
[c] \Data Dictionary\Tables\SysVersionControlSynchronizeLog\Methods\processModelInBatchNum
[c] \Data Dictionary\Tables\SysVersionControlSynchronizeLog\Methods\processBatchNum 2 g
     [c] \Classes\SysVersionControlFilebasedBackEndTfs\fileSynchronize 8 d+f
[c] \Classes\SysVersionControlSystemFileBased\commandSynchronize 87 b+c
[c] \Classes\VersionControl\getLatestVersion 7 a
 Let us start looking into how the flow goes:

a) the command to get the object(s) is issued;

b) a decision on whether what you want to get is made; it's either a file or the entire directory;

c) if it's a file we are looking at the Force parameter and try to set it; this is what happens, but the idea is that the controllable which is of type SysTreeNode is always returning false, so:

        filename = this.fileName(_controllable);
        _syncParm.parmForce(_syncParm.parmForce() && _controllable.forceSynchronize());

d) this is where we actually download the file, if it's not Latest Yes;

result = tfsWorkspaceProxy.Get(_filename, _syncParameters.parmVersion(), _syncParameters.parmForce());

e) in this moment we have a result from the TFS in the form of

Number of failures: 0
Number of Warnings: 0
Have resolvable Warnings: False
Number of Operations: 0
Number of Conflicts: 0

[c] \Classes\SysVersionControlFilebasedBackEndTfs\processGetCommandResult 54
[c] \Classes\SysVersionControlFilebasedBackEndTfs\createSyncResultMap 85

and we parse the result;

f) if we have any we insert the entries in the table SysVersionControlSynchronizeLog; they will be created with the value for Processed set to false; we have not yet imported anything in AX;

g) we start to process the changes. First, the deletes are being taken care of. Then, we process the xpos we got as part of the add change: we include them in a large xpo file, that we will import;

        // Delete commands must be processed first, as they may be part of a rename or move to model operation.
        result = SysVersionControlSynchronizeLog::processDeletesInBatchNum(_batchNum);

        while (modelsEnum.moveNext())
            modelId = modelsEnum.current();
            if (SysModelStore::modelExists(modelId))
                result = SysVersionControlSynchronizeLog::processModelInBatchNum(modelId, _batchNum) && result;
                result = checkFailed(strFmt("@SYS345063", SysModelStore::displayName(modelId)));

h) if the result of the import for each object is successful, we update the status of the Processed column to true;

The following is a typical callstack when doing a Synchronize (on a model):

[c]    \Classes\SysVersionControlFilebasedBackEndTfs\folderSetSynchronize 19 c
[c]    \Classes\SysVersionControlSystemFileBased\commandSynchronize 79 b
[c]    \Classes\VersionControl\getLatestVersion 7 a
[c]    \Classes\SysVersionControlSynchronization\run 28
[c]    \Classes\SysVersionControlSynchronization\main 23

So, as a conclusion: if you do a synchronize check the Processed value for the objects included in the latest update batch in the Version Control -> Synchronization log; it should be True; if not an error occurred and most likely your AX is missing the latest set of objects.

No comments:

Post a Comment