Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Improving Code for Groups Sync

68 views
Skip to first unread message

BliZzArD182

unread,
Feb 23, 2010, 1:03:44 PM2/23/10
to
Hi

I am trying to make a sync between some MSAD groups and Domino groups.
I dont need to create the groups in Domino when they are created in
MSAD, just keep them in sync.

At this point I am using an LDAP connector in Iterator mode, and then
a use a Domino agent which I call from another Notes connector in
passive mode, to add the user. This is working fine, however I need to
handle the event where a user is deleted from the group.

1) One idea might be to retrieve all the users, make a list, and then
replace the field in the group
2) Somehow know when a user is deleted and remove that user from that
group.

Problems

1) I have no idea how to save the users in a temporary Vector while I
iterate (losing the previous username. I was thinking on using a
temporal CSV file)
2) I am guessing something around the Delta feature, but I have to
check that out.

If anyone knows the best way of doing this, I'd be grateful to know.

Thank you

BliZzArD182

unread,
Feb 23, 2010, 2:55:44 PM2/23/10
to

Ok, got it.

I used this to keep all the values on memory:

var v = new Vector()
v = java.lang.System.getProperties().get("groupList")

And then sent the values to an agent in Domino, that replaces the
values in the members field in the group document.
Working great.

Eddie Hartman

unread,
Feb 24, 2010, 5:09:38 AM2/24/10
to
If I need a searchable collection that is guaranteed
to have no duplicates then I use a HashMap:
----
hsh = new java.util.HashMap();
keyAttribute = "Nickname"; // attr in the input file

file = system.getConnector("ibmdi.FileSystem");
csv = system.getParser("ibmdi.CSV");
file.setParser(csv);
file.setParam("filePath","TDIForumUsers.csv");

file.initialize(null);
file.selectEntries();

while ((e = file.getNextEntry()) != null) {
uid=e.getString("UID");
if (uid == null)
task.logmsg("ERROR", "No UID found for: " + e)
else
hsh.set(uid, e);
}
----

Now I can do hsh.get("BliZzArD182") to find you :)

-Eddie

Message has been deleted

Eddie Hartman

unread,
Feb 24, 2010, 5:12:18 AM2/24/10
to
Also a quick quez: are you using an agent in Domino
instead of doing the writes from TDI because it's
easier? If so, please elaborate - I'd love to learn
more about how TDI+Domino agents can help
make users more productive!

-Eddie

BliZzArD182

unread,
Feb 24, 2010, 7:48:42 AM2/24/10
to

Actually I found that I can call Domino agents and I am doing that.
For some strange reason my brain was set to 'TDI = Users replication'.
And since I had to use some agent in the Domino server and call it, I
just added a couple more. I also needed a couple of Script Libraries
which extend the NotesAdministrationProcess class in terms of group
manipulation (Example, RemoveFromGroup).

So I am using a AD LDAP as iterator with three hooks:

Before Initialize hook:

importPackage(Packages.java.util);
var lista = new Vector()
java.lang.System.getProperties().put("groupList", lista)

On Success hook:

importPackage(Packages.java.util);


var v = new Vector()

task.logmsg("Obteniendo vector")


v = java.lang.System.getProperties().get("groupList")

task.logmsg("Agregando " + work.cn+"/TDI")
v.addElement(work.cn+"/TDI")
java.lang.System.getProperties().put("groupList",v)

On close:

importPackage(Packages.java.util);


var v = new Vector()
v = java.lang.System.getProperties().get("groupList")

for (i=0;i<v.size();i++){
task.logmsg( v[i] )
}
NotesThread.sinitThread();
var ses = NotesConn.getConnector().getDominoSession();
var db = ses.getDatabase("Domino/TDI","database.nsf",false);
var paramid = new String
var group = "Invitados" //Group I want to replicate
var user = v
//Set agent of the db
var agent = db.getAgent("groupagent")
//Create parameters doc
var doc = db.createDocument()
//Add values to doc to send to Domino
var item = doc.appendItemValue("user", user)
var item = doc.appendItemValue("group", group)
//Save the document
doc.save(true, false)
paramid$ = doc.getNoteID()
//Send the agent the NoteID of the doc to process
var result = agent.runOnServer(paramid$)
//Removes the doc from the db
// doc.remove(true)
NotesThread.stermThread();

