top-image

LATEST ARTICLES

Hi,
Just a post concerning the concurrency in DFC for the error :

DfException:: THREAD: http-0.0.0.0-0.0.0.0-9080-5; MSG: [DM_SYSOBJECT_E_CANT_SAVE]error: “Cannot save 0902xxxxxxxx15 sysobject.”; ERRORCODE: 100; NEXT: DfException:: THREAD: http-0.0.0.0-0.0.0.0-9080-5; MSG: [DM_SYSOBJECT_E_VERSION_MISMATCH]error: “save of object failed because of version mismatch: old version was 30”; ERRORCODE: 100; NEXT: null

Followed by: DfException:: THREAD: http-0.0.0.0-0.0.0.0-9080-5; MSG: [DM_SYSOBJECT_E_VERSION_MISMATCH]error: “save of object failed because of version mismatch: old version was 30”; ERRORCODE: 100; NEXT: null

Summary:

  • Optimistic concurrency control (OCC) assumes that multiple transactions can frequently complete without interfering with each other. While running, transactions use data resources without acquiring locks on those resources. Before committing, each transaction verifies that no other transaction has modified the data it has read. If the check reveals conflicting modifications, the committing transaction rolls back and can be restarted.
  • All objects in repository have i_vstamp attribute that incremented automatically after save action. Content server checks whether i_vstamp specified is actual or not, so concurrent modification of sysobjects can throw either DM_SYSOBJECT_E_VERSION_MISMATCH or DM_OBJ_MGR_E_VERSION_MISMATCH errors.
  • When any server error occurred, CS marks the current transaction invalid, so, to modify multiple objects consistently it is necessary to perform changes in explicit transaction.

Source : a very good article https://blog.documentum.pro/2014/01/19/concurrency-patterns-in-dfc-optimistic-locking/

That’s all!!!

Huseyin

Hello,

I would like to expose you the DCTM BOF Business Object Framework (BOF) which is the object oriented framework provided by Documentum to build, deploy, test and execute reusable business logic component known as Business Objects.

Types of BOF Modules:

  • TBO – Type Based Business Object
  • SBO – Service Based Business Object
  • Aspects
  • Simple Module


DCTM SBO (Service based Business Object)

  • SBO’s are part of Documentum Business Object framework
  • SBO’s are not associated with any repositories
  • SBO’s are not associated with any Documentum object types.
  • SBO information is stored in repositories designated as Global Registry.
  • SBO’s are stored in /System/Modules/SBO/ folder of repository. is the name of SBO.
  • Each folder in /System/Modules/SBO/ corresponds to a individual SBO

The steps to create a SBO are these using Composer (java codes, 2 jars (impl, interfaces), create jardefs, create module SBO):
1) Create a interface that extends IDfService define your business method
2) Create the implementation class implement write your business logic, This class should extend DfService and implement the interface defined in Step 1
3) Create a jar file for the created Interface and another jar for the implementation class then create Jar Definitions
4) Create a SBO Module and Deploy your Documentum Archive using Documentum Composer (Application builder for older versions)

How to use SBO from a Client Application
follow the below steps to instantiate a SBO from a client application.
1) Get the Local client
2) Create a login info and populate the login credentials.
3) Create a IDfSessionManager object
4) Use the newService () from the Client Object to create a SBO instance
Example: zipcodevalidator

  // create client
  IDfClient myClient = DfClient.getLocalClient();
  // create login info
  IDfLoginInfo myLoginInfo = new DfLoginInfo();
  myLoginInfo.setUser("user");
  myLoginInfo.setPassword("pwd");
  // create session manager
  IDfSessionManager mySessionManager = myClient.newSessionManager();
  mySessionManager.setIdentity("repositoryName", myLoginInfo);
  // instantiate the SBO
  IZipValidatorSBO zipValidator = (IZipValidatorSBO) myClient.newService( IZipValidatorSBO.class.getName(), mySessionManager);
  // call the SBO service
  zipValidator.validateZipCode(obj, zipCode, "repositoryName");

https://ajithp.com/2009/07/20/service-based-objects-sbos-in-documentum/
http://rinturajak.blogspot.lu/2014/06/implementation-of-documentum-business.html?m=1


DCTM TBO (Type based Business Object)

  • TBO’s are part of Documentum Business Object framework
  • extend the persistence object type
  • installed in target repository
  • override DFC method or adding of new functionnalities
  • Creation: java codes, 2 jars (impl, interfaces), create jardefs, create module TBO
  • Use in client: instanciation directly “newobject…(…)”

How to use TBO from a Client Application

