Marginalia

Execute job immediately

apply,c,,DO_METHOD,
  METHOD,S,agent_exec_method,
  ARGUMENTS,S,'
    -docbase_name <docbase name>.<server name> 
    -docbase_owner <docbase owner name> 
    -job_id <dm_job r_object_id>  
    -log_directory <full path to dba/log directory> 
    -docbase_id <docbase_id, see server.ini> 
    -trace_level <trace level from 0 to 10>
  '

or SQL generator:

SELECT    'apply,c,,DO_METHOD,METHOD,S,agent_exec_method,'
       || 'ARGUMENTS,S,''-docbase_name '
       || dc.object_name
       || '.'
       || sc.object_name
       || ' -docbase_owner '
       || sc.r_install_owner
       || ' -job_id '
       || j.r_object_id
       || ' -log_directory '
       || (SELECT file_system_path
             FROM dm_location_sp
            WHERE object_name = 'log')
       || ' -docbase_id '
       || dc.r_docbase_id
       || ' -trace_level 0'''
  FROM dm_job_sp j, dm_server_config_sp sc, dm_docbase_config_sp dc
 WHERE     j.object_name = '<job name>'
       AND sc.object_name = '<server name>'
       AND dc.i_has_folder = 1
       AND dc.i_is_deleted = 0
       AND sc.i_has_folder = 1
       AND sc.i_is_deleted = 0

Database locks

