Synchronization editor problem: mapping property with script retrieve object

Hi all,

I'm synchronizing a csv with the department objects

in my csv file I had a code for department manager that is equal to a code in field CustomProperty01 on Person object.

With the property "Key resolution by reference" I can insert the UID_Person in UID_PersonHead on Department object but...

If Person has a UID_PersonMasterIdentity is not empty I need to insert in UID_PersonHead of Department that UID.

So if a Person as a masteridentity attached to it I need to insert that person as department Manager.

I don't know how to do it in Synch Editor I thinkg with a script property but I can't figure out how.

 

Thanks 

Mik

Parents
  • Hi Michele,

    as you have assumed, you need to define a Script property to achieve your goal.

    In the script you have access to the properties of the current object, the current value when the sync engine tries to set a property and you can query for other objects the connector has access to, defined by your current schema definition (we come to that in a second).

    The sync engine itself, and therefore the scripted property has no direct access to the OneIM database, the object layer or the script library.

    Having explained that, here is your solution:

    • You need to define script property on the OneIM (the left) side of the mapping in the Department objects. In my sample, it is called vrtPersonHead. 
    • As in your use-case definition, we only need a write script.
    • Script code is the following:
    Imports VI.Projector.Connection

    Dim Person As ISystemObject = SystemObject.Connection.QueryObject(SystemQuery _
    .From("Person") _
    .Select("UID_PersonHead", "UID_PersonMasterIdentity") _
    .Filter(String.Format("CustomProperty01='{0}'", value.ToString))
    ).Result.FirstOrDefault

    If Not Person Is Nothing Then
    If String.IsNullOrEmpty(Person.GetValue("UID_PersonMasterIdentity").AsString) Then
    $UID_PersonHead$ := Person.GetValue("UID_PersonHead").AsString
    Else
    $UID_PersonHead$ := Person.GetValue("UID_PersonMasterIdentity").AsString
    End If
    End If
    • You need a mapping from your CSV column that stores the Manager lookup value to the new script property. In my sample, this is the mapping column CustomProperty01 in my CSV file to the script property vrtPersonHead.

    • You need to pin the Person objects in your schema, as the connector is only able to access objects that are part of your sync project schema. So when you shrink the schema, you need to exclude the Person table from the shrink, when it isn't a part of your sync project already.

    The script demonstrates the use of:

    • How to query data from other objects that are part of your sync project.
    • How to set another property in your object (:= notation) in a write script
    • How to us the current value in a write script.

    Hope that helps.

Reply
  • Hi Michele,

    as you have assumed, you need to define a Script property to achieve your goal.

    In the script you have access to the properties of the current object, the current value when the sync engine tries to set a property and you can query for other objects the connector has access to, defined by your current schema definition (we come to that in a second).

    The sync engine itself, and therefore the scripted property has no direct access to the OneIM database, the object layer or the script library.

    Having explained that, here is your solution:

    • You need to define script property on the OneIM (the left) side of the mapping in the Department objects. In my sample, it is called vrtPersonHead. 
    • As in your use-case definition, we only need a write script.
    • Script code is the following:
    Imports VI.Projector.Connection

    Dim Person As ISystemObject = SystemObject.Connection.QueryObject(SystemQuery _
    .From("Person") _
    .Select("UID_PersonHead", "UID_PersonMasterIdentity") _
    .Filter(String.Format("CustomProperty01='{0}'", value.ToString))
    ).Result.FirstOrDefault

    If Not Person Is Nothing Then
    If String.IsNullOrEmpty(Person.GetValue("UID_PersonMasterIdentity").AsString) Then
    $UID_PersonHead$ := Person.GetValue("UID_PersonHead").AsString
    Else
    $UID_PersonHead$ := Person.GetValue("UID_PersonMasterIdentity").AsString
    End If
    End If
    • You need a mapping from your CSV column that stores the Manager lookup value to the new script property. In my sample, this is the mapping column CustomProperty01 in my CSV file to the script property vrtPersonHead.

    • You need to pin the Person objects in your schema, as the connector is only able to access objects that are part of your sync project schema. So when you shrink the schema, you need to exclude the Person table from the shrink, when it isn't a part of your sync project already.

    The script demonstrates the use of:

    • How to query data from other objects that are part of your sync project.
    • How to set another property in your object (:= notation) in a write script
    • How to us the current value in a write script.

    Hope that helps.

Children
  • Hello Markus
    I'm trying to use the this script for a similar use-case. (Identity Manager v. 8.0.3)
    Our department tree is duplicated for internal and external use and distinguishable by a custom boolean attribute "Department.CCC_IsExternal". 
    So when adding a person to a department, I need match Person.IsExternal with Department.CCC_IsExternal. But it's not working. The script never finds the corresponding department matching to the ObjectID from the CSV file.

    Is there something wrong with my script?

     

    Imports VI.Projector.Connection
    
    Dim Department As ISystemObject = SystemObject.Connection.QueryObject(SystemQuery _
     .From("Department") _
     .Select("UID_Department") _
     .Filter(String.Format("ObjectID = '{0}' AND CCC_IsExternal = {1}", value.ToString, $IsExternal:Int$))
     ).Result.FirstOrDefault
    
    Dim UID_Department As String = Department.GetValue("UID_Department").AsString
    
    If Not Department Is Nothing Then
    	If String.IsNullOrEmpty(UID_Department) Then
    		$UID_Department$ := UID_Department
    	End If
    End If

    Thanks and best regards

    Dominic

  • How does your mapping look like?

    Did you pin the Department table in the schema on the Identity Manager side as Person seems to be your base object for the synchronization?

    Did you check the generated SQL in the trace log of a test synchronization in the Synchronization Editor?

  • Hi Markus
    Never mindfound out that an issue in the scope definition caused the problem.

    Thanks anyway!

  • Hello Markus

    You wrote: "...and you can query for other objects the connector has access to...."

    Can you explain further what happens when calling queryobject?

    Does it translate the call to an Iqueryable call to the oneImConnector and retrieve just in time the data over the  OneIM-Connector/objectlayer from the 1IM Database while applying at the same time the constraints definied in the scope and schema within the synchronization editor?

    Or is the Data being defined in the  Schema/Scope within the synchronization editor preloaded / cached. And the queryobject accesses  that data?

    Or is it a mix of both?

    I kinda think this is important to know if somebody want to ensure good performance for a synchronzation.

    Thank you in advance!

  • Does it translate the call to an Iqueryable call to the oneImConnector and retrieve just in time the data over the  OneIM-Connector/objectlayer from the 1IM Database while applying at the same time the constraints definied in the scope and schema within the synchronization editor?

    It uses the OneIMConnector to retrieve the data and all Synchronization Project settings apply and not the object layer alone. That's the reason why you have to pin the object type you are using in the schema.

  • Hello Markus,

    Would it be possible to retrieve all the UNSGroupB (Groups) that a single UNSAccountB (User) belong to using the script property?

    I'm trying to query multiple data that exist in the UNSAccountBInUNSGroupB.

    Best regards

  • I am not fully understanding your use case, but the SystemObject.Connection.QueryObject returns more than one object by default. That's why there is the FirstOrDefault part of the code in this thread.