Mumbai, India
ecmnotes.com parag@ecmnotes.com

Custom Java Method for Job

To develop a Java method for job is simple and straight forward, Below you’ll find a sample which implements IDmMethod.

package com.ecmnotes.documentum.method;

import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import com.documentum.fc.client.DfClient;
import com.documentum.fc.client.IDfClient;
import com.documentum.fc.client.IDfPersistentObject;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfSessionManager;
import com.documentum.fc.client.IDfSysObject;
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;

public class customJavaMethod implements IDmMethod
{
// Declaration of variables
protected IDfSessionManager sessionMgr = null;
protected String docbase = null;
protected String userName = null;
protected String password = null;
protected String domain = null;

protected String jobid = null;

protected String strJobName = null;
protected String strServerLog = "";
protected String strFilename = "";

// Default parameters passed by invocation of job
private static final String USER_KEY = "user_name";
private static final String DOCBASE_KEY = "docbase_name";
private static final String PASSWORD_KEY = "password";
private static final String DOMAIN_KEY = "domain";
private static final String JOBID = "job_id";
private static final String MTL = "method_trace_level";

// Additional job parameters in dm_job object
private static final String JOB_PARAM_1 = "-param1";
private static final String JOB_PARAM_2 = "-param2";

// Just to make output easier
private static final String NEWLINE = "\r\n";

@SuppressWarnings("rawtypes")
public void execute(Map params, OutputStream ostream) throws Exception
{
Date dtStart = new Date();
// Get parameters from input
initParams(params);
// Get SessionManager
IDfSessionManager sessionManager = getSessionManager();
IDfSession session = null;
IDfSysObject oIDfJob = null;
IDfSysObject oResultDoc = null;
boolean bSuccess = false;

try
{
session = sessionManager.getSession(docbase);
oIDfJob = (IDfSysObject)session.getObject(new DfId(jobid));
strJobName = oIDfJob.getObjectName();
if ( strJobName.startsWith("dm_") )
strJobName = strJobName.substring(3);

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Logic Goes Here
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

bSuccess = true;
}
catch (DfException e)
{
String strMessage = e.getMessage();
ostream.write(strMessage.getBytes());
e.printStackTrace();
}
finally
{
if ( session != null )
{
if ( oIDfJob != null )
{
Date dtEnd = new Date();
String strElapsed = "";
// Get seconds total
long lSeconds = (dtEnd.getTime() - dtStart.getTime()) /1000;
if ( lSeconds > 60 )
{
long lMinutes = lSeconds / 60;
lSeconds = lSeconds - (lMinutes * 60);
strElapsed = lMinutes + " minute";
if ( lMinutes != 1 )
strElapsed += "s";
}
if ( lSeconds > 0 )
{
if ( !strElapsed.equals("") )
strElapsed += " and ";
strElapsed += lSeconds + " second";
if ( lSeconds != 1 )
strElapsed += "s";
}
if ( strElapsed.equals("") )
strElapsed = "0 seconds";

String strStatus = strJobName;
if ( bSuccess )
strStatus += " Tool Completed at " + dtEnd.toString() + " Total duration was " + strElapsed;
else
strStatus += " Tool was aborted at " + dtEnd.toString() + " View the job's report for details";

oIDfJob.setString("a_current_status", strStatus);
oResultDoc.setContentType ("crtext");
oResultDoc.setFile ( strFilename );
IDfId oDocId = null;
if ( oResultDoc.getLockOwner().equals("") )
{
oResultDoc.saveLock();
oDocId = oResultDoc.getObjectId();
}
else
{
oDocId = oResultDoc.checkin(false, "");
}
oIDfJob.setId("a_last_document_id", oDocId);
oIDfJob.save();
}
sessionManager.release(session);
}
}
}

@SuppressWarnings("rawtypes")
protected void initParams(Map params) throws Exception
{
Set keys = params.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext())
{
String key = (String) iter.next();

if( (key == null) || (key.length() == 0) )
{
continue;
}
String []value = (String[])params.get(key);

if ( key.equalsIgnoreCase(USER_KEY) )
userName = (value.length > 0) ? value[0] : "";
else if ( key.equalsIgnoreCase(DOCBASE_KEY) )
docbase = (value.length > 0) ? value[0] : "";
else if ( key.equalsIgnoreCase(PASSWORD_KEY) )
password = (value.length > 0) ? value[0] : "";
else if ( key.equalsIgnoreCase(DOMAIN_KEY) )
domain = (value.length > 0) ? value[0] : "";
else if ( key.equalsIgnoreCase(JOBID) )
jobid = (value.length > 0) ? value[0] : "";
}
}

protected IDfSessionManager getSessionManager() throws DfException
{
if (docbase == null || userName == null )
return null;

// now login
IDfClient dfClient = DfClient.getLocalClient();

if (dfClient != null)
{
IDfLoginInfo li = new DfLoginInfo();
li.setUser(userName);
li.setPassword(password);
li.setDomain(domain);

IDfSessionManager sessionMgr = dfClient.newSessionManager();
sessionMgr.setIdentity(docbase, li);
return sessionMgr;
}
return null;
}
}

The Legacy Deployment Process

In older versions of Documentum, methods needed to be archived in a jar file and copied into the Java Method Server’s dba/java_methods directory.  In 6.6, the Documentum Administrator User Guide  stated this directory is deprecated, and the DmMethods.war/WEB-INF/lib directory should be used instead.

Regardless of the exact location of your custom jar and then any supporting 3rd party libraries, they still needed to be physically copied to the Content Server.  And if you were updating the code, a full restart ofthe Java Method Server was necessary because the classes would be cached in a classloader.

The New Deployment Process

From 6.7 onward, the recommended deployment model for custom methods allows them to be hot-deployed via Composer – in other words, there is no need to physically copy the jar or its dependent libraries into any special directories on the Content Server. They are added as objects into the repository and automatically retrieved from there.

When deployed as a BOF module, these methods can be deployed and updated at will without needing to incur any downtime because restarts of the Java Method Server are not necessary.  Each module has its own classloader which allows the ability to hot-update.

DEFINE COMPOSER ARTIFACTS FOR EACH METHOD
The basic sequence of steps from inside Composer are:

  • Create the Jar Definition Artifacts
  • Create the Module Artifacts
  • Create the Method Artifacts

The reader can refer to this project as a template – but essentially each jar gets its own Jar Definition, then a standard module is created that uses the jar definition as an implementation jar. Finally, the method artifact is created that refers to the module name.

INSTALL INTO REPOSITORY

  •  Right-click on project name in left hand tree view, ‘Install Documentum Project’
  • Select repository name
  • username/password
  • Press “Login”
  • Use project and Artifact Settings
  • Press ‘Finish’

INVOKE METHOD
Execute the following DQL using Documentum Administrator, substituting your own local docbase name and install owner:

dql> EXECUTE do_method WITH method = ‘CustomJavaMethod’, arguments =’-user_name <installowner> – docbase_name <docbase> -myparam thisisatest’

VALIDATE
To see the invocation of each method, see the following files:

  •  docbase log on the Content Server to see the method launch trace
  • JMS ServerApps.log for DfLogger.WARN output
  • JMS server.log for stdout

 

One thought on “Custom Java Method for Job”

  1. kranthi says:

    good job 🙂

Leave a Reply