SELECT r_object_id,
   blocked_sid,
   blocked_sql_text,
   blocking_sid,
   last_sql_text
  FROM (SELECT s.sid AS blocked_sid,
     s.serial# AS blocked_serial#,
     s.username AS blocker_username,
     s.module AS blocked_module,
     DBMS_ROWID.rowid_create (1,
          (SELECT data_object_id
             FROM dba_objects
            WHERE object_id = s.row_wait_obj#),
          s.row_wait_file#,
          s.row_wait_block#,
          s.row_wait_row#)
      AS blocked_rowid,
     s.sql_hash_value AS blocked_has_value,
     s.sql_address AS blocked_sql_address,
     sq.sql_text AS blocked_sql_text,
     o.sid AS blocking_sid,
     os.sql_text AS last_sql_text
    FROM v$session_wait sw,
     v$session s,
     v$sql sq,
     v$lock l,
     v$session o,
     v$sql os
   WHERE   1 = 1
     AND sw.event = 'enq: TX - row lock contention'
     AND sw.sid = s.sid
     AND l.TYPE = 'TX'
     AND l.request = 6
     AND l.sid = s.sid
     AND s.sql_hash_value = sq.hash_value
     AND s.sql_address = sq.address
     AND s.blocking_session = o.sid
     AND os.sql_id = NVL (o.sql_id, o.prev_sql_id)) locks,
   dm_sysobject_s ot
 WHERE ot.ROWID = locks.blocked_rowid;

Refresh JMS config list

apply,c,,REFRESH_JMS_CONFIG_LIST

Why does user have certain object permissions

WITH usr
     AS (SELECT 'user' AS source,
                user_name AS accessor,
                user_name AS user_name
           FROM dm_user_s
         UNION
         SELECT 'dm_world' AS source,
                'dm_world' AS accessor,
                user_name AS user_name
           FROM dm_user_s
         UNION
         SELECT 'superuser' AS source,
                'dm_owner' AS accessor,
                user_name AS user_name
           FROM dm_user_s
          WHERE BITAND (user_privileges, 16) = 16
         UNION
         SELECT 'docbase owner' AS source,
                'dm_owner' AS accessor,
                user_name AS user_name
           FROM dm_user_s
          WHERE LOWER (USER) = LOWER (user_name)
         UNION
         SELECT 'primary group' AS source,
                user_group_name AS accessor,
                user_name AS user_name
           FROM dm_user_s
         UNION
         SELECT DISTINCT
                'group' AS source,
                gr2.i_supergroups_names AS accessor,
                gr1.users_names AS user_name
           FROM dm_group_r gr1, dm_group_r gr2
          WHERE     gr1.r_object_id = gr2.r_object_id
                AND gr1.users_names IS NOT NULL
                AND gr2.i_supergroups_names != ' ')
SELECT usr.user_name AS user_name,
       usr.accessor,
       source,
       DECODE (
          dm_acl_r.r_accessor_name,
          'dm_owner', GREATEST (r_accessor_permit, sys_s.owner_permit, 3),
          DECODE (
             usr.accessor,
             'dm_browse_all', GREATEST (NVL (r_accessor_permit, 1), 2),
             'dm_read_all', GREATEST (NVL (r_accessor_permit, 1), 3),
             'dm_escalated_read', GREATEST (NVL (r_accessor_permit, 1), 3),
             'dm_escalated_relate', GREATEST (NVL (r_accessor_permit, 1), 4),
             'dm_escalated_version', GREATEST (NVL (r_accessor_permit, 1), 5),
             'dm_escalated_write', GREATEST (NVL (r_accessor_permit, 1), 6),
             'dm_escalated_full_control', GREATEST (NVL (r_accessor_permit, 1), 7),
             r_accessor_permit))
          r_accessor_permit,
       dm_acl_r.r_accessor_name AS acl_record
  FROM dm_sysobject_s sys_s
       INNER JOIN dm_acl_s
          ON (sys_s.acl_name = dm_acl_s.object_name
              AND sys_s.acl_domain = dm_acl_s.owner_name)
       INNER JOIN dm_acl_r
          ON (dm_acl_s.r_object_id = dm_acl_r.r_object_id)
       RIGHT JOIN usr
          ON ( (usr.accessor = dm_acl_r.r_accessor_name
                OR ( (sys_s.owner_name = usr.accessor
                      OR usr.accessor = 'dm_superusers')
                    AND dm_acl_r.r_accessor_name = 'dm_owner'))
              AND sys_s.r_object_id = <object_id>)
 WHERE usr.user_name = <user_name>

Contents of /System, /Templates and /Resource folders

Useful for PROD -> UAT cloning

WITH include
   AS (SELECT DISTINCT r_object_id
     FROM dm_folder_r
    WHERE i_ancestor_id IN
       (SELECT r_object_id
      FROM dm_folder_r
       WHERE r_folder_path IN
        ('/Templates', '/System', '/Resources'))),
   exclude
   AS (SELECT DISTINCT r_object_id
     FROM dm_folder_r
    WHERE i_ancestor_id IN
       (SELECT r_object_id
      FROM dm_folder_r
       WHERE r_folder_path IN ('/System/Sysadmin/Reports'))),
   objects
   AS (SELECT DISTINCT r_object_id
     FROM dm_sysobject_r
    WHERE   i_folder_id IN (SELECT r_object_id FROM include)
    AND i_folder_id NOT IN (SELECT r_object_id FROM exclude)
    AND r_object_id NOT LIKE '0b%'
    AND r_object_id NOT LIKE '0c%')
SELECT  l.file_system_path
   || '/'
   || LPAD (SUBSTR (o.r_object_id, 3, 6), 8, 0)
   || LOWER (
     REGEXP_REPLACE (
    SUBSTR (
       TO_CHAR (
      CASE
       WHEN cs.data_ticket < 0
       THEN
        POWER (16, 16) + cs.data_ticket
       ELSE
        cs.data_ticket
      END,
      'XXXXXXXXXXXXXXXX'),
       10,
       8),
    '(\w\w)',
    '/\1'))
   || CASE
     WHEN f.dos_extension <> ' ' THEN '.' || f.dos_extension
     ELSE ''
    END
  FROM objects o,
   dmr_content_r cr,
   dmr_content_s cs,
   dm_format_s f,
   dm_filestore_s fs,
   dm_location_sp l
 WHERE   cr.parent_id = o.r_object_id
   AND cr.r_object_id = cs.r_object_id
   AND f.r_object_id = cr.i_format
   AND fs.r_object_id = cs.storage_id
   AND l.object_name = fs.root

Increase entropy on Linux/VMWare

Environment variables for Documentum:

export DEVRANDOM=/dev/urandom

Java options:

-Djava.security.egd=file:/dev/./urandom

System services:

 ~]# rpm -qf /etc/sysconfig/rngd
rng-tools-2-13.el6_2.x86_64
 ~]# cat /etc/sysconfig/rngd
# Add extra options here
EXTRAOPTIONS="-r /dev/urandom -o /dev/random -t 0.1"
 ~]# chkconfig --level 345 rngd on
 ~]# service rngd start
