Vault Data Standards - Upload File problem

Vault Data Standards - Upload File problem

cassidy_ng
Contributor Contributor
4,292 Views
19 Replies
Message 1 of 20

Vault Data Standards - Upload File problem

cassidy_ng
Contributor
Contributor

Hi

 

I am having issues with uploading files using Vault Data Standards.  For some reason it will work the first time but hangs on the following line of code the second time the code is executed.  The Vault client freezes and I have no choice but to kill the session.  Any ideas?

 
$uploadTicket.Bytes = $vault.FilestoreService.UploadFilePart($bufferStream)
 
Regards,
Cassidy
0 Likes
Accepted solutions (1)
4,293 Views
19 Replies
Replies (19)
Message 2 of 20

wangdu
Collaborator
Collaborator

Hi,

The line of code is from Vault API which you are using in VDS. It looks like a customization is involved in your VDS for some workflow that you haven't mentioned here. Therefore it's difficult to suggest anything based on that line of code. 

One thing you can try is in order to avoid that the Vault hangs on that line, wrap it with try catch statement. It will not hang the Vault client and you will also be able to make out what error is returned in the catch block. 

Hope it helps!

Wangdu

coolOrange

0 Likes
Message 3 of 20

cassidy_ng
Contributor
Contributor

Hi Wangdu

 

Putting a try catch block on that line of code does not make a difference.  I've been using 

$dsDiag.inspect() to debug and identify which line of code the Vault client is hanging on.  I think the code is correct as I can run it without problems outside of VDS and runs on the first attempt.  As for the customization of VDS, I added a menuitem in the MenuDefinitions.xml to call the powershell script.
 
Regards,
Cassidy
0 Likes
Message 4 of 20

wangdu
Collaborator
Collaborator

Hi,

 

I don't know what could be causing the issue then.

Would you be able to share something that I can give a look at and maybe do a test to reproduce the same problem? 

 

Regards,

Wangdu

coolOrange

0 Likes
Message 5 of 20

cassidy_ng
Contributor
Contributor

Hi

Here are the two functions used to Checkin and Upload files to Vault.  Let me know if you are able to reproduce the problem by calling the CheckinFile function in VDS.

 

Regards,

Cassidy

 

Function UploadFile {
	param ( 
		[System.Object[]] $vault = $(throw "-vault is required."),
		[string]$filePath = $(throw "-filename is required.")
	)
	if(-Not (Test-Path $filePath -PathType Leaf)) {
		Exit
	}
	$maxFilePartSize = 49 * 1024 * 1024    # 49MB perchunk
	
	$fileContents = [System.IO.File]::ReadAllBytes($filePath)

	# ---------------------------------------------------------------------------------------------------------------
	$vault.FilestoreService.FileTransferHeaderValue = New-Object Autodesk.Connectivity.WebServices.FileTransferHeader
	$vault.FilestoreService.FileTransferHeaderValue.Identity = [Guid]::NewGuid()
	$vault.FilestoreService.FileTransferHeaderValue.Extension = [System.IO.Path]::GetExtension($filePath)
	$vault.FilestoreService.FileTransferHeaderValue.Vault = $vault.WebServiceCredentials.VaultName

	# create a upload ticket, this is a prerequisiste for checking the file out
	$uploadTicket = New-Object Autodesk.Connectivity.WebServices.ByteArray
	$bytesSent = 0
	$bufferSize = $maxFilePartSize
	while ($bytesSent -lt $fileContents.Length) {
		if (($fileContents.Length - $bytesSent) -lt $maxFilePartSize) {
			$bufferSize = $fileContents.Length - $bytesSent
		}
		else {
			$bufferSize = $maxFilePartSize
		}

		$Compression = New-Object Autodesk.Connectivity.WebServices.Compression
		$vault.FilestoreService.FileTransferHeaderValue.Compression = $Compression::None
		$vault.FilestoreService.FileTransferHeaderValue.UncompressedSize = $bufferSize	
		if (($bufferSize + $bytesSent) -ge $fileContents.Length) {
			$isComplete = $true
		}
		else {
			$isComplete = $false
		}
		$vault.FilestoreService.FileTransferHeaderValue.IsComplete = $isComplete

		[byte[]] $buffer = $null
		if ($bufferSize -eq $fileContents.Length) {
			$buffer = $fileContents
		}
		else {
			$buffer = New-Object byte[] $bufferSize
			[System.Array] $Array.Copy($fileContents,[long] $bytesSent, $buffer, 0, [long] $bufferSize)
		}
		$bufferStream = New-Object System.IO.MemoryStream(,$buffer)
		$uploadTicket.Bytes = $vault.FilestoreService.UploadFilePart($bufferStream)
		$bytesSent += $bufferSize
	}
	return $uploadTicket
}

