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/
01 | public void registerAudit(IDfSession session) throws DfException { |
03 | IDfAuditTrailManager auditMgr = session.getAuditTrailManager(); |
05 | String objectType = "vendor_admin" ; |
06 | String eventName = "dm_save" ; |
08 | boolean auditSubTypes = true ; |
09 | boolean signAuditEntries = false ; |
10 | int authentication = 0 ; |
11 | String description = "Save Vendor Admin" ; |
12 | String[] auditAttrs = { "va_name, " va_tax_id" }; |
17 | auditMgr.registerEventForType(objectType, eventName, auditSubTypes, |
Here, a simple code in order to create audit entries without registration:
001 | package com.huo.test.ecm.test2; |
003 | import com.documentum.fc.client.DfClient; |
004 | import com.documentum.fc.client.DfQuery; |
005 | import com.documentum.fc.client.IDfAuditTrailManager; |
006 | import com.documentum.fc.client.IDfClient; |
007 | import com.documentum.fc.client.IDfCollection; |
008 | import com.documentum.fc.client.IDfQuery; |
009 | import com.documentum.fc.client.IDfSession; |
010 | import com.documentum.fc.client.IDfSessionManager; |
011 | import com.documentum.fc.client.IDfSysObject; |
012 | import com.documentum.fc.common.DfId; |
013 | import com.documentum.fc.common.DfLoginInfo; |
014 | import com.documentum.fc.common.IDfLoginInfo; |
022 | public class DMAuditTrailTest { |
024 | IDfSysObject sysObject = null ; |
025 | IDfSession idfSession = null ; |
026 | IDfSessionManager sessMgr = null ; |
028 | public DMAuditTrailTest(String user, String passwd, String docbase) throws Exception { |
029 | getDfSession(user, passwd, docbase); |
032 | public IDfSession getDfSession(String args1, String args2, String args3) throws Exception { |
034 | IDfLoginInfo login = new DfLoginInfo(); |
035 | login.setUser(args1); |
036 | login.setPassword(args2); |
037 | IDfClient client = DfClient.getLocalClient(); |
038 | sessMgr = client.newSessionManager(); |
039 | sessMgr.setIdentity(args3, login); |
040 | idfSession = sessMgr.getSession(args3); |
042 | if (idfSession != null ) |
043 | System.out.println( "Session created successfully" ); |
049 | public void releaseSession() throws Exception { |
050 | sessMgr.release(idfSession); |
053 | public void createAuditTrailEntry(String objectId, String eventName) throws Exception { |
054 | IDfAuditTrailManager mgr = idfSession.getAuditTrailManager(); |
056 | mgr.createAudit( new DfId(objectId), eventName, null , null ); |
059 | public int getNbEntriesOfAuditTrail(String eventName) throws Exception{ |
060 | IDfCollection resCount = null ; |
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(); |
066 | resCount = query.execute(idfSession, IDfQuery.DF_EXEC_QUERY); |
069 | nbEntries = resCount.getInt( "cnt" ); |
073 | if (resCount!= null ) { |
080 | public static void main(String[] args) throws Exception { |
082 | String user = "huouser" ; |
083 | String passwd = "pwd_4huouser" ; |
084 | String docbase = "MY_DOCBASE_DEV" ; |
086 | boolean isTransactionalSession = false ; |
087 | boolean noErrorWithCurrentDocument = false ; |
089 | DMAuditTrailTest object = new DMAuditTrailTest(user, passwd, docbase); |
092 | if (!object.idfSession.isTransactionActive()) { |
093 | object.idfSession.beginTrans(); |
094 | isTransactionalSession = true ; |
096 | String eventName = "Executing createAuditTrailInput :)" ; |
097 | String objectId = "090xxxxxxxxf1d" ; |
099 | int nbEntries1 = object.getNbEntriesOfAuditTrail(eventName); |
100 | System.out.println( "Nb of audit trail for the event '" +eventName+ "' = " + nbEntries1 + "(BEFORE adding)" ); |
102 | object.createAuditTrailEntry(objectId, eventName); |
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!!!!" ); |
107 | noErrorWithCurrentDocument = true ; |
110 | if (isTransactionalSession) { |
111 | if (noErrorWithCurrentDocument) { |
112 | object.idfSession.commitTrans(); |
114 | object.idfSession.abortTrans(); |
119 | object.releaseSession(); |
Below, an example of output for this program:
1 | Session created successfully |
2 | Nb of audit trail for the event 'Executing createAuditTrailInput :)' = 2(BEFORE adding) |
3 | Nb of audit trail for the event 'Executing createAuditTrailInput :)' = 3( AFTER adding) - under condition that the transaction is committed !!!! |
The important point of code is :
1 | public void createAuditTrailEntry(String objectId, String eventName) throws Exception { |
2 | IDfAuditTrailManager mgr = idfSession.getAuditTrailManager(); |
4 | mgr.createAudit( new DfId(objectId), eventName, null , null ); |
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:
1 | select user_xprivileges from dm_user where user_name = 'gedadm' ; |
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:
01 | public void createAuditTrailEntry(String objectId, String eventName) throws Exception { |
02 | IDfAuditTrailManager mgr = idfSession.getAuditTrailManager(); |
04 | IDfId auditTrailId = mgr.createAudit( new DfId(objectId), eventName, null , null ); |
08 | IDfAuditTrail auditTrailObj = (IDfAuditTrail) idfSession.getObject(auditTrailId); |
09 | auditTrailObj.setString( "event_description" , "event_description for the " +objectId+ " object" ); |
TEST 2 :
Howvever, it is possible to modify any existing AuditTrail object via SQL:
03 | String auditTrailId = "5f0xxxxxx7" ; |
04 | StringBuilder sql = new StringBuilder(); |
05 | sql.append( "UPDATE " ).append(object.idfSession.getDocbaseOwnerName()).append( ".dm_audittrail_s" ); |
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); |
14 | IDfValue dfValue = coll.getValueAt( 0 ); |
15 | if (!dfValue.asBoolean()) { |
16 | throw new RuntimeException( "Error in modification of existing AuditTrail object via SQL :" + sql); |
19 | throw new RuntimeException( "Error in modification of existing AuditTrail object via SQL :" + sql); |
Example of deleting of existing AuditTrail object via pure API:
1 | API> retrieve,c,dm_audittrail where r_object_id = '5f0xxxxxx7' |
Example of creation of AuditTrail object via pure API:
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
Related