IMyDocumentTbo myDocumentTypeObj = (IMyDocumentTbo) getSession().newObject("my_document_tbo");
myDocumentTypeObj.setObjectName("sayHello baby");
myDocumentTypeObj.setContentType("pdf");
myDocumentTypeObj.sayHello("...");
myDocumentTypeObj.save();

http://www.docbyte.com/fr/blog/creating-custom-tbo
http://rinturajak.blogspot.lu/2014/06/implementation-of-documentum-business.html?m=1


DCTM ASPECTS

Persistent Object = [TBO] + [Aspects] = [Object Type attributes + behaviour] + [New attributes + behaviour]

  • Aspect’s are part of Documentum Business Object framework
  • attached on object INSTANCES
  • NO attached to object type
  • installed in target repository
  • could be atached to object type but can be attached/detached to INSTANCES of ANY object type at RUNTIME
  • while TBO alter all instances of a specific persistence object type; Aspects alter specific instances of a specific object type under constraints at RUNTIME
  • Aspects define custom fields and custom values WITHOUT changing type definition (at RUNTIME)
  • Aspects are used when across type functionnality to be defined
  • Creation: ….
  • Use in client: ….

Example:
Users-based of differents countries depending of the country where user belongs, behaviour and fields of application change:

  • -> different aspects by country must be created for specific behaviour and fields attached user as needed
  • -> if user changes from one country to another, simply remove the old country aspect and attach the ney country aspect

https://ajithp.com/2008/01/18/aspects-the-new-bof-type-in-documentum/
EMC Documentum Composer Version 7.2 User Guide : https://www.emc.com/collateral/TechnicalDocument/docu57854.pdf


Automate BOF Module Deployment During Development

Very good article concerning the use of “BOFPackaging” Ant task allowing automatical installation and update of BOF modules into any repository:
https://www.bluefishgroup.com/insights/ecm/bof-ant-task/

Best regards,

Huseyin OZVEREN

Hi,
A very good article which presents the essence of cloud computing by the three fundamental models (Infrastructure as a Service (IaaS), Platform as a Service (PaaS), Software as a Service (SaaS)): http://www.scrumalliance.org/articles/435-cloud-and-agility-a-winwin-alliance

Best regards,

Huseyin

Hi,

I would like to expose you a simple example of interaction with the IRM server in order to encrypt and apply the IRM security on CONTENT files of a document. The IRM configuration is out of scope of this article.
Briefly, EMC Documentum Information Rights Management (IRM): Unauthorized access prevention to secured content, enabling organizations to maintain control of information rights beyond the firewall.
More informations:

 

…when, you use IRM on your local development machine, the following actions are necessary:

  • Adding of “emcdctmirm.jar” in the classpath of local project. Otherwise, you obtain the following error:
    29281 [main] ERROR com.documentum.services.irm.impl.irmserver.BaseIRMProxy - java.lang.ClassNotFoundException: com.emcirm.edsdecrypt.CAPIEDS
    29286 [main] ERROR com.documentum.services.irm.impl.irmserver.PolicyServerConnectionPool - java.lang.ClassNotFoundException: com.authentica.pvsapi.PVSAPI
    com.documentum.services.irm.impl.irmserver.PolicyServerProxy$PolicyServerException: java.lang.ClassNotFoundException: com.authentica.pvsapi.PVSAPI
  • Adding of a parameter in “VM arguments” of executed class corresponding to the IRM DLL local folders :
    -Djava.library.path="D:\Documentum\DEV\irm;D:\Documentum\DEV\irm\Common"
  • Adding of parameters in “dfc.properties” file:
    dfc.data.dir=C:/Documentum/DEV
  • Creation of new file in classpath for “dctmirm.properties”:
    irm.dir=D\:/Documentum/DEV/irm
    irm.index.enable=false
    irm.connectPool.size=5
    irm.protect.deleteOriginal=true
    irm.log.performance.enable=false
  • Installation of IRM Clients:
    C:\Program Files (x86)\EMC IRM:
    * Common
    * IRM Client for Microsoft Office
    * IRM Client For PDF
    * IRM Common

 
