JavaBlog.fr / Java.lu API DCTM,DEVELOPMENT,Documentum,ECM Documentum : Creation of audit trail entries dm_audittrail

Documentum : Creation of audit trail entries dm_audittrail

Hi,

Here, a Documentum DFC standalone sample program in order to create entries in dm_audittrail. DCTM provides several more evolved methods for example to register an audit event (dm_save) for specific custom object and its subtypes and including new values of attributes in order to create automatically entries,

Very good article : https://www.bluefishgroup.com/insights/articles/the-content-server-audit-facility/

01public void registerAudit(IDfSession session) throws DfException {
02    // Get an instance of the audit manager using the session
03    IDfAuditTrailManager auditMgr = session.getAuditTrailManager();
04    // Setup the request parameters
05    String objectType = "vendor_admin";
06    String eventName = "dm_save";
07 
08    boolean auditSubTypes = true; // we want to audit subtypes also
09    boolean signAuditEntries = false; // disable tamper-evident Audit Trail
10    int authentication = 0; // we don't require user to authenticate
11    String description = "Save Vendor Admin"; // shows up in each audit entry
12    String[] auditAttrs = { "va_name, "va_tax_id" };
13 
14    // Use the audit manager to register the audit.
15    // We do not care about controlling applications or workflows,
16    // so we pass null for those arguments.
17    auditMgr.registerEventForType(objectType, eventName, auditSubTypes,
18        null, // controllingApp
19        null, // policyId
20        null, // stateName
21        signAuditEntries,
22        authenticate,
23        description,
24        new DfList(attrs));
25}

 
Here, a simple code in order to create audit entries without registration:

001package com.huo.test.ecm.test2;
002 
003import com.documentum.fc.client.DfClient;
004import com.documentum.fc.client.DfQuery;
005import com.documentum.fc.client.IDfAuditTrailManager;
006import com.documentum.fc.client.IDfClient;
007import com.documentum.fc.client.IDfCollection;
008import com.documentum.fc.client.IDfQuery;
009import com.documentum.fc.client.IDfSession;
010import com.documentum.fc.client.IDfSessionManager;
011import com.documentum.fc.client.IDfSysObject;
012import com.documentum.fc.common.DfId;
013import com.documentum.fc.common.DfLoginInfo;
014import com.documentum.fc.common.IDfLoginInfo;
015 
016/*
017 Documentum DFC Standalone Sample Program
018 
019 Creation of audit trail entries
020 */
021 
022public class DMAuditTrailTest {
023 
024    IDfSysObject sysObject = null;
025    IDfSession idfSession = null;
026    IDfSessionManager sessMgr = null;
027 
028    public DMAuditTrailTest(String user, String passwd, String docbase) throws Exception {
029        getDfSession(user, passwd, docbase);
030    }
031 
032    public IDfSession getDfSession(String args1, String args2, String args3) throws Exception {
033         
034        IDfLoginInfo login = new DfLoginInfo();
035        login.setUser(args1);
036        login.setPassword(args2);
037        IDfClient client = DfClient.getLocalClient(); //new DfClient();
038        sessMgr = client.newSessionManager();
039        sessMgr.setIdentity(args3, login);
040        idfSession = sessMgr.getSession(args3);
041 
042        if (idfSession != null)
043            System.out.println("Session created successfully");
044 
045        return idfSession;
046    }
047 
048 
049    public void releaseSession() throws Exception {
050        sessMgr.release(idfSession);
051    }
052     
053    public void createAuditTrailEntry(String objectId, String eventName) throws Exception {
054        IDfAuditTrailManager mgr = idfSession.getAuditTrailManager();
055        //  createAudit(IDfId objectId, String event, String[] stringArgs, IDfId[] idArgs) 
056        mgr.createAudit(new DfId(objectId), eventName, null, null);
057    }
058 
059    public int getNbEntriesOfAuditTrail(String eventName) throws Exception{
060        IDfCollection resCount = null;
061        int nbEntries = 0;
062        try{
063            String dql = "select count(r_object_id) as cnt from dm_audittrail where event_name = '"+eventName+"' order by time_stamp desc";
064            IDfQuery query = new DfQuery();
065            query.setDQL(dql);
066            resCount = query.execute(idfSession, IDfQuery.DF_EXEC_QUERY);
067            if(resCount!=null){
068                resCount.next();
069                nbEntries = resCount.getInt("cnt");
070            }
071             
072        } finally {
073            if (resCount!=null) {
074                resCount.close();
075            }
076        }//end-if
077        return nbEntries;
078    }
079     
080    public static void main(String[] args) throws Exception {
081 
082        String user = "huouser";
083        String passwd = "pwd_4huouser";
084        String docbase = "MY_DOCBASE_DEV";
085 
086        boolean isTransactionalSession = false;
087        boolean noErrorWithCurrentDocument = false;
088 
089        DMAuditTrailTest object = new DMAuditTrailTest(user, passwd, docbase);
090 
091        try {
092            if (!object.idfSession.isTransactionActive()) {
093                object.idfSession.beginTrans();
094                isTransactionalSession = true;
095            }
096            String eventName =  "Executing createAuditTrailInput :)";
097            String objectId = "090xxxxxxxxf1d";
098            //
099            int nbEntries1 = object.getNbEntriesOfAuditTrail(eventName);
100            System.out.println("Nb of audit trail for the event '"+eventName+"' = "+ nbEntries1 + "(BEFORE adding)");
101            //
102            object.createAuditTrailEntry(objectId, eventName);
103            //
104            int nbEntries2 = object.getNbEntriesOfAuditTrail(eventName);
105            System.out.println("Nb of audit trail for the event '"+eventName+"' = "+ nbEntries2 + "(AFTER adding) - under condition that the transaction is committed!!!!");
106             
107            noErrorWithCurrentDocument = true;
108        } finally {
109            if(object!=null){
110                if (isTransactionalSession) {
111                    if (noErrorWithCurrentDocument) {
112                        object.idfSession.commitTrans();
113                    } else {
114                        object.idfSession.abortTrans();
115                    }
116                }
117                 
118                // to release a docbase session
119                object.releaseSession();
120            }
121        }
122         
123    }
124}

 
Below, an example of output for this program:

1Session created successfully
2Nb of audit trail for the event 'Executing createAuditTrailInput :)' = 2(BEFORE adding)
3Nb of audit trail for the event 'Executing createAuditTrailInput :)' = 3(AFTER adding) - under condition that the transaction is committed!!!!

 
The important point of code is :

1public void createAuditTrailEntry(String objectId, String eventName) throws Exception {
2    IDfAuditTrailManager mgr = idfSession.getAuditTrailManager();
3    //  createAudit(IDfId objectId, String event, String[] stringArgs, IDfId[] idArgs) 
4    mgr.createAudit(new DfId(objectId), eventName, null, null);
5}

 
 
Extended User Privileges
To do anything on auditing, the current user must have specific extended user privileges. There are three extended user privileges which the Content Server
uses to manage security authorization for audit requests:

  • Config Audit : User can execute the Audit and Unaudit methods to start and stop auditing, its integer value is 8
  • Purge Audit : User can remove Audit Trail entries from the Docbase, its integer value is 16
  • View Audit : User can view Audit Trail entries, its integer value is 32

 
We have an user yith the Extended Privileges = Config, View and Purge Audit:

1select user_xprivileges from dm_user where user_name = 'gedadm';
2= 56
3= 8 + 16 + 32

 
TEST 1 :
Even if the maximum extended user privileges, it is not possible to modify an existing AuditTrail object via DFC/DQL/API, any tentative will get the exception DfException:: THREAD: main; MSG: [DM_AUDITTRAIL_E_CANT_MODIFY]error: “You can not modify any existing AuditTrail object 5f0xxxxxxxxxxxxxbf.”; ERRORCODE: 100; NEXT: nullerror:

01public void createAuditTrailEntry(String objectId, String eventName) throws Exception {
02    IDfAuditTrailManager mgr = idfSession.getAuditTrailManager();
03    //  createAudit(IDfId objectId, String event, String[] stringArgs, IDfId[] idArgs) 
04    IDfId auditTrailId = mgr.createAudit(new DfId(objectId), eventName, null, null);
05     
06    // => Exception in thread "main" DfException:: THREAD: main; MSG: [DM_AUDITTRAIL_E_CANT_MODIFY]error:  "You can not modify any existing AuditTrail object 5f0xxxxxxxxxxxxxbf."; ERRORCODE: 100; NEXT: null
07    try{
08        IDfAuditTrail auditTrailObj = (IDfAuditTrail) idfSession.getObject(auditTrailId);
09        auditTrailObj.setString("event_description", "event_description for the "+objectId+" object" );
10        auditTrailObj.save();
11    }catch(Exception ex){
12        ex.printStackTrace();
13    }
14}

 
TEST 2 :
Howvever, it is possible to modify any existing AuditTrail object via SQL:

01// MAIN 2 : Modification of audit trail
02{
03    String auditTrailId = "5f0xxxxxx7";
04    StringBuilder sql = new StringBuilder();
05    sql.append("UPDATE ").append(object.idfSession.getDocbaseOwnerName()).append(".dm_audittrail_s");
06    sql.append(" SET ");
07    sql.append(" event_description = '").append("event_description for the "+auditTrailId+" object").append("' ");
08    sql.append(" WHERE R_OBJECT_ID = '").append(auditTrailId).append("'");
09    IDfApplyExecSQL dfApplyExecSQL = (IDfApplyExecSQL) DfAdminCommand.getCommand(DfAdminCommand.APPLY_EXEC_SQL);
10    dfApplyExecSQL.setQuery(sql.toString());
11    IDfCollection coll = dfApplyExecSQL.execute(object.idfSession);
12    try {
13        if (coll.next()) {
14            IDfValue dfValue = coll.getValueAt(0);
15            if (!dfValue.asBoolean()) {
16                throw new RuntimeException("Error in modification of existing AuditTrail object via SQL :" + sql);
17            }
18        } else {
19            throw new RuntimeException("Error in modification of existing AuditTrail object via SQL :" + sql);
20        }
21    } finally {
22        if(coll!=null){
23            coll.close();
24        }
25    }
26}

 
Example of deleting of existing AuditTrail object via pure API:

1API> retrieve,c,dm_audittrail where r_object_id ='5f0xxxxxx7'
2...
35f0xxxxxx7
4API> destroy,c,l
5...
6OK

 
Example of creation of AuditTrail object via pure API:

01create,c,dm_audittrail
02set,c,l,event_name
03my_event_huo_name
04set,c,l,event_source
05My process
06set,c,l,user_name
07My process
08set,c,l,audited_obj_id
0909xxxxxx62
10set,c,l,string_1
11Value Str 1
12set,c,l,string_2
13Value Str 2
14set,c,l,string_3
15Value Str 3
16set,c,l,id_1
1709xxxxx621
18set,c,l,id_2
1909xxxxxx622
20set,c,l,sid_3
2109xxxxxx623
22save,c,l

The informations user_id, session_id, owner_name, time_stamp, time_stamp_utc, host_name are filled automatically by Content Server. Yet, the informations acl_name, acl_domain, chronicle_id, object_type, version_label, object_name are extracted from the audited object (audited_obj_id).
 
 
Resources : https://www.bluefishgroup.com/insights/articles/the-content-server-audit-facility/
Best regards,

Huseyin

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.

Related Post