And the actual code in the agent:

Sub Initialize

on Error GoTo errhandler

Dim ses As New NotesSession
Dim db As NotesDatabase
Dim agent As NotesAgent
Dim doc As NotesDocument
Dim item As NotesItem
Dim NoteId As String
Dim result As Boolean
Dim users As String
Dim group As String

' Get the current agent and the parameter associated with it
Set db = ses.CurrentDatabase

db.delayupdates = False

Set agent = ses.CurrentAgent

NoteId = agent.ParameterDocID
' Get the parameter document
Set doc = db.GetdocumentbyId(NoteId$)

Set item = doc.GetFirstItem("user")
users = item.Text
Set item = doc.GetFirstItem("group")
group$ = item.Text

'Replacing group

Dim db2 As NotesDatabase
Set db2 = ses.getDatabase("Domino/TDI","names.nsf",False)

Dim view2 As NotesView
Set view2 = db2.getView("($VIMGroups)")

Dim doc2 As NotesDocument
Set doc2 = view2.getDocumentByKey( group , True )

Call doc2.Replaceitemvalue("members", users)
Call doc2.Save(true, true)


Terminate:

Exit Sub
errhandler:
MsgBox Err & " at line " & Erl & ": " & Error$
End

End sub


------------------------------------------

You actually dont need to run the runOnServer method always. It
depends if the code you need to run is a Server method or if t can run
in the client. The difference is just the call when you assign the
database. But if you have to send data to an agent, that is the way I
know.

Eddie Hartman

unread,
Feb 25, 2010, 6:01:35 AM2/25/10
to
Awesome!! Thanks for sharing that!

Coupla notes (of course :) in that you do not
need to import packages since any jars that TDI
knows about will be available. Manual import is
only necessary if you are dynamically loading your
own .jars.

Sure you can read and write to Domino Group
docs/objects just as you can to anything in an nsf.
However your method will probably be a easier
approach to Lotus scripting experts.

Thanks again!!

Also, don't forget to add some error handling. If
you look at the Flow Diagrams here:
http://publib.boulder.ibm.com/infocenter/tivihelp/v2r1/topic/com.ibm.IBMDI.doc_7.0/TDI_7.0_FlowDiagrams.pdf
You'll see how this works. Any exception is "thrown"
out to the "Error Flow" in the TDI workflows. This
Error Flow first executes the mode-specific Error
Hook (e.g. AddOnly Error) and then on to the
Default Error Hook. Here you want to write out
enough information to be able to deal with the issue:
--- e.g. for a failed add
task.logmsg("ERROR", "Error during add for"
+thisConnector.getName());
task.dumpEntry(error);
if (typeof(conn) != "undefined" && conn != null) {
task.logmsg("ERROR", "-- CONN Entry --");
task.dumpEntry(conn);
}
task.logmsg("ERROR", "-- WORK Entry --");
task.dumpEntry(work);
----
The error Entry holds attributes like "message" and
"operation", so you don't always need to write out
this yourself, along with the component name as above.

Note that if either of the Error Hooks are enabled then
the error is "swallowed" and execution continues to the
next component. So if you don't want this to happen and
for example you want processing to go back to the Feed
then you have to do system.exitFlow() or similar yourself.

If this error is too serious to continue with then you
should throw it again:

throw error.getObject("exception");

then the AL catches it and stops with the all-too-familiar
stack dump :)

-Eddie

Eddie Hartman

unread,
Feb 25, 2010, 6:21:25 AM2/25/10
to
For those who want to know more about how
the Error Flow in TDI works:

http://www.tdi-users.org/twiki/pub/Integrator/HowTo/HowTo_HandleErrors.pdf

-Eddie

BliZzArD182

unread,
Feb 25, 2010, 5:18:42 PM2/25/10
to
On 25 feb, 08:21, Eddie Hartman <eddiehart...@gmail.com> wrote:
> For those who want to know more about how
> the Error Flow in TDI works:
>
> http://www.tdi-users.org/twiki/pub/Integrator/HowTo/HowTo_HandleError...
>
> -Eddie

Thank you very much! I'll look into those.

So far I am only enabling the default on error hook and either making
a task.logmsg(work) or leaving it empty, so the AL keeps going.

0 new messages