The Property Compliance feature has some aspects that may affect your programs.
Background:
Vault has a special property called Property Compliance, which tells if your file has broken any property compliance rules. This is very useful for things like life cycle state transitions, where you don’t want files to move to the Released state unless all the properties are compliant.
The problem:
The Property Compliance value is calculated by the Vault server asynchronously. So if you write a program that updates some properties then immediately moves the file to Released, you will likely run into error 1092 with a restriction code of 5003, which means that the properties are not compliant.
The error is a bit misleading. The properties may be compliant, but the Vault sever hasn’t calculated the Property Compliance value yet.
How to Fix:
Unfortunately there is no perfect solution. There is no API function that will force the compliance check. Here are some workarounds you can do, and you can decide which one fits best given your project requirements.
Solution #1: Halt your program until the Property Compliance value is set
If you application has UI, you can put up a wait cursor or something while waiting.
C# code:
| // a place to store the Property Compliance PropDef object private int COMPLIANCE_PENDING = 4; /// <summary> /// This function will halt the program until it detects that the compliance check has been completed /// </summary> /// <param name="fileId">The file to check compliance on</param> private void WaitForCompliance(long fileId) { if (m_propertyCompliancePropDef == null) { // find the "Property compliance" property Document.PropDef[] propDefs = docSvc.FindPropertyDefinitionsByPropertySetIdsPropIdsAndDataTypes( new string[] { "89562930-aa40-41d3-a671-132f42cb6ab6" }, new string[] { "Compliance" }, new string[] { "int" }); // save off this information once we find it // we don't want to keep looking this up m_propertyCompliancePropDef = propDefs[0]; } // if we are in a dialog, change the cursor to let the user know that we are waiting Cursor currentCursor = this.Cursor; this.Cursor = System.Windows.Forms.Cursors.WaitCursor; int propCompliance = COMPLIANCE_PENDING; while (propCompliance == COMPLIANCE_PENDING) { // read the property from the file Document.PropInst[] propInsts = docSvc.GetProperties(new long[] { fileId }, new long[] { m_propertyCompliancePropDef.Id }); if (propInsts != null && propInsts.Length == 1) propCompliance = (int)propInsts[0].Val; else break; // or throw an error error // wait 10 seconds if property compliance is pending if (propCompliance == COMPLIANCE_PENDING) System.Threading.Thread.Sleep(1000 * 10); // TODO: You might want to provide a way for the user to break out of this loop } // switch the cursor back to the original value this.Cursor = currentCursor; } |
VB.Net code:
| ' a place to store the Property Compliance PropDef object ' a value of 4 means that compliance is still pending Private COMPLIANCE_PENDING As Integer = 4 ''' <summary> ''' This function will halt the program until it detects that the compliance check has been completed ''' </summary> ''' <param name="fileId">The file to check compliance on</param> Private Sub WaitForCompliance(ByVal fileId As Long) If (m_propertyCompliancePropDef Is Nothing) Then ' find the "Property compliance" property Dim propDefs As Document.PropDef() = docSvc.FindPropertyDefinitionsByPropertySetIdsPropIdsAndDataTypes( _ New String() {"89562930-aa40-41d3-a671-132f42cb6ab6"}, _ New String() {"Compliance"}, _ New String() {"int"}) ' save off this information once we find it ' we don't want to keep looking this up m_propertyCompliancePropDef = propDefs(0) End If ' if we are in a dialog, change the cursor to let the user know that we are waiting Dim currentCursor As Cursor = Me.Cursor Me.Cursor = System.Windows.Forms.Cursors.WaitCursor Dim propCompliance As Integer = COMPLIANCE_PENDING While (propCompliance = COMPLIANCE_PENDING) ' read the property from the file Dim propInsts As Document.PropInst() = docSvc.GetProperties(New Long() {fileId}, _ New Long() {m_propertyCompliancePropDef.Id}) If (propInsts IsNot Nothing AndAlso propInsts.Length = 1) Then propCompliance = CType(propInsts(0).Val, Integer) Else Exit While ' or throw an error error End If ' wait 10 seconds if property compliance is pending If (propCompliance = COMPLIANCE_PENDING) Then System.Threading.Thread.Sleep(1000 * 10) End If ' TODO: You might want to provide a way for the user to break out of this loop End While ' switch the cursor back to the original value Me.Cursor = currentCursor End Sub |
Solution #2: Don’t use Property Compliance
Maybe you don’t need the Property Compliance feature. In that case you can just to the Administration dialog and edit the appropriate life cycle states so that Property Compliance is no longer a requirement of the transition.
Solution #3: Your program is the compliance check
Your program just set the properties, so you can be sure that those values are correct. You can also query any other properties to make sure that they are right too. If anything is not correct, your program can throw an error and not proceed with the state transition. In effect, what you have is a property compliance check in your own program instead of on the server side. So you can go ahead and remove the Property Compliance checks like in solution 2.
The drawback here is that it assumes this transition will always be going through your program. If that is what you want, you need a way to uphold this rule. I recommend creating a user specific to your application. Next set it so that the transition can only be done by the new user. Lastly you update your program so that it logs in as that user to do lifecycle transitions.

Subscribe