Programmatically add direct assignment ADSAccountInADSGroup even as deferred operation

Hi all, Community

I am trying to programmatically set up some deferred operations in order to directly assign an ADSGroup to an AdsAccount. This should be done also for existing indirect assignments.

Usually, if I have to do it “runtime” (not deferred operation), I can execute from the script a sql query (mySQLExec.SqlExecuteNonQuery(“update ADSAccountInADSGroup set XOrigin = x where …. ”) ) but this cannot be done in a deferred operation block as it is executed immediately. In deferred operation block I need to base the updates I want to persist throughout the deferred operation to IsingleObject or Entity, but as I tried to update the field XOrign I keep on getting permission exceptions, no matter what I do.

So, can someone give me some ideas how to solve this problem? Maybe there is a better way than to directly querying the DB. Some method or else linked to ISingleDbObject or Entity …

Thank you in advance to anyone who can provide detail.

 

Alberto

Parents
  • Could you describe your use case in more detail? Why do you need to update the XOrigin flag directly? This flag is handled by the object layer and the DB queue processor and you shouldn't mess with it.

  • Hi Markus

    Thank you for interesting to my issue.

    We need to implement a sort of copy ADSAccount. We need to align the ADSAccountInADSGroup of two different accounts when, of course, it is possible. In case, we need to allow user to start this alignment as deferred operations.

    In particular, we have to handle the following case: donor ADSAccount has a direct assignment of a ADSGroup while recipient has not. My clients want me to assign that AdsGroup directly to the recipient too, this means that XOrigin increases, if I am not wrong, from 2 to 3.

    Usually, I handle this kind of requests with an SQLExecutor, by I cannot do that as deferred operation. When I try to use the deferred operation, I need to base the instruction on Entity or ISingleDbObject, but they do not let me modify the XOrigin.

    That’s it.

     

    Thank you in advance.

    Alberto

  • Thank you a lot.

    I read your old post but i was getting some error.. Probably it was unrelated. nyway now everything works like a charm! 

    a

  • Wait a minute...

    So if I want to assign an AD group to a user for only one (1) hour, this is the way to do it, or am I getting this wrong?

  • I think you are getting this wrong. this is the code to assign something (for example an ADSAccount to an ADSGroup) in the future. In my sample code, the assignment will be run 45 days from now.

  • Markus

    I am sorry to bother you again with this issue but after a couple of successful tests, it start again the give me the same error of yesterday:

     

    One or more errors occurred.

    Error flushing changes to database.

    Error during execution of statement: insert into ADSAccountInADSGroup (UID_ADSAccount, UID_ADSGroup, XOrigin, xdateinserted, xuserinserted, xdateupdated, xuserupdated, xobjectkey) values ('f7fc38e8-ecb3-4ab1-a567-89aaf19a45fb', 'cccc6aee-0bfa-4619-8a63-0eb00f0b3d2f', 1, GetUTCDate(), N's2e-alberto', GetUTCDate(), N's2e-alberto', '<Key><T>ADSAccountInADSGroup</T><P>f7fc38e8-ecb3-4ab1-a567-89aaf19a45fb</P><P>cccc6aee-0bfa-4619-8a63-0eb00f0b3d2f</P></Key>')

    Database error 2627: Violation of PRIMARY KEY constraint 'PK__ADSAccou__51A5CB301C738950'. Cannot insert duplicate key in object 'dbo.ADSAccountInADSGroup'. The duplicate key value is (f7fc38e8-ecb3-4ab1-a567-89aaf19a45fb, cccc6aee-0bfa-4619-8a63-0eb00f0b3d2f).

    The statement has been terminated.

    Violation of PRIMARY KEY constraint 'PK__ADSAccou__51A5CB301C738950'. Cannot insert duplicate key in object 'dbo.ADSAccountInADSGroup'. The duplicate key value is (f7fc38e8-ecb3-4ab1-a567-89aaf19a45fb, cccc6aee-0bfa-4619-8a63-0eb00f0b3d2f).

    The statement has been terminated.

     

    Again, I am trying to add a direct assignment to an existing indirect assignment. I am using the following code:

    Dim recordToAddEntity As IEntity = Me.Connection.Session.Source.CreateNew("ADSAccountInADSGroup", EntityCreationType.Default)

    recordToAddEntity.PutValue("UID_ADSAccount", Me.Recipient_ADSAccount.UID_ADSAccount)

    recordToAddEntity.PutValue("UID_ADSGroup", uid_group)

    Using uow = Me.Connection.Session.StartUnitOfWork()

                   uow.Put(recordToAddEntity)

                   uow.Commit()

    End Using

     

    Where am I wrong or why does this code works only sometimes (even with there is an indirect assignment) ?

     

    Thank you

    A

  • After a second thought, the Object Layer does the translation from a Delete of direct memberships into an update of XOrigin, if XOrigin is 3 (for example).

    I'll check the insert case and keep you updated.

  • Yes Markus,

    the delete behavior is pretty clear as I have a lot of experience in deleting assignments Blush

    On the contrary I was quite surprised that, in order to “increase” the XOrigin, it was enough to create an entity or an ISingleDbObject and save it, as in the last couple of years, every time I was asked to implement such feature, I had to deal with SqlExecutor. But this time, I couldn’t have it working because of the deferred operation.

    Anyway, I really look forward to read your suggestions

     

    A

  • So here is the correct solution. To create a direct assignment for an existing membership, you can call the AssignDirect method.

    I've updated my sample code (using your variables) to reflect this change.

    Public Sub CCC_AssignDirect(UID_ADSAccount As String, uid_group As String)
             ' Create a new DeferredBlock for a point in time.
             Using New VI.DB.DeferredOperations.DeferredBlock(Session, DateTime.UtcNow.AddDays(45), "Optional description for operation")
             ' Operations done here are done deferred
    
                      Using uow = Session.StartUnitOfWork()
                               Dim dbEntity As IEntity = Nothing
                               Dim dbKey As DbObjectKey = New DbObjectKey(Table.ADSAccountInADSGroup, New String() {UID_ADSAccount, uid_group})
                               ' Check if memberships already exists
    
                               If Session.Source().TryGet(dbKey, EntityLoadType.Default, dbEntity) Then
                                        'if exists call AssignDirect method
                                        dbEntity.CallMethod("AssignDirect")
                               Else
                                        'if not exists create new membershio
                                        dbEntity = Session.Source().CreateNew(Table.ADSAccountInADSGroup)
                                        dbEntity.PutValue(Table.ADSAccountInADSGroup.UID_ADSAccount, UID_ADSAccount)
                                        dbEntity.PutValue(Table.ADSAccountInADSGroup.UID_ADSGroup, uid_group)
                               End If
                               uow.Put(dbEntity)
                               uow.Commit()
                      End Using
             End Using
    End Sub

  • Markus,

    I tested your solution several times and it seems to be perfect.

    I didn’t know about the existence of the method “AssignDirect”, and of course it made the magic!

    Thank you again

    Alberto

     

    Just one more think, even if it is not so important. In this case, why to incapsulate the instruction in a using uow while it should be the same than calling entity.Save(Session)?

     

  • In this case (single operation), it is just my coding style. Using an entity.Save(Session) would be sufficient as well.

Reply Children
No Data