Starting rngd:                                             [  OK  ]

Trace authentication

Useful for LDAP debugging.

Enable:

apply,c,,SET_OPTIONS,OPTIONS,S,trace_authentication,VALUE,B,T

Disable:

apply,c,,SET_OPTIONS,OPTIONS,S,trace_authentication,VALUE,B,F

Other debug options

Get ACS URLs

public List<String> getAcsUrls(IDfSysObject object, String location)
    throws Exception {
    List<String> result = new ArrayList<String>();
    IDfClientX clientX = new DfClientX();
    IDfExportOperation operation = clientX.getExportOperation();
    IDfAcsTransferPreferences acsTransferPreferences = clientX
            .getAcsTransferPreferences();
    acsTransferPreferences.preferAcsTransfer(true);
    acsTransferPreferences.allowBocsTransfer(true);
    acsTransferPreferences.setSynchronousBocsTransfer(true);
    acsTransferPreferences.setClientNetworkLocationId(location);
    operation.setAcsTransferPreferences(acsTransferPreferences);
    operation.setSession(object.getSession());
    IDfExportPackage exportPackage = clientX.getContentPackageFactory()
            .newExportPackage();
    exportPackage.add(object.getObjectId());
    operation.add(exportPackage);
    operation.execute();
    IDfEnumeration items = exportPackage.getItems();
    while (items != null && items.hasMoreElements()) {
        IDfExportPackageItem item = (IDfExportPackageItem) items
                .nextElement();
        if (item == null) {
            continue;
        }
        IDfClientServerFile csFile = item.getFile();
        if (csFile == null) {
            continue;
        }
        IDfServerFile sFile = csFile.getServerFile();
        if (sFile == null) {
            continue;
        }

        IDfEnumeration requests = sFile.getRemoteLocations();
        while (requests != null && requests.hasMoreElements()) {
            IDfAcsExportContentRequestInternal request = 
                    (IDfAcsExportContentRequestInternal) requests.nextElement();
            result.add(RequestHandlerFactory.getHandler(
                    request.getProtocol(), this).makeURL(request));
        }
    }
    return result;
}

Handle IDfOperation errors

public boolean executeOperation(IDfOperation op, List<Throwable> t)
    throws Exception {
    boolean result = op.execute();
    if (result) {
        return true;
    }

    IDfList errors = op.getErrors();
    for (int i = 0; i < errors.getCount(); i++) {
        IDfOperationError err = (IDfOperationError) errors.get(i);
        IDfException ex = err.getException();
        if (ex instanceof Throwable) {
            t.add((Throwable) ex);
        }
    }

    return false;
}

The only correct transaction pattern

// the rule of thumb is perform begin/commit/abort in the same scope, to
// support nesting we check whether transaction is already active or not
boolean txStartsHere = false;
try {
    // if transaction is already active we mustn't try to
    // begin/commit/abort transaction in our code because we don't
    // control transaction
    if (!session.isTransactionActive()) {
        session.beginTrans();
        txStartsHere = true;
    }
 
    // business logic here
 
    // transaction is controlled by our code
    if (txStartsHere) {
        session.commitTrans();
        txStartsHere = false;
    }
} finally {
    // transaction is controlled by our code, commitTrans can throw
    // exception but DFC forcibly aborts
    // transaction in this case, so we need to check transaction state
    if (txStartsHere && session.isTransactionActive()) {
        session.abortTrans();
    }
}

Dump information about type

dump,c,t<type_name>

Dump information about attribute

dump,c,t<type_name>.<attribute name>

Top things to do before install workflow

UPDATE dmi_workitem_s w
   SET r_queue_item_id = '0000000000000000'
 WHERE     r_queue_item_id <> '0000000000000000'
       AND NOT EXISTS
              (SELECT *
                 FROM dmi_queue_item_s q
                WHERE q.r_object_id = w.r_queue_item_id);

COMMIT;

Bypass TBO during DQL update

apply,c,,EXEC,QUERY,S,<DQL>,FOR_UPDATE,B,T,BOF_DQL,B,F

One thought on “Marginalia

  1. Pingback: Entropy | Documentum in a (nuts)HELL

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s