Tuesday, April 9, 2013

How to stop running job

A Documentum job consists of a dm_job object, containing job configuration, name of method to run, as well as process execution information. The job method is executed on the Content Server (if it's a java method - on the JMS). Once the job is started, there's no 'soft' approach to stop it, you can only force it.
Below are the steps to stop properly a running job, reseting also the dm_job object:
1. Get the process id, by running the DQL:
select a_last_process_id from dm_job where object_name='[JOB_NAME]'
2. Using Process Explorer (or similar tool) locate the process by id and kill it. (Or with a command like: taskkill /pid 1234)
3. Run the API command to unlock the job object:
unlock,c,[job_id]
4. Execute the following DQL queries to clear job execution-related attributes:
a) Reset application that uses/locked the job
update dm_job objects set a_special_app='' where object_name='[JOB_NAME]';
b) Reset current status
update dm_job object set a_current_status='FAILED' where object_name='[JOB_NAME]';
c) Prevent job from being run immediately
update dm_job object set run_now=FALSE where object_name='[JOB_NAME]';

Remember to change the schedule or inactivate the job if you don't want it to run automatically after specified period.
If your job is locked in running state, check here how to unlock it: How to unlock a job in running state.

Tuesday, April 2, 2013

Renaming users - how dm_UserRename job works

In a previous article How to change the user_name of a dm_user we've seen how to rename a Documentum user manually (using Documentum Administrator) and by DFC code.
Let's assume we want to update a set of users, but can't or don't want to write DFC code (it also requires some time to write and run the code). We have an additional option: have the dm_UserRename job rename the users automatically. But how does the dm_UserRename job work?
This job polls a queue: dm_job_request objects. The object has the following attributes which are relevant for the job:
object_name         : UserRename
job_name            : dm_UserRename
method_name         : dm_UserRename
request_completed   : F
arguments_keys   [0]: OldUserName
                 [1]: NewUserName
                 [2]: report_only
                 [3]: unlock_locked_obj
arguments_values [0]: userA

                 [1]: userB
                 [2]: F
                 [3]: F


The jobs read the arguments_keys & arguments_values values and calls the dm_UserRename method with these arguments, so the specified user is renamed with selected options (report_only mode, unlock objects or leave locked). When the operation completes, the request_completed attributed is set to TRUE.
Thus in order to rename a set of users, you need to create a dm_job_request object for each user and run the dm_UserRename job. Note that by default the dm_UserRename job is inactive, so you can either run it manually, or activate it and schedule if you often rename users.

Here's sample DQL to create a dm_job_request object (to rename 1 user):
create dm_job_request object set object_name='UserRename', set job_name='dm_UserRename', set method_name='dm_UserRename', set request_completed=FALSE, append arguments_keys='OldUserName', append arguments_keys='NewUserName', append arguments_keys='report_only', append arguments_keys='unlock_locked_obj', append arguments_values='userA', append arguments_values='userB', append arguments_values=FALSE, append arguments_values=FALSE

How to change the user_name of a dm_user

In a Documentum repository users are uniquely identified by the user_name attribute. Being a key, the user_name value is used in related objects (for example: owner, r_modifier, r_creator, r_lock_owner, etc.) stating that this user performed an action on this object.
In certain cases we need to change the user_name value: for example when we want to create a new user, but an old one (perhaps deactivated) already exists with the same user_name.
Being a key, we can't simply update this value, you won't even be able to modify it on user property screen. Here are the ways to accomplish this:

1. Manual renaming
There's a simple tool called Reassign User which invokes the dm_UserRename job (Renaming users - how dm_UserRename job works explains how this job works):
a. (Optional) Create a new user with the user_name you want to rename the old user to.
b. Open DA, go to Users node in browsertree, find the desired user, right click on it and choose Reassign User. On the opened page enter/select the new user, select the option to run the reassign job now (and change other settings if required).
c. (Optional) As soon as the dm_RenameUser job has completed, you can remove the original (old) user if it's not needed anymore.
Note that you can skip the creation of a new user and just enter the new user_name on the Reassign User page, it will handle the modification of user_name itself.

2. Automatic renaming
If we want to rename many users, the manual approach would be really annoying, so as usual we turn to some DFC coding.
Renaming users in DFC is quite straightforward, it's enough to call the rename method:
 IDfUser user = session.getUser("userA");
 user.renameUser("userB", true, false, true);
 user.save();


Here's the method description from the API:
void renameUser(String userName,
                boolean isImmediate,
                boolean unlockObjects,
                boolean reportOnly)
                throws DfException

    Renames this user. If this is a new user, the attribute value is set. If this is an existing user, this method invokes a job to rename user.
    Parameters:
        userName - user name to be set or renamed to (existing user)
        isImmediate - Detemines if the job should be run immediately or run on schedule.
        unlockObjects - control if the objects should be unlocked when renaming user. If this is a new user, this parameter does not take any effect.
        reportOnly - control if the job created is to report or actual rename. If this is a new user, this parameter does not take any effect.

How to register and unregister types for indexing

Documentum uses fulltext indexing to enable search on all document properties as well as its contents.  How does fulltext indexing work?
Indexing is performed by a dedicated server (FAST, xPlore, etc.) that polls the queue of the fulltext user. In order to index certain (sub)types of documents, you must register certain events of these types for index user. Thus when a registered event occurs on a document of the registered type, a queue item is created in the fulltext user's queue, which consequently is processed by the Fulltext indexing server, by indexing the document. The events to register are those that usually change the object metadata and/or content: dm_save,dm_readonlysave,dm_checkin,dm_move_content,dm_destroy

By default, (in previous versions of Documentum) all dm_sysobject types and its subtypes are registered for indexing. Usually you don't need all the dm_sysobject to be indexed, so before registering your custom types, you should unregister the dm_sysobject first. You can do that by running the following API script, being connected with the fulltext user (dm_fulltext_index_user):
(Note: if you don't know the password for dm_fulltext_index_user you can generate a login ticket by running following API with a superuser: getlogin,c,dm_fulltext_index_user Read more details about this trick in: How to login to the repository with a ticket).

API for unregistering indexing:
unregister,c,[TYPE_ID],dm_save,,F
unregister,c,[TYPE_ID],dm_readonlysave,,F
unregister,c,[TYPE_ID],dm_checkin,,F
unregister,c,[TYPE_ID],dm_move_content,,F
unregister,c,[TYPE_ID],dm_destroy,,F

[TYPE_ID] is the r_object_id of the dm_type object
Note: If you have more Index servers, you should have an index user for each, so run the unregister script for each user.

You can also do that by unchecking the 'Enable Indexing' checkbox on dm_sysobject type properties in DA.

You can register a custom type for indexing in 2 ways:
1. By executing the following API script, with the fulltext user (dm_fulltext_index_user):
register,c,[TYPE_ID],dm_save,,F
register,c,[TYPE_ID],dm_readonlysave,,F
register,c,[TYPE_ID],dm_checkin,,F
register,c,[TYPE_ID],dm_move_content,,F
register,c,[TYPE_ID],dm_destroy,,F


[TYPE_ID] is the r_object_id of the dm_type object
Note: If you have more Index servers, you should have an index user for each, so run the register script for each user.

2. Manually, by using DA: Open Types node in browsertree, find the desired type, open its properties and check the 'Enable Indexing' checkbox.

To check which types are currently registered for indexing, use the DQL:
select name from dm_type where r_object_id in (select distinct registered_id from dmi_registry where user_name='dm_fulltext_index_user')