…some importants points:

  • see IRM profile in irm_profile
  • the R_MODIFIER and R_MODIFY_DATE are overridden:

    BEFORE IRMisation of CONTENT : i_vstamp=14 - r_modify_date=08/06/2015 11:28:31
    AFTER IRMisation of CONTENT : i_vstamp=15 - r_modify_date=01/12/2016 11:40:58
  • when a document has been secured via IRM, the irm_document_aspect is attached to this document,
  • when a document has been secured via IRM, a new format is associated irm-***** to this document => see the dm_format table,
  • the apply of IRM security is done via a SBO service provided by IRM com.documentum.services.irm.IIRMService:
    IDfService irmService = DfClient.getLocalClientEx().newService("com.documentum.services.irm.IIRMService", sessMgr);
    Method method = irmService.getClass().getMethod("setObjectIRMProfile", IDfSession.class, IDfSysObject.class, IDfId.class);
    method.invoke(irmService, targetObject.getObjectSession(),
  • a new dmr_content object is created for the secured content,
  • the previous dmr_content object (no-secured) is not removed and exists still in the docbase. It becomes unused and unreferenced in dm_document. The execution of standard cleaner “dm_DMClean” “dm_DMFilescan” jobs could remove the object and the file on filestore.

 
 
Example:

----------------
BEFORE :
----------------

------ dm_document or sub-type
o r_aspect_name [0]: my_aspect_java
o r_content_size : 9401
o r_full_content_size : 9401
o a_content_type : excel12book
o i_contents_id : 060xxxxxxxxxxxxxxc
o i_vstamp : 14
o r_modify_date : 08/06/2014 11:28:31
o r_modifier : user1

------ dmr_content or sub-type
o r_object_id : 060xxxxxxxxxxxxxxc
o content_size : 9401
o full_format : excel12book
o format : 27xxxxxxxxxxxxx4
o full_content_size : 9401
o i_format [0]: 27xxxxxxxxxxxxx4
o i_full_format [0]: excel12book
o i_vstamp : 1


----------------
AFTER:
----------------
------ dm_document or sub-type
o r_aspect_name [0]: my_aspect_java [1]: irm_document_aspect
o r_content_size : 14848
o r_full_content_size : 14848
o a_content_type : irm-excel12book
o i_contents_id : 06xxxxxxxxxxxxxx1a
o i_vstamp : 15
o r_modify_date : 01/12/2015 11:40:58
o r_modifier : user2

------ dmr_content or sub-type
o r_object_id : 06xxxxxxxxxxxxxx1a
o content_size : 14848
o full_format : irm-excel12book
o format : 270xxxxxxxxxxxx329
o full_content_size : 14848
o i_format [0]: 270xxxxxxxxxxxx329
o i_full_format [0]: irm-excel12book
o i_vstamp : 0

 
Concerning the PREVIOUS dm_content (no-secured):

  • The previous dmr_content object exists still in the docbase:
    SELECT * from dmr_content where r_object_id = '060xxxxxxxxxxxxxxc';
    060xxxxxxxxxxxxxxc 0 0 6dxxxxxxxxxx28 1 0 9401 excel12book
  • The previous dmr_content becomes unused and unreferenced in dm_document:
    SELECT * from dm_sysobject where i_contents_id = '060xxxxxxxxxxxxxxc';
  • EXECUTION of “dm_DMClean” job with parameter “-clean_content TRUE”. Its logs contains:
    Content object 060xxxxxxxxxxxxxxc has parent count of zero.
    apply,c,060xxxxxxxxxxxxxxc,DESTROY_CONTENT
    getmessage,c
    close,c,q0
    ...
    28.626 0.234 N/A [main] com.documentum.dmcl.impl.DmclApiNativeAdapter@727e8a11.get("apply,c,060xxxxxxxxxxxxxxc,DESTROY_CONTENT") ==> "q0"
    28.860 0.000 N/A [main] com.documentum.dmcl.impl.DmclApiNativeAdapter@727e8a11.exec("close,c,q0") ==> true
  • The previous dmr_content object has been removed from the docbase.
    Importante Note: the content file on Storage has not been deleted. This point is done by the job “dm_DMFilescan”.
    SELECT * from dmr_content where r_object_id = '060xxxxxxxxxxxxxxc';

 
 
…. finally, here the source code test class for applying IRM security:

import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;

import org.apache.commons.lang.exception.ExceptionUtils;

import com.documentum.fc.client.DfClient;
import com.documentum.fc.client.DfQuery;
import com.documentum.fc.client.IDfClient;
import com.documentum.fc.client.IDfCollection;
import com.documentum.fc.client.IDfDocument;
import com.documentum.fc.client.IDfQuery;
import com.documentum.fc.client.IDfService;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfSessionManager;
import com.documentum.fc.client.IDfSysObject;
import com.documentum.fc.client.aspect.IDfAspects;
import com.documentum.fc.commands.admin.DfAdminCommand;
import com.documentum.fc.commands.admin.IDfApplyExecSQL;
import com.documentum.fc.common.DfException;
import com.documentum.fc.common.DfId;
import com.documentum.fc.common.DfLoginInfo;
import com.documentum.fc.common.IDfId;
import com.documentum.fc.common.IDfLoginInfo;
import com.documentum.fc.common.IDfTime;
import com.documentum.fc.common.IDfValue;
import com.pwc.lu.irm.ecm.util.AppConstants;
import com.pwc.lu.irm.ecm.util.ApplyIRMException;
import com.pwc.lu.irm.ecm.util.ApplyIRMExceptionCodes;

public class DfcApiApplyIRMSecurityTest {
	IDfSession idfSession = null;
	IDfSessionManager sessMgr = null;

	/**
	 * Constructor
	 */
	public DfcApiApplyIRMSecurityTest(String user, String passwd, String docbase) throws Exception {
		getDfSession(user, passwd, docbase);
	}

	/**
	 * MAIN METHOD
	 */
	public static void main(String[] args) throws Exception {
		long startTime = 0;
		long stopTime = 0;
		
		String user = "useradm";
		String passwd = "passwordOfuseradm";
		String docbase = "MY_DOCBASE_DEV";
		String objectId = "090xxxxxxx2f2";
		String irmProfileName = "IRMConnectorProfile";
		
		DfcApiApplyIRMSecurityTest me = new DfcApiApplyIRMSecurityTest(user, passwd, docbase);
		
		boolean isTransactionalSession = false;
		boolean noErrorWithCurrentDocument = false;
		try {
			if (!me.idfSession.isTransactionActive()) {
				me.idfSession.beginTrans();
				isTransactionalSession = true;
			}

			startTime = System.currentTimeMillis();

			// Examples : irm-excel12book
			List<String> irmFormats = me.getIRMFormats();

			IDfDocument doc = null;
			{
				doc = (IDfDocument)me.idfSession.getObject(new DfId(objectId));
				System.out.println("BEFORE IRMisation of CONTENT : i_vstamp="+doc.getInt("i_vstamp") + " - r_modify_date="+doc.getTime("r_modify_date"));
			}
			
			if(doc instanceof IDfAspects) {
				if(doc.findString("r_aspect_name", "irm_document_aspect")>=0){ // OR IDfList aspectsAttached = ((IDfAspects) doc).getAspects();
					throw new RuntimeException(MessageFormat.format("The document ({0}) has already been IRMised (associated to the \"{1}\" ASPECT)", objectId, "irm_document_aspect"));
				}
			}
			
			IDfTime previousModifyDateTime = doc.getTime("r_modify_date");
			String previousModifier = doc.getString("r_modifier");
			String aContentType = doc.getString("a_content_type"); // excel12book

			boolean isIRMableContentType = false;
			for (Iterator<String> iterator = irmFormats.iterator(); iterator.hasNext() && isIRMableContentType==false;) {
				String currIRMFormat = iterator.next();
				isIRMableContentType = currIRMFormat.equalsIgnoreCase("irm-"+aContentType);
			}//end-for

			if(isIRMableContentType==false){
				throw new RuntimeException("The content type of object ("+aContentType+") is not compliant with IRM!");
			}
			
						
			me.applyIRMSecurity(objectId, irmProfileName);	

			
			{
				doc = (IDfDocument)me.idfSession.getObject(new DfId(objectId));
				System.out.println("AFTER IRMisation of CONTENT : i_vstamp="+doc.getInt("i_vstamp")  + " - r_modify_date="+doc.getTime("r_modify_date"));
			}

			// Setting of the previous value for r_modify_date AND r_modifier because the attachment of aspect needs a SAVE action on document.
			// So, Content server overrides r_modifer and r_modify_date informations. 
			setPreviousValuesOfLastModifAttributesBySQL(objectId, me.idfSession, previousModifyDateTime, previousModifier);

			stopTime = System.currentTimeMillis();
			
			noErrorWithCurrentDocument = true;
			
		} catch(Throwable th) {
			Throwable rootCause = ExceptionUtils.getRootCause(th);
			if(rootCause!=null){
				rootCause.printStackTrace();
			}else{
				th.printStackTrace();
			}
			
		} finally {
			if(me!=null){
				if (isTransactionalSession && me.idfSession!=null) {
					if (noErrorWithCurrentDocument) {
						me.idfSession.commitTrans();
					} else {
						me.idfSession.abortTrans();
					}
				}

				// to release a docbase session
				me.releaseSession();
				
				long elapsedTime = stopTime - startTime;
				System.out.println(MessageFormat.format("Execute() total execution time : {0} ms ", elapsedTime));
			}
			
		}
	}

	
	private IDfSession getDfSession(String userName, String password, String docbaseName) throws Exception {
		IDfLoginInfo login = new DfLoginInfo();
		login.setUser(userName);
		login.setPassword(password);
		IDfClient client = DfClient.getLocalClient(); // new DfClient();
		sessMgr = client.newSessionManager();
		sessMgr.setIdentity(docbaseName, login);
		idfSession = sessMgr.getSession(docbaseName);

		if (idfSession != null){
			System.out.println("Session created successfully");
		}

		return idfSession;
	}
	
	
	private void releaseSession() throws Exception {
		sessMgr.release(idfSession);
	}

	private List<String> getIRMFormats() throws DfException {
		IDfCollection col = null;
		List<String> result = new ArrayList<String>();
		try {
			IDfQuery query = new DfQuery();
			query.setDQL("select r_object_id, name, dos_extension, mime_type from dm_format where LOWER(name) like 'irm-%'");
			col = query.execute(idfSession, IDfQuery.DF_EXEC_QUERY);
			if(col != null) {
				while(col.next()){
					// ---- dm_format
					// 27xxxxx123		irm-excel12book		xlsx	application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
					// 27xxxxxxxx456		irm-excel8book		xls		application/vnd.ms-excel
					result.add(col.getString("name"));
				}//end-while
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (col!=null) {
				col.close();
			}
		}
		return result;
	}
	
	private void applyIRMSecurity(String targetObjectId, String irmProfileName) throws Throwable {
		IDfSysObject sysObjectIRMProfile = (IDfSysObject) idfSession.getObjectByQualification("irm_profile WHERE object_name = '"+irmProfileName+"'");
		if(sysObjectIRMProfile != null) {
			DfId irmProfileId = new DfId(sysObjectIRMProfile.getString("r_object_id"));
			if(irmProfileId!=null && !irmProfileId.isNull()) {
				IDfSysObject targetObject = (IDfSysObject)idfSession.getObject(new DfId(targetObjectId));
				if(targetObject instanceof IDfAspects) {
					if(targetObject.findString("r_aspect_name", "irm_document_aspect")<0){ // OR IDfList aspectsAttached = ((IDfAspects) doc).getAspects();
						IDfService irmService = DfClient.getLocalClientEx().newService("com.documentum.services.irm.IIRMService", sessMgr);
						Method method = irmService.getClass().getMethod("setObjectIRMProfile", IDfSession.class, IDfSysObject.class, IDfId.class);
						method.invoke(irmService, targetObject.getObjectSession(), targetObject, irmProfileId);
					}else{
						String tmpStr = MessageFormat.format("The document \"{0}\" is already protected by IRM (presence of ASPECT 'irm_document_aspect')", targetObjectId);
						System.out.println(tmpStr);	
					}
				}
			}
		}
	}
	
	
	private static void setPreviousValuesOfLastModifAttributesBySQL(String currObjectId, IDfSession session, IDfTime previousModifyDateTime, String previousModifier) throws Throwable{
		StringBuilder sql = new StringBuilder();
		sql.append("UPDATE ").append(session.getDocbaseOwnerName()).append(".DM_SYSOBJECT_S");
		sql.append(" SET ");
		sql.append(" R_MODIFIER = '").append(previousModifier).append("',");
		DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
		dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
		sql.append(" R_MODIFY_DATE = to_date('").append(dateFormat.format(previousModifyDateTime.getDate())).append("', 'DD-MM-YYYY HH24:MI:SS')");
		sql.append(" WHERE R_OBJECT_ID = '").append(currObjectId).append("'");
		IDfApplyExecSQL dfApplyExecSQL = (IDfApplyExecSQL) DfAdminCommand.getCommand(DfAdminCommand.APPLY_EXEC_SQL);
		dfApplyExecSQL.setQuery(sql.toString());
		IDfCollection coll = dfApplyExecSQL.execute(session);
		try {
			if (coll.next()) {
				IDfValue dfValue = coll.getValueAt(0);
				if (!dfValue.asBoolean()) {
					throw new RuntimeException("Error in updating of R_MODIFIER and R_MODIFY_DATE fields.");
				}
			} else {
				throw new RuntimeException("Error in updating of R_MODIFIER and R_MODIFY_DATE fields.");
			}
		} finally {
			if(coll!=null){
				coll.close();
			}
		}
	}
	
}

That’s all!!

Huseyin OZVEREN

Page 1 of 36:1 2 3 4 »Last »
bottom-img
Copyright ® 2012 Huseyin Ozveren. No reproduction, even partial, can be used from this site and all its contents including text, documents, images, etc.. without the express permission of the author.