Function ChkinFile {
	param (
		[System.Object[]] $vaultConnection = $(throw "-vaultConnection is required."),
		[string]$filePath = $(throw "-filePath is required."), 
		[string]$comment = $(throw "-comment is required.")
	)

	# Get WebServiceManager object 
    $vault = $vaultConnection.WebServiceManager
    # Get vault root folder
    $root = $vault.DocumentService.GetFolderRoot();
    # Get vault working folder (C:\TEMP\Vault\)
	$workingFolder = $vaultConnection.WorkingFoldersManager.GetWorkingFolder($root.FullName).FullPath
	# Get vault folder path
	$vltFilePath = $filePath.Replace($workingFolder,"$/").Replace('\','/')
	# Get file object from vault file path
	$file = $vault.DocumentService.FindLatestFilesByPaths($vltFilePath)

	# get child file associations so we can preserve them.
	$FileAssocAlg = New-Object Autodesk.Connectivity.WebServices.FileAssocAlg
	$FileAssociationTypeEnum = New-Object Autodesk.Connectivity.WebServices.FileAssociationTypeEnum
	[Autodesk.Connectivity.WebServices.FileAssocLite[]] $childAssocs =  $vault.DocumentService.GetFileAssociationLitesByIds($file.Id, $FileAssocAlg::Actual.value__, $FileAssociationTypeEnum::None.value__, $false, $FileAssociationTypeEnum::All.value__, $false, $true, $false, $true)

	# convert FileAssocLite array to FileAssocParam array
	$associations = @()
	foreach ($childAssoc in $childAssocs)
	{
		$childAssocObj = New-Object Autodesk.Connectivity.WebServices.FileAssocParam -Property @{ Typ = $childAssoc.Typ; CldFileId = $childAssoc.CldFileId; Source = $childAssoc.Source; RefId = $childAssoc.RefId; ExpectedVaultPath = $childAssoc.ExpectedVaultPath }
		if ($null -ne $childAssocObj)
		{
			$associations += $childAssocObj
		}
	}

	# upload/checkin pdf drawing file from local to Vault
	# create a ticket to check the file back in with
	$uploadTicket = UploadFile -vault $vault -filePath $filePath
	# check the file back in
	$checkedInFile = $vault.DocumentService.CheckinUploadedFile($file.MasterId, $comment, $false, `
	(Get-Date),$associations,$null,$true,$file.Name,$file.FileClass,$file.Hidden,$uploadTicket)
	return $checkedInFile
}

 

 

0 Likes
Message 6 of 20

wangdu
Collaborator
Collaborator

Hi,

 

I still don't know how to reproduce the issue you are facing. Can you please provide the powershell file that get executed when you do a click on your custom menu? I want to know what parameters you are passing to the function ChkInFile.

 

Thanks,

Wangdu

0 Likes
Message 7 of 20

cassidy_ng
Contributor
Contributor

Hi

 

I have attached the powershell that is being called.

 

Regards,

Cassidy

0 Likes
Message 8 of 20

wangdu
Collaborator
Collaborator

Hi,

 

I tested and find that for me the first time it is freezing. I don't know why. 

 

One thing that you can try is to change the uploading file API by using the VDF's Connection.FileManager.AddFile instead of the FileStoreService.UploadFilePart.

 

If that doesn't work, then I don't know what else can you do. I suggest to contact the Autodesk support and get help on the Vault API since these are related to Vault API and not to the Vault Data Standard.

 

Hope it helps!

Wangdu

coolOrange

0 Likes
Message 9 of 20

cassidy_ng
Contributor
Contributor

Hi

 

I have already logged this problem with Autodesk.  From what I can see this is related to DataStandards because calling FileStoreService.UploadFilePart works outside of Vault.  I suspect it has something to do with the vault connection but I am not 100% sure. 

 

Regards,

Cassidy

0 Likes
Message 10 of 20

wangdu
Collaborator
Collaborator

I did some tests again and I have found that for me it was running into 'Error occured' dialog instead of the freeze i mentioned in my earlier post and the reason is because the the line

#$fileContents = [System.IO.File]::ReadAllBytes($filePath)

was commented. It started working fine after I removed the comment tag. So, for me it isn't hanging at all, not at the second time and also not at any number of times.

 

So, now I am not sure why it is hanging on your machine. I need to reproduce the issue to understand the problem you are facing. And I am not able to reproduce the issue.

 

FYI, I have just a empty dwg file, and I was able to run the menu on that file any number of times. The only thing i saw is that the file is set to unknown status after I run the code. When I delete the local copy then the unknown status goes away.

 

Wangdu

 

0 Likes
Message 11 of 20

cassidy_ng
Contributor
Contributor

Hi

 

My apologies, I forgot to un-comment that line of code.  I added the $dsDiag.inspect() before and after the UploadFilePart and it runs twice the first time and once the second time.  So I can confirm the problem is to do with UploadFilePart.  Also, this is not isolated to my machine, I am able to duplicate the problem on multiple machines.

 

$dsDiag.inspect()
$uploadTicket.Bytes = $svrmgr.FilestoreService.UploadFilePart($bufferStream)
$dsDiag.inspect()
 
Regards,
Cassidy
0 Likes
Message 12 of 20

wangdu
Collaborator
Collaborator

HI again,

 

In my case, I don't have the custom functions and therefore just added a circle to the dwg file and it is working fine. Could it be that the custom commands/functions is doing something to the dwg file that is causing the issue? You could try either using circle or line command in the .scr or just a .txt file and append some texts to the file and see if that makes any difference.

One other thing is that I tried your code always on the only dwg file that I have in my vault. So, is it still hanging for you if you try the code only on just one file? Maybe it doesn't make difference for you, but I don't know what else can be done.

 

Wangdu

0 Likes
Message 13 of 20

cassidy_ng
Contributor
Contributor

Hi Wangdu

 

I managed to get it to work with FileManager.AcquireFiles and FileManager.AddFiles.  Therefore I will not use UploadFilePart() going forward.  Unfortunately, I am getting the same problem when I use ExplorerUtil.UpdateFileProperties to update vault property information via DataStandards.  It's leaving the drawing file checked out which means it is having issues checking in the file which is part of the ExplorerUtil.UpdateFileProperties function.
 
Do you have any suggestions for this problem?  Thanks!  
 
Regards,
Cassidy
0 Likes
Message 14 of 20

wangdu
Collaborator
Collaborator

Hi,

 

Glad to know you managed to get it working.

In your code, I didn't see the UpdateFileProperties. Is this something new that you are doing now?
And how are you getting the ExplorerUtil object?  Are you using the existing $explorerUtil of the VDS?

 

Wangdu

0 Likes
Message 15 of 20

cassidy_ng
Contributor
Contributor

Hi

 

Yes this is part of another function which is having the same with where it hangs after the second time running with VDS.  Here is the function.  Let me know if you are able to duplicate the problem.

Function UpdateFileProps{
	param (
        [System.Object[]] $vaultConnection = $(throw "-vaultConnection is required."),
		[Autodesk.Connectivity.WebServices.File] $file = $(throw "-file is required."),
		[hashtable]$propsNameValues = $(throw "-propsNameValues is required.")
	)
    # Connecting dlls
	[System.Reflection.Assembly]::LoadFrom("C:\Program Files\Autodesk\Vault Professional 2018\Explorer\Autodesk.Connectivity.Extensibility.Framework.dll")
	[System.Reflection.Assembly]::LoadFrom("C:\Program Files\Autodesk\Vault Professional 2018\Explorer\Autodesk.Connectivity.Explorer.ExtensibilityTools.dll")

    # Get WebServiceManager object 
	$vault = $vaultConnection.WebServiceManager

	# Create a explorerUtil object
	$explorerUtil = [Autodesk.Connectivity.Explorer.ExtensibilityTools.ExplorerLoader]::LoadExplorerUtil($vaultConnection.Server, $vaultConnection.Vault, $vaultConnection.UserID, $vaultConnection.Ticket)
	# Create your generic dictionary with properties and values
	$propDefs = $vault.PropertyService.GetPropertyDefinitionsByEntityClassId("FILE")
	$props = New-Object "System.Collections.Generic.Dictionary[[Autodesk.Connectivity.WebServices.PropDef],[System.Object]]"
	ForEach ($prop in $propsNameValues.Keys) {
		$propDef = $propDefs | Where-Object{$_.DispName -eq $prop}
		$propValue = $propsNameValues[$prop]
		$props.Add($propDef,$propValue)
	}
	# Pass the file and the dictionary and update the file properties
	$explorerUtil.UpdateFileProperties($file,$props)
}

   

0 Likes
Message 16 of 20

wangdu
Collaborator
Collaborator

Hi,

 

You should use GetExplorerUtil and not LoadExplorerUtil. This difference is depending on whether you are inside Vault explorer or not. But since, VDS already provides you the $explorerUtil object, you don't need to get it yourself. Try this and see if it works.

 

Hope it helps!

Wangdu

0 Likes
Message 17 of 20

cassidy_ng
Contributor
Contributor

Hi Wangdu

 

I tried using the $vaultExplorerUtil variable in VDS and it has the same problem.

 

Regards,

Cassidy

0 Likes
Message 18 of 20

wangdu
Collaborator
Collaborator
Accepted solution

Hi,

 

Can you try this code for updating the properties? I am updating 'Author' property as you can see in the code. The author property will have the value 'admin' if it runs correctly. I am using the $vaultExplorerUtil that exists in the VDS.

$vaultContext.ForceRefresh = $true
$fileId=$vaultContext.CurrentSelectionSet[0].Id
$file = $vault.DocumentService.GetLatestFileByMasterId($fileId)
$propDefs = $vault.PropertyService.GetPropertyDefinitionsByEntityClassId("FILE")
$props = New-Object "System.Collections.Generic.Dictionary[[Autodesk.Connectivity.WebServices.PropDef],[System.Object]]"

$author = $propDefs | Where-Object{$_.DispName -eq "Author"}

$props.Add($author[0], "admin")
$vaultExplorerUtil.UpdateFileProperties($file,$props)

 

When this works, you will have to check your code and understand what might be causing the issue. Let me know if it helps!

 

Wangdu

coolOrange

0 Likes
Message 19 of 20

cassidy_ng
Contributor
Contributor

Hi 

 

I managed to get this to work but I had to create a separate function for VDS which passes in an additional parameter vaultExplorerUtil variable instead of using LoadExplorerUtil.  Ideally I would like to use the same function normally and VDS but this is sufficient for my requirements.

 

Regards,

Cassidy

0 Likes
Message 20 of 20

bertha.rios
Participant
Participant

Hi, I am reading this post now. Could you please explain how did you add file using $vaultConnection.FileManager.AddFile, I have problems to obtain  $vaultConnection. 

0 Likes