What is a Method?
A method is an object in the docbase that lets you launch a program on the server without being logged into the server. Instead, you issue a DQL or API command from inside a Documentum client, and Documentum will launch the program for you. You can even pass the program arguments and get a return code back.
Why Would I Use One?
There are two main reasons to use server-side methods: to allow normal users to execute a command that only a superuser can execute, and to off load processor-intensive tasks from the client to the server.
Running Methods as Superuser
Because Documentum allows you to run a method as dmadmin (a super user), you can write programs that log into the docbase as dmadmin and execute commands that are reserved for super users.
For example, in Documentum, only super users can unlock a document that is checked out by someone else. Suppose that your business rules state that is a manager has the authority to unlock documents as well. You don’t want to give the manager superuser privileges, so instead you create a server-side method that runs as superuser, logs into the docbase as dmadmin, unlocks the document, and logs out. You could add a menu item to workspace for the manager, and when he selects it, you call the method and pass it the object id of the selected document.
Offloading Tasks to the Server
Sometimes there are programs that a user needs to execute that are inappropriate for them to run on their client machines. The program might take hours to complete, or it might only run on UNIX machine (while your users have Windows machines). These are both good reasons to use a server-side method.
What do the Different Options Mean?
A dm_method object has lots of attributes that affect how the object behaves.
launch_async Indicates whether the procedure is to run asynchronously or not.method_typeThis is used when the program is stored as content for the method. If set to GAWK or dmbasic, directs the server to add -f in front of the file name and to pass all arguments specified on the DO_METHOD command line to the program.method_verbCommand-line name of the program to execute.run_as_serverIndicates if you want the method to run as the server account.use_method_contentIndicates whether the program that you want to run is stored as content in the method object or as an external file.
How do I Create a Method?
The best way to create a method is using a script or procedure. This way, you can create the method exactly the same way on your development docbase, your test docbase, and your production docbase. I have written a procedure that I use anytime I need a new method. All the important variables are defined at the top of the Main() subroutine. It’s easy to change the variables to suit this method’s purpose. Then you just execute the procedure in Workspace to create the method. The source code for the method-creating procedure is located here.
Using Trusted Logon
Now that you have created your method object, you must write the server-side program that gets called by the method. You will probably want this program to connect to the docbase and issue several APIs and queries in order to accomplish its task. But how do you connect to the docbase without hard-coding a password in the connect API? The solution is to use Trusted Logon.
In certain circumstances, you can log into the docbase without specifying a password. There are two requirements to be able to do this:
- You must already be logged into the physical server
- You can only log into the docbase as the user that is logged into the server
The idea here is that in order to log into the server, you had to type your password, right? So why does Documentum need to ask you for it again? When you issue the connect API you can leave the password argument blank and Documentum will connect you anyway. You can try this out using IAPI or IDQL – just log into the docbase, but when it asks you for a password, hit return.
When you create a server method and set the run_as_server attribute = TRUE, Documentum will launch the method so that the process is owned by dmadmin (or whatever your installation server is named). In your code, you can connect to the docbase by issuing the connect API without a password, like this:
strSession = dmAPIGet("connect," & strDocbasename & ",dmadmin,")
You leave the password argument blank, and it will connect to the docbase anyway.
You can avoid hard-coding the installation owner’s userid by querying the apiconfig
object. This is a non-persistent object that knows about the particular details of the session that you are running. One of its attributes is r_process_user_name
, which will tell you the user id that owns the currently running process. You access the attribute like this:
strUserOSName = dmAPIGet("get,apisession,apiconfig,r_process_user_name")
And then use that variable when connecting to the docbase, like this:
strSession = dmAPIGet("connect," & strDocbasename & "," & strUserOSName & ",")
Note: Thanks to Aaron Webber for the apiconfig hint.
Using Method Content
Documentum Methods can execute programs that live on the filesytem (complied executables), or scripts that live inside the docbase. When executing a script inside the docbase, you attach the script as content of the method object itself.
A good example of why you would use method content is if you are writing your program to run in server-side Docbasic. This is a very common practice. Rather than storing the script on the server filesystem, you can keep it inside the docbase. When the method gets executed, Documentum will export the script to a temporary location on the server, execute it, and then delete it.
How do I Set it Up?
To execute a method using method content, you must set some attributes. You should set the use_method_content attribute of the dm_method object = TRUE. You must also set the method_verb attribute to point to the interpreter for your script (i.e. Perl or Docbasic).
Of course, in order to execute the content of a method, you must attach your script to the method object. Unfortunately, this is not as easy as it sounds because Workspace does not permit you to add content to a method.You must do this using the Documentum API.
If you have completed the script and know that it works, you may wish to add it as the method’s content when you create the method. My sample method-creating procedure will allow you to do this.
If you have already created your method and need to add a file as the content of that method, you will need to use the Documentum setfile
API. You can enter into the Message Tester in Workspace to do this. In this example, the method is named foo and the script is located at C:foo.txt. We assume that the script file is a DOS ascii text file.
retrieve,c,dm_method where object_name = 'foo'
setfile,c,l,c:foo.text,crtext
save,c,l
How do I Call My Method?
There are two ways to execute a method: using DQL and using the API. We will discuss both, but since most of the time you will be executing the server method from some piece of client-side code, it makes sense to discuss the API method first.
Using the Apply API
The apply method is used to execute server-side programs. It can be used to execute several pre-defined Documentum utilities, or it can execute a dm_method object that you have created yourself. The apply method lets you specify the name of the method you are executing, pass that method some arguments, and specify some settings as to how the method should run (asynchronously, as server, etc.) When specifying any arguments to the method, you must also specify the data type of the argument. For example, if the method expects an object ID as an argument, you must specify that the argument is a string.
The apply method returns a query collection object that contains a result set. The syntax of the apply method is a bit tricky, so lets go over it.
The reason that it’s tricky is that you have to jump through some hoops in order pass an argument to the meathod. You have to tell the name of the argument, the datatype of the argument and the value of the argument.
dmAPIGet("apply,session,object_id,function_name,argument,datatype,value")
object_idThe object_id argument is not used when executing a method. Use NULL
instead.function_nameUse DO_METHOD
to specify that you are executing a method.argumentThere are several arguments you can pass to the method. Use METHOD
to specify that you are about to give the name of the method. Use ARGUMENTS
to specify that you are about to give the arguments to the method.datatypeUse S
to specify that the argument you are passing is a string.valueThis is where you specify the value of the argument. Here you give the name of the dm_method you are executing or the other arguments you are passing to the method.You can repeat argument/datatype/value in order to specify other arguments.
In the following example, the name of the method is update_legacy
. We need to pass it an argument – in this case, the r_object_id of an object in the docbase.
strCollectionID = dmAPIGet("apply,s0,NULL,DO_METHOD,METHOD,
S,update_legacy,ARGUMENTS,S,090000837000214b")
Using DQL
You may also use DQL to execute a method. I usually only do this during testing so that I can see the result set in a Workspace window. The DQL command needed to execute a method is named EXECUTE, and its syntax is similar to using the Apply API.
EXECUTE function_name [[FOR] object_id] [WITH argument = value {,argument = value}]
function_nameUse DO_METHOD
to specify that you are executing a method.object_idThe object_id argument is not used when executing a method. Leave this blank.argumentThere are several arguments you can pass to the method. Use METHOD
to specify that you are about to give the name of the method. Use ARGUMENTS
to specify that you are about to give the arguments to the method.valueThis is where you specify the value of the argument. Here you give the name of the dm_method you are executing or the other arguments you are passing to the method.Here’s the same example using the DQL syntax.
EXECUTE do_method WITH method = 'update_legacy', arguments = '090000837000214b'
Getting a Return Code and Passing Back Meaningful Results
When your client-side program executes a method, it is often necessary to find out if that method completed successfully, and if it did not, return some meaningful error message to the user. Documentum supports this requirement by returning a result set of information about the method’s execution. This result set is made up of several columns.
Note: You must run the method synchronously in order to get a meaningful result set.
Return Code
If your method returns a return code, Documentum can capture that return code and you can find out what it was. A return code specified in this way is available in the result set’s Return Code column. This allows your client code to know exactly what the result of the server method was and take an appropriate action. For example, if the server method returns 104, the client code that called the method might know that 104 means that the method could not find the necessary disk space on the server to complete its task. The client could then present an error message to the user asking them to notify a system administrator.
Note: Docbasic provides a command called dmexit
which allows you to specify a return code in a Docbasic program.
Result ID
If the save_results attribute is set on the dm_method object, Documentum will spool any error messages generated by the server method to a special log file. When the method completes, it will automatically load this file into the Temp Cabinet in the docbase. This allows a user to look in the file for a detailed description of what took place during the method execution. The object id of this result document is returned in the result_id
column in case the client app wants to display it or route it.
Tips and Tricks
- When debugging a server method, it is useful to print out debugging statements. The easiest way to do this is to send output to standard out. If you are writing your method in server-side docbasic, use the
Print
command to print a message to standard out. These statements will be captured in the docbase server log files. Note: If the save_results attribute is set on the method object, these statements will not appear in the log file – they will be captured in a file and imported into the temp cabinet. - I often write server-side methods in Docbasic. Since Workspace’s Docpage Builder provides a reasonably decent Docbasic Editor and Syntax Editor, I create and test my scripts as dm_procedure objects stored in the Docbase. This allows me to version the scripts as I make changes (you can not version a dm_method). When I feel my script is ready to be tested as a server method, I use the bindfile API to attach the content of the dm_procedure object to the dm_method object.