Custom Workflows
Ok...we have some custom options that need to happen when we run through a workflow, like changing lifecycles and permission. I cannot find for the life of me how to do this?
I have our custom java class, based from when we were running 5.3 SP5, but we are upgrading to 6.7 (on new machines).
Our Content Server is a SPARC 10 Solaris unit, and our Web Server is a Web Server 2008 unit.
I've created the workflows in the web client that Documentum has pointing to the "cmsworkflowmethod" (custom class) for each of the automatic activities, I created a method through our DocApp for "cmsworkflowmethod" pointing to the CMSWorkflow class...but I'm not exactly sure if I have it right? I've looked at some of the documentation, but I cannot seem to find a workflow example with customization in it. I'm not sure if my methods in the docapp are created correctly or not, I'm not sure where to put the methods on the Web / Content Server.
Any help would be much appreciated. IF you can think of a way that I don't need to use custom code to do the workflows (changing lifecycles and permissions) that would work too.
Though I think my supervisor would prefer workflows customizations...
Thanks.
Joe
If this needs more information, please let me know. I'll provide everything I can.
I pretty much have a week to get workflow working properly.
Comments
-
There are many activity templates available to accomplish the tasks which you mentioned like applying ACL, chaning state of the lifecycle, etc .. you can see this in left side panel of process builder ... and if those templates are not gud enuf, you may very well write custom code and deploy in JMS to use it in a workflow automatic activity
0 -
With the activity templates to change ACL and lifecycle, are those done in workflow? If so, can you explain how? I didn't see them.
0 -
Great, so where on the Content Server do I install these custom java classes so that they will work with workflow?
0 -
While I appreciate the comments, I don't think anyone else is listening to the question. We are not using Process Builder. We are using the workflow manager. This is what I'm trying to get to work. I've contact EMC about getting process builder, but they have not gotten back to me yet. In the meantime, I need to find a way to make the workflow that we've been using for years on 5.3 work on 6.7.
I found where it goes, though some of the documentation says that location is depricated. When I start the Java Method Server, it says that it gets the class files from the $DOCUMENTUM/dba/java_methods folder, so I placed my class files here. It still doesn't work.
0 -
Here's an image of the method
here's a copy of my code....
package com.gdais.custom.Workflow;
/*
*
* @class name: CMSWorkflow
* Called by workflow automatic activity. This class processes the
* child of the workitem document. For child components of
* the mini-build template, promote the lifecycle state, and set permissions
* according to current state and CMS Workflow requirements.
*/import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;import com.documentum.fc.client.DfClient;
import com.documentum.fc.client.IDfActivity;
import com.documentum.fc.client.IDfClient;
import com.documentum.fc.client.IDfCollection;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfSessionManager;
import com.documentum.fc.client.IDfSysObject;
import com.documentum.fc.client.IDfVirtualDocument;
import com.documentum.fc.client.IDfVirtualDocumentNode;
import com.documentum.fc.client.IDfWorkitem;
import com.documentum.fc.common.DfException;
import com.documentum.fc.common.DfId;
import com.documentum.fc.common.DfLogger;
import com.documentum.fc.common.DfLoginInfo;
import com.documentum.fc.common.IDfId;
import com.documentum.fc.common.IDfLoginInfo;
import com.documentum.mthdservlet.IDmMethod;public class CMSWorkflow implements IDmMethod {
/**
* @param args
*/
protected IDfSessionManager m_sessionMgr = null;
protected String m_docbase = null;
protected String m_userName = null;
protected String m_workitemId = null;
protected String m_ticket = null;
protected String m_packageID = null;
protected String m_TaskName = null;
private String m_domain = null;private static final String USER_KEY = "user";
private static final String DOCBASE_KEY = "docbase_name";
private static final String WORKITEM_KEY_2 = "workitemId";
private static final String TICKET_KEY = "ticket";
private static final String WORKITEM_KEY = "packageId";private IDfId docIdObj; // ID of main document in WF package
private boolean lifeCycleOverride; // always false in this workflow
private boolean lifeCycleTestOnly; // default to falsepublic void execute(Map params, OutputStream ostream) throws Exception {
IDfSession session = null;
IDfId workitemID = null;
IDfWorkitem workitem = null;
IDfCollection pkgColl = null;
lifeCycleOverride = false; // force object promotion
lifeCycleTestOnly = false; // true to test if object can be promotedinitWorkflowParams(params); // receive and initialize params
DfLogger.info("tracing", "STARTING WORKFLOW:", null, null);
IDfSessionManager sessionManager = login();try {
workitemID = new DfId(m_packageID);
session = sessionManager.getSession(m_docbase);DfLogger.info("tracing", "SESSION ID: "
+ session.getSessionId(), null, null);// Get the workitem (task)
workitem = (IDfWorkitem) session.getObject(workitemID);// Acquire the workitem then process the package
workitem.acquire();// This is the partial build (techinfo object)
pkgColl = workitem.getPackages("");if (pkgColl != null) {
while (pkgColl.next()) {
IDfActivity m_act = workitem.getActivity();
m_TaskName = m_act.getObjectName();
DfLogger.info("tracing", "TASK NAME: "
+ m_TaskName.toString(), null, null);
int docCount = pkgColl.getValueCount("r_component_id");for (int i = 0; i <= (docCount - 1); i++) {
docIdObj = pkgColl.getRepeatingId("r_component_id", i);
if (docIdObj != null) {
DfLogger.info("tracing", "DOCIDOBJ: "
+ docIdObj.getId(), null, null);
setChildProperties(null, docIdObj, session, ostream);
}
}
}
pkgColl.close();
}
DfLogger.info("tracing", "ENDING WORKFLOW:", null, null);
workitem.complete();
} catch (DfException e) {
ostream.write(e.getMessage().getBytes());
DfLogger.error("tracing", "Error message : " + e.getMessage(),
null, null);
e.printStackTrace(); // spit out to stderr as well
throw e;
} finally {
if (session != null) {
sessionManager.release(session);
sessionManager.clearIdentities();
}
}
}// get the 5 WF-related parameters always passed in by Server
protected void initWorkflowParams(Map params) {Set keys = params.keySet(); // returns a Set
Iterator iter = keys.iterator(); // get the 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)) {
m_userName = (value.length > 0) ? value[0] : "";
DfLogger.info("tracing", "INIT WF PARAM-User Name = : "
+ m_userName, null, null);
} else if (key.equalsIgnoreCase(DOCBASE_KEY)) {
m_docbase = (value.length > 0) ? value[0] : "";
DfLogger.info("tracing", "INIT WF PARAM-Docbase = : "
+ m_docbase, null, null);
} else if (key.equalsIgnoreCase(WORKITEM_KEY_2)) {
m_workitemId = (value.length > 0) ? value[0] : "";
DfLogger.info("tracing", "INIT WF PARAM-Workitem ID = : "
+ m_workitemId, null, null);
} else if (key.equalsIgnoreCase(WORKITEM_KEY)) {
m_packageID = (value.length > 0) ? value[0] : "";
DfLogger.info("tracing", "INIT WF PARAM-Package ID = : "
+ m_packageID, null, null);
} else if (key.equalsIgnoreCase(TICKET_KEY)) {
m_ticket = (value.length > 0) ? value[0] : "";
DfLogger.info("tracing", "INIT WF PARAM-Ticket value = : "
+ m_ticket, null, null);
}
}
}// login and return a session manager interface
protected IDfSessionManager login() throws DfException {
if (m_docbase == null || m_userName == null || m_ticket == null) {
return null;
}// now login
IDfClient dfClient = DfClient.getLocalClient();
if (dfClient != null) {
IDfLoginInfo li = new DfLoginInfo();
li.setUser(m_userName);
li.setPassword(m_ticket);
li.setDomain(null);IDfSessionManager sessionMgr = dfClient.newSessionManager();
sessionMgr.setIdentity(m_docbase, li);
return sessionMgr;
}
return null;
}// This method sets properties of applicable virtual document components.
// Applicable objects
// include those with the MRU_Development lifecycle applied. Recursively
// Walk the VD (minibuild)
// tree and set object permissions and lifecycle states.
private void setChildProperties(IDfVirtualDocumentNode vdNode,
IDfId docObjID, IDfSession session, OutputStream ostream)
throws DfException, IOException {
try {
if (m_docbase.equalsIgnoreCase("devtest")) {
m_domain = m_docbase;
} else if (m_docbase.equalsIgnoreCase("sp23fdcms")) {
m_domain = m_docbase;
}
// get the root object
if (vdNode == null && docObjID != null) { // for Root node only
IDfVirtualDocument vDoc = null;
IDfSysObject m_obj = (IDfSysObject) session.getObject(docObjID);
if (m_obj != null) {
// process (vdNode) root node
vDoc = m_obj.asVirtualDocument("CURRENT", false);
vdNode = vDoc.getRootNode();
// DfLogger.info("tracing",
// "setChildProperties: ROOT OBJ NAME= " +
// m_obj.getObjectName(),null,null);
}
}IDfVirtualDocumentNode childNode = null;
// # of child nodes of current (vdNode) virtual document node
int childCnt = vdNode.getChildCount();// update children objects
for (int i = 0; i <= (childCnt - 1); i++) {
childNode = vdNode.getChild(i);
IDfSysObject m_childObj = childNode.getSelectedObject();
// String nameOfAcl = m_childObj.getACLName();
// DfLogger.info("tracing", "ACL NAME: " + nameOfAcl, null,
// null);// Make sure no system objects are processed
if (m_childObj.getBoolean("a_is_template") == false
&& !(m_childObj.getTypeName()
.equalsIgnoreCase("sp23_system"))) {
// DfLogger.info("tracing", "OBJECT NOT TEMPLATE: " +
// m_childObj.getObjectName(), null, null);
// set permissions on all VD components based on WF activity
if ((m_TaskName.equalsIgnoreCase("Check_Initial_Data"))
|| (m_TaskName
.equalsIgnoreCase("DemoteToDocDevelopment"))) {
// DfLogger.info("tracing",
//"set permissions to content developer: ", null,null);
// set permissions to content developer if needed
// aclContDev = dm_450038b280000901_80000500 in devtest
// repository
if (m_childObj.getACLName() != "aclContDev") {
m_childObj
.setACLName("aclContDev");
m_childObj.setACLDomain(m_domain);
m_childObj.save();
}
} else if (m_TaskName.equalsIgnoreCase("PromoteToPVAL")) {
// set permissions to content manager if needed
// aclContMngr = dm_450038b280000902_80000500 in devtest
// repository
if (m_childObj.getACLName() != "aclContMngr") {
m_childObj
.setACLName("aclContMngr");
m_childObj.setACLDomain(m_domain);
m_childObj.save();
}
} else {
// DfLogger.info("tracing","setChildProperties:TASK: " +
// m_TaskName,null,null);
}// Process IETM content objects
if (m_childObj.getPolicyName().equalsIgnoreCase(
"MRU_development")) {
if (m_childObj.getCurrentStateName().equalsIgnoreCase("Doc_Development")
&& m_TaskName.equalsIgnoreCase("PromoteToPeerReview")) {
// Lifecycle state
// Doc Development => Peer Review
m_childObj.promote("PEER_REVIEW", lifeCycleOverride, lifeCycleTestOnly);
m_childObj.save();
// DfLogger.info("tracing",
// "DocDevelopment --> Peer_Review: " +
// m_childObj.getObjectName(),null,null);
}
// The workflow templates allow reject/demote when an
// object meets lifecycle states =
// PVAL, PMO, Verification, or External_Review for the
// procedural workflow.
// Less PVAL, Verification, and External_Review for
// descriptive workflow.
else if (m_TaskName.equalsIgnoreCase("DemoteToDocDevelopment")) {
} else if (m_childObj.getCurrentStateName()
.equalsIgnoreCase("PEER_REVIEW")
&& (m_TaskName.equalsIgnoreCase("PromoteToPVAL"))) {
// Peer Review to PVAL
// lifeCycleState = "PVAL";
m_childObj.promote("PVAL", lifeCycleOverride,
lifeCycleTestOnly);
m_childObj.save();
} else if (m_childObj.getCurrentStateName()
.equalsIgnoreCase("PEER_REVIEW")
&& (m_TaskName.equalsIgnoreCase("PromoteToPMO"))) {
// Descriptive Path, will skip over PVAL and go to
//PMO as it's supposed to do
// PEER_REVIEW --> PMO
// lifeCycleState = PMO;
m_childObj.promote("PMO", lifeCycleOverride,
lifeCycleTestOnly);
m_childObj.save();
} else if (m_childObj.getCurrentStateName()
.equalsIgnoreCase("PVAL")
&& (m_TaskName.equalsIgnoreCase("PromoteToPMO"))) {
// PVAL --> PMO
// lifeCycleState = PMO;
m_childObj.promote("PMO", lifeCycleOverride,
lifeCycleTestOnly);
m_childObj.save();
} else if (m_childObj.getCurrentStateName()
.equalsIgnoreCase("PMO")
&& (m_TaskName.equalsIgnoreCase("PromoteToVerification"))) {
// PMO => Verification
// lifeCycleState = Verification
m_childObj.promote("VERIFICATION", lifeCycleOverride, lifeCycleTestOnly);
m_childObj.save();
} else if (m_childObj.getCurrentStateName()
.equalsIgnoreCase("PMO")
&& (m_TaskName.equalsIgnoreCase("PromoteToPA"))) {
// Descriptive Path, will skip over Verification and External Review
// and go to PA as it's supposed to do
// PEER_REVIEW --> PA
// lifeCycleState = PA
m_childObj.promote("PA", lifeCycleOverride, lifeCycleTestOnly);
m_childObj.save();
} else if (m_childObj.getCurrentStateName()
.equalsIgnoreCase("Verification")
&& (m_TaskName.equalsIgnoreCase("PromoteToExternalReview"))) {
// Verification => External
m_childObj.promote("EXTERNAL_REVIEW",
lifeCycleOverride, lifeCycleTestOnly);
m_childObj.save();
} else if (m_childObj.getCurrentStateName()
.equalsIgnoreCase("External_Review")
&& (m_TaskName.equalsIgnoreCase("PromoteToPA"))) {
// External => PA
m_childObj.promote("PA", lifeCycleOverride, lifeCycleTestOnly);
m_childObj.save();
}
else if (m_childObj.getCurrentStateName()
.equalsIgnoreCase("PA")
&& (m_TaskName.equalsIgnoreCase("PromoteToDevComplete"))) {
// External => PA
m_childObj.promote("DEVELOPMENT_COMPLETE", lifeCycleOverride, lifeCycleTestOnly);
m_childObj.mark("DEVELOPMENT_COMPLETE");
m_childObj.save();
DfLogger.info("tracing", "setChildProperties:new state = DEVELOPMENT_COMPLETE: "
+ m_childObj.getObjectName(), null, null);
}
// SHOULD NEVER PROCESS FROM THIS STATE
else if (m_childObj.getCurrentStateName()
.equalsIgnoreCase("DEVELOPMENT_COMPLETE"))
// "DEVELOPMENT COMPLETE" )
{
DfLogger.info("tracing",
"setChildProperties:Object already DEVELOPMENT_COMPLETE: "
+ m_childObj.getObjectName(), null,
null);
} else // just log that this object is not processed
{
// String LogMsg = "\nChild object " +
// m_childObj.getObjectName()
// +
// " does not meet the lifecycle state for activity!"
// + m_TaskName;
// DfLogger.info("tracing",LogMsg ,null,null);
}
} // if not a template, set object attributes
} // lifecycle correct?// recurse through children of current child node
if (childNode.isVirtualDocument()) {
// DfLogger.info("tracing",
// "setChildProperties: Process Next Component: "
// +
// childNode.getProperties().getString("object_name"),null,
// null);
// Recurse through document
setChildProperties(childNode, null, session, ostream);
} else // not a virtual document node
{
String DbgMsg = childNode.getProperties().getString(
"object_name")
+ " IS LEAF NODE!";
DfLogger.info("tracing", DbgMsg, null, null);
}
} // for each child node
} // try
catch (Exception e) {
if (e instanceof DfException) {
String exceptionTrace = ((DfException) e)
.getStackTraceAsString();
DfLogger.info("tracing", exceptionTrace, null, null);
ostream.write(exceptionTrace.getBytes());
} else {
DfLogger.info("tracing", e.getMessage(), null, null);
e.printStackTrace();
}
} // catch
}// setChildProperties
} // classand this is the error I'm getting on the Content Server when I run the
startMethodServer.sh and leave it running...after it runs completely and I get the message that says it's started, I try to start a workflow, here is the message that shows up on the Content Server...
Java class must implement IDmMethod interface or have a main() method.
As you can clearly see from above my class does implement IDmMethod...any ideas?
Message was edited by: Joe_Chorba
0 -
No, I got this error from the startMethodServer.sh script that is run from the Content Server. When you start this script it doesn't close, and when I start a workflow this error pops up and continues to popup. It's on a loop.
0 -
@bacham2 - yes the a_special_app is selected to Workflow. I created this in composer which gives you a boolean checkbox as to whether it should or should not be Workflow.
Any other helpful hints?
0 -
I contacted EMC Support for help and here is what I received from them. Once I try this and see if it works I'll let you all know how it went.
To summarize here is action plan since you don’t have license to PE which handles workflow method.
1). Revert change on your dm_method to use standard doMethod by blanking out the a_special_app attribute. This attribute should not be set to ‘workflow’ if you don’t have PE server side installed.
2). Then repackage your classes into a jar and place inside:
$DOCUMENTUM_SHARED/jboss5.1.0/server/DctmServer_MethodServer/deploy/ServerApps.ear/DmMethods.war/WEB-INF/lib/
Please check to make sure your com.gdais.custom.Workflow folder structure don’t exists anywhere else, if they do, please delete the com/ folder structure. You should not be placing class file inside dba/java_method folder anymore as it’s deprecated.
0
Categories
- All Categories
- 123 Developer Announcements
- 54 Articles
- 156 General Questions
- 152 Thrust Services
- 56 Developer Hackathon
- 38 Thrust Studio
- 20.6K Analytics
- 4.2K AppWorks
- 9.1K Extended ECM
- 919 Core Messaging
- 84 Digital Asset Management
- 9.4K Documentum
- 34 eDOCS
- 193 Exstream
- 39.8K TeamSite
- 1.7K Web Experience Management
- 10 XM Fax
- Follow Categories