How to Assign a Batch Instance

Overview

This article describes how to assign batch instances to specific groups or users using custom scripts in Ephesoft Transact to support a particular business workflow. This is different from the Suspend Batch feature. Batch instances cannot be assigned from the Ephesoft Transact UI. This is managed in the ScriptDocumentAssembler.java file.

Prerequisites

To perform the instructions in this article, you will need:

  • Familiarity with Java scripting.
  • Access to the ScriptDocumentAssembler.java file.
    • Located at [Ephesoft_Directory]\SharedFolders\[your batch class]\scripts
  • The DOCUMENT_ASSEMBLER_SCRIPTING_PLUGIN added to the workflow.
    • Located at [your batch class] > Modules > Document Assembly.
  • The rv.move_to_next_batch property set to “OFF” in the application.properties file. This property must be disabled for the script to function.
    • Located at [Ephesoft_Directory]\Application\WEB-INF\classes\META-INF\

Designing the Script

The guidelines for this script design are as follows. Code excerpts listed below are pulled from the sample ScriptDocumentAssembler.java file.

  1. Write logic to determine the username to whom the batch should be assigned.
  2. Write logic to get the batch instance identifier from the batch.xml file.
  3. Write logic to get the role name, either from the database or a properties file, using the username determined in step 1.
  4. Write logic to insert data in the Ephesoft database in the batch_instance_group table.

Refer to the sample ScriptDocumentAssembler.java file listed in the Appendix for a framework of this script.

Assigning Batches

Once you have designed the script, you can assign the batch instance.

You can either:

Assign a Batch to a Group of Users

You may want to assign a batch to a group of users if you have a group that performs the same kind of task, and anyone in that group can do the work.

To assign a batch to a group, make an entry in the batch_instance_groups table in the Ephesoft database.

  • You can assign a group to every batch instance using scripts by making an entry in the batch_instance_groups table in the database.

Note: Only the assigned group will have access to that batch instance.

  • If no group is assigned to the batch instance in the batch_instance_groups table, users belonging to the batch class group will have access to that batch instance.

Note: Users belonging to the group mapped in batch_instance_groups will be given preference over the users in the batch class group.

Assign a Batch to a Single User

You may want to assign a batch to a single user if you want to direct a specific user to process a batch. This might be used if your business process dictates that the person who created a batch must also review or validate that batch.

To assign a specific user to a batch, make an entry in the batch_instance_users table.

You cannot have both a group and specific user assigned to a batch instance at once, as records in the batch_instance_groups table will override entries in the batch_instance_users table.

Note: The batch_instance_users table is only available in Ephesoft Transact 4.5.0.0 and above.

Conclusion

This completes an overview of how to assign batch instances to specific groups or users using custom scripts in Ephesoft Transact.

Appendix

Sample framework of the ScriptDocumentAssembler.java file.

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.StatelessSession;
import org.hibernate.Transaction;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import com.ephesoft.dcma.core.DCMAException;
import com.ephesoft.dcma.core.component.ICommonConstants;
import com.ephesoft.dcma.core.hibernate.DynamicHibernateDao;
import com.ephesoft.dcma.script.IJDomScript;
import com.ephesoft.dcma.util.ApplicationConfigProperties;
import com.ephesoft.dcma.util.logger.EphesoftLogger;
import com.ephesoft.dcma.util.logger.ScriptLoggerFactory;
/**
* The <code>ScriptDocumentAssembler</code> class represents the script execute structure. Writer of scripts plug-in should implement
* this IScript interface to execute it from the scripting plug-in. Via implementing this interface writer can change its java file at
* run time. Before the actual call of the java Scripting plug-in will compile the java and run the new class file.
*
* @author Ephesoft
* @version 1.0
*/
public class ScriptDocumentAssembler implements IJDomScript {
private static EphesoftLogger LOGGER = ScriptLoggerFactory.getLogger(ScriptDocumentAssembler.class);
private static String BATCH_LOCAL_PATH = "BatchLocalPath";
private static String BATCH_INSTANCE_ID = "BatchInstanceIdentifier";
private static String EXT_BATCH_XML_FILE = "_batch.xml";
private static String ZIP_FILE_EXT = ".zip";
final static String SQL_USER = "ephesoft";
final static String SQL_PASSWORD = "C@pture2O2O";
final static String SQL_DRIVER = "net.sourceforge.jtds.jdbc.Driver";
final static String DATABASE_NAME = "ephesoft";
final static String SQL_CONNECTION_STRING = "jdbc:jtds:sqlserver://localhost:1433/" + DATABASE_NAME;
final static String SQL_TABLE = "batch_instance_groups";
/**
* The <code>execute</code> method will execute the script written by the writer at run time with new compilation of java file. It
* will execute the java file dynamically after new compilation.
*
* @param document {@link Document}
* @throws DCMAException
*
*/
public static void main(String[] args) {
String filePath="C:\\Ephesoft\\SharedFolders\\ephesoft-system-folder\\BI2\\BI2_batch.xml\\BI2_batch.xml";
try{
SAXBuilder sb = new SAXBuilder();
Document document = sb.build(filePath);

// GET USERNAME FROM BATCH.XML
String userName=getUserName(document);

// GET BATCH INSTANCE IDENTIFIER FROM BATCH.XML
String batchInstanceIdentifier=getUserName(document);

// GET ROLE FROM DATABASE OR PROPERTIES FILE
String userRole="role1";

// Insert an entry into batch_instance_group table
assignedBatchInstanceGroup(batchInstanceIdentifier,userRole);
}
catch(Exception e){
e.printStackTrace();
}
}

// method to get username, adjust your logic accordingly
public static String getUserName(Document document) {
String getUserName=document.getRootElement().getChild("BatchName").getText();
return getUserName;
}

//method to get batch instance identifier
public static String getBatchInstanceIdentifier(Document document) {
String batchInstanceIdentifier=document.getRootElement().getChild("BatchInstanceIdentifier").getText();
return batchInstanceIdentifier;
}

//method to get batch instance identifier
public static void assignedBatchInstanceGroup(String batchInstanceIdentifier, String userRole ) throws DCMAException {
DynamicHibernateDao dynamicHibernateDao = null;
try {
dynamicHibernateDao = new DynamicHibernateDao(SQL_USER, SQL_PASSWORD, SQL_DRIVER, SQL_CONNECTION_STRING);
StatelessSession statelessSession = null;
statelessSession = dynamicHibernateDao.getStatelessSession();
Transaction transaction = statelessSession.getTransaction();
StringBuffer dbQueryBuffer = new StringBuffer();
if (SQL_CONNECTION_STRING.contains("mysql")) {
dbQueryBuffer.append("INSERT INTO ");
dbQueryBuffer.append(SQL_TABLE);
dbQueryBuffer.append(" (creation_date, last_modified, batch_instance_id, group_name) VALUES (NOW(), NOW(), '");
dbQueryBuffer.append(batchInstanceIdentifier);
dbQueryBuffer.append("', '");
dbQueryBuffer.append(userRole);
dbQueryBuffer.append("')");
} else if (SQL_CONNECTION_STRING.contains("sqlserver")) {
dbQueryBuffer.append("INSERT INTO ");
dbQueryBuffer.append(SQL_TABLE);
dbQueryBuffer.append(" (creation_date, last_modified, batch_instance_id, group_name) VALUES (GETDATE(), GETDATE(), '");
dbQueryBuffer.append(batchInstanceIdentifier);
dbQueryBuffer.append("', '");
dbQueryBuffer.append(userRole);
dbQueryBuffer.append("')");
}
SQLQuery query = statelessSession.createSQLQuery(dbQueryBuffer.toString());
transaction.begin();
query.executeUpdate();
transaction.commit();
statelessSession.close();
} catch (HibernateException e) {
System.err.println(e.getMessage());
e.printStackTrace();
} finally {
if (dynamicHibernateDao != null) {
dynamicHibernateDao.closeSession();
}
}
}
public Object execute(Document documentFile, String methodName, String documentIdentifier) {
Exception exception = null;
try {
LOGGER.info("************* Inside ScriptDocumentAssembler scripts.");
LOGGER.info("************* Start execution of the ScriptDocumentAssembler scripts.");
boolean write = false;
if (null == documentFile) {
LOGGER.error("Input document is null.");
}

// GET USERNAME FROM BATCH.XML
String userName=getUserName(document);

// GET BATCH INSTANCE IDENTIFIER FROM BATCH.XML
String batchInstanceIdentifier=getUserName(document);

// GET ROLE FROM DATABASE OR PROPERTIES FILE
String userRole="role1";

// Insert an entry into batch_instance_group table
assignedBatchInstanceGroup(batchInstanceIdentifier,userRole);

// Write the document object to the xml file. Currently following IF block is commented for performance improvement.
/*if (write) {
writeToXML(documentFile);
LOGGER.info("************* Successfully write the xml file for the ScriptDocumentAssembler scripts.");
}*/

LOGGER.info("************* End execution of the ScriptDocumentAssembler scripts.");
} catch (Exception e) {
LOGGER.error("************* Error occurred in scripts." + e.getMessage());
exception = e;
}
return exception;
}
/**
* The <code>writeToXML</code> method will write the state document to the XML file.
*
* @param document {@link Document}.
*/
private void writeToXML(Document document) {
String batchLocalPath = null;
List batchLocalPathList = document.getRootElement().getChildren(BATCH_LOCAL_PATH);
if (null != batchLocalPathList) {
batchLocalPath = ((Element) batchLocalPathList.get(0)).getText();
}
if (null == batchLocalPath) {
LOGGER.error("Unable to find the local folder path in batch xml file.");
return;
}
String batchInstanceID = null;
List batchInstanceIDList = document.getRootElement().getChildren(BATCH_INSTANCE_ID);
if (null != batchInstanceIDList) {
batchInstanceID = ((Element) batchInstanceIDList.get(0)).getText();
}
if (null == batchInstanceID) {
LOGGER.error("Unable to find the batch instance ID in batch xml file.");
return;
}
String batchXMLPath = batchLocalPath.trim() + File.separator + batchInstanceID + File.separator + batchInstanceID
+ EXT_BATCH_XML_FILE;
boolean isZipSwitchOn = true;
try {
ApplicationConfigProperties prop = ApplicationConfigProperties.getApplicationConfigProperties();
isZipSwitchOn = Boolean.parseBoolean(prop.getProperty(ICommonConstants.ZIP_SWITCH));
} catch (IOException ioe) {
LOGGER.error("Unable to read the zip switch value. Taking default value as true. Exception thrown is:" + ioe.getMessage(),
ioe);
}
LOGGER.info("isZipSwitchOn************" + isZipSwitchOn);
OutputStream outputStream = null;
FileWriter writer = null;
XMLOutputter out = new com.ephesoft.dcma.batch.encryption.util.BatchInstanceXmlOutputter(batchInstanceID);
try {
if (isZipSwitchOn) {
LOGGER.info("Found the batch xml zip file.");
outputStream = getOutputStreamFromZip(batchXMLPath, batchInstanceID + EXT_BATCH_XML_FILE);
out.output(document, outputStream);
} else {
writer = new java.io.FileWriter(batchXMLPath);
out.output(document, writer);
writer.flush();
writer.close();
}
} catch (Exception e) {
LOGGER.error(e.getMessage());
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
}
}
}
}
public static OutputStream getOutputStreamFromZip(final String zipName, final String fileName) throws FileNotFoundException,
IOException {
ZipOutputStream stream = null;
stream = new ZipOutputStream(new FileOutputStream(new File(zipName + ZIP_FILE_EXT)));
ZipEntry zipEntry = new ZipEntry(fileName);
stream.putNextEntry(zipEntry);
return stream;
}
}