Java Action Example
For this example, the action "A_DoValInPT" that is used in the FTM Sample App is re-implemented in Java
This action performs the same function as the ESQL version in FTM Generic Model Actions. This
action shows examples of ;
- Package name and Class name matching the fully-qualified Class name entered in RSA.
- Extension of the 'ActionInstance' Class
- Database queries (using the dbHelper object created by the 'ActionInstance' superclass)
- Database persistence (persisting the Error)
- Cache access (getCache() method)
- Raising Events (for example, e_PTValid)
- Accessing the Transition Object Elements ( using the ElementHelper Class)
Action named in RSA:
The Java implementation;
package com.ibm.fxh.actions.generic;
import java.util.HashMap;
import java.util.Map;
import com.ibm.broker.plugin.MbException;
import com.ibm.fxh.action.ActionInstance;
import com.ibm.fxh.action.Constants;
import com.ibm.fxh.database.Parameters;
import com.ibm.fxh.event.ContextData;
import com.ibm.fxh.events.generic.E_InPTFailed;
import com.ibm.fxh.events.generic.E_PTDupFail;
import com.ibm.fxh.events.generic.E_PTValFail;
import com.ibm.fxh.events.generic.E_PTValid;
import com.ibm.fxh.persistance.Error;
import com.ibm.fxh.persistance.ObjId;
import com.ibm.fxh.utils.ElementHelper;
public final class A_DoValInPT extends ActionInstance
{
/*---------------------------------------------------------------------------
-- Module Scope Constants : Begin
---------------------------------------------------------------------------*/
// none
/*---------------------------------------------------------------------------
-- Module Scope Constants : End
---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
-- Module Scope Pseudo Constants : Begin
-- Initialized the 1st time the action is run.
---------------------------------------------------------------------------*/
private static String ACTION_NAME;
private E_PTValFail e_PTValFail = new E_PTValFail();
private E_PTValid e_PTValid = new E_PTValid();
private E_PTDupFail e_PTDupFail= new E_PTDupFail();
private E_InPTFailed e_InPTFailed= new E_InPTFailed();
private static String SQL_GET_DUP_PT;
private Parameters SQL_GET_DUP_PT_PARAMS = new Parameters(3);
private static String SQL_INC_FAILED;
private Parameters SQL_INC_FAILED_PARAMS = new Parameters(2);
private static String SQL_GET_CNTRS;
private Parameters SQL_GET_CNTRS_PARAMS = new Parameters(4);
private static String SQL_GET_PT_BAT_COUNT;
private Parameters SQL_GET_PT_BAT_COUNT_PARAMS = new Parameters(1);
private static String SQL_UPDATE_PT;
private Parameters SQL_UPDATE_PT_PARAMS = new Parameters(2);
/*---------------------------------------------------------------------------
-- Module Scope Pseudo Constants : End
---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
-- Module Scope Variables : Begin
-- Initialized for each message.
---------------------------------------------------------------------------*/
private ObjId nPTId = new ObjId();
private String ptType;
/*---------------------------------------------------------------------------
-- Module Scope Variables : End
---------------------------------------------------------------------------*/
public String getEventSourceName() {
return ACTION_NAME;
}
/*---------------------------------------------------------------------------
-- Standard procedure to Initialize Pseudo Constants
---------------------------------------------------------------------------*/
protected synchronized void InitPseudoConstants() throws MbException
{
ACTION_NAME = ElementHelper.getElementValueAsString(getTransition(), Constants.STR_ACTION, 0);
SQL_GET_DUP_PT =dbHelper.preProcessSQL_WithUR("SELECT ID FROM $DBSchema.OBJ_BASE WHERE TYPE = ? AND CID = ? AND ID<>?");
dbHelper.preProcessSQL_WithUR("SELECT ID FROM $DBSchema.ERROR WHERE OBJ_ID IN "+
"(SELECT B.ID FROM $DBSchema.BATCH B WHERE B.TRANSMISSION_ID=?)");
SQL_INC_FAILED =dbHelper.preProcessSQL("UPDATE $DBSchema.TRANSMISSION T SET T.BAT_FAILED_CNTR = T.BAT_FAILED_CNTR + ? WHERE T.ID = ?");
SQL_GET_CNTRS = dbHelper.preProcessSQL("SELECT P.BAT_VAL_PASS_COUNT, F.BAT_VAL_FAIL_COUNT FROM "+
"(SELECT V.OBJ_ID, V.SMALL_VALUE BAT_VAL_PASS_COUNT FROM $DBSchema.OBJ_VALUE V "+
" WHERE V.OBJ_ID = ? AND V.CATEGORY = 'EPP' AND V.KEY = ?) P FULL OUTER JOIN "+
"(SELECT V.OBJ_ID, V.SMALL_VALUE BAT_VAL_FAIL_COUNT FROM $DBSchema.OBJ_VALUE V "+
"WHERE V.OBJ_ID = ? AND V.CATEGORY = 'EPP' AND V.KEY = ?) F ON P.OBJ_ID = F.OBJ_ID");
dbHelper.preProcessSQL("UPDATE $DBSchema.OBJ_VALUE SET SMALL_VALUE = ? WHERE OBJ_ID = ? AND CATEGORY = ? AND KEY = ?");
dbHelper.preProcessSQL("INSERT INTO $DBSchema.OBJ_VALUE (OBJ_ID, CATEGORY, KEY, SMALL_VALUE) VALUES(?, ?, ?, ?)");
SQL_GET_PT_BAT_COUNT = dbHelper.preProcessSQL_WithUR("SELECT COUNT(B.ID) BAT_COUNT FROM $DBSchema.BATCH B WHERE B.TRANSMISSION_ID = ?");
SQL_UPDATE_PT = dbHelper.preProcessSQL("UPDATE $DBSchema.TRANSMISSION SET BAT_COUNT = ? WHERE ID = ?");
}
/*
* Called prior to processing all transition objects.
* Put code that is common to all transition objects.
*/
protected void ActionInit() throws MbException
{
}
/*
* Called for each object being transitioned
*/
protected void ActionObj() throws MbException
{
/*-------------------------------
-- Action Object : Begin
-------------------------------*/
// this provides diagnostic information in the Env in the event of an Exception
ElementHelper.setValue(getPMPVars(), "CURRENT_ID", ElementHelper.getElementValueAsLong(transitionObjElem, Constants.STR_ID, 0));
nPTId.setId(ElementHelper.getElementValueAsLong(transitionObjElem, Constants.STR_ID, 0));
ptType= ElementHelper.getElementValueAsString(transitionObjElem, Constants.STR_SUBTYPE, 0);
ElementHelper.setValue(getREnvContext(), "PTTYPE", ptType);
if (this.checkAllValidationComplete()){
if (!isDuplicate()){
if (isValidationErrors()){
e_PTValFail.raise(nPTId);
}else{
e_PTValid.raise(ptType,nPTId);
}
}
}
ElementHelper.delete(getREnvContext(), "PTTYPE");
/*-------------------------------
-- Action Object : End
-------------------------------*/
}
/**
* @return
* @throws MbException
*/
private boolean isValidationErrors() throws MbException {
boolean bValErrors = ("E_ValFail".equals(this.getInputEvent().getType()));
return bValErrors;
}
/**
* @return
* @throws MbException
*/
private boolean isDuplicate() throws MbException {
boolean bDup=false;
boolean bDoDupCheck;
String dupCheckPtTypes= getCache().getObjectValues().getValueInCategory("DUP_CHECK_PTTYPES",ptType);
String dupCheckFTypes=null;
if (dupCheckPtTypes==null){
dupCheckFTypes= getCache().getObjectValues().getValueInCategory("DUP_CHECK_FTYPES",ptType);
bDoDupCheck= ("Y".equals(dupCheckFTypes));
}else{
bDoDupCheck= (dupCheckPtTypes.equals("Y"));
}
if (bDoDupCheck){
// lookup database for another object of type TRANSMISSION with same CID
SQL_GET_DUP_PT_PARAMS.setParam(0, "TRANSMISSION");
SQL_GET_DUP_PT_PARAMS.setParam(1, ElementHelper.getElementValueAsString(transitionObjElem, Constants.STR_CID, 0));
SQL_GET_DUP_PT_PARAMS.setParam(2, nPTId);
dbHelper.doQuery(SQL_GET_DUP_PT, SQL_GET_DUP_PT_PARAMS);
Map<String, Object> rs = new HashMap<String, Object>();
bDup=dbHelper.getNextResult(rs);
if (bDup){
//create an ERROR record for the transmission with details of the error
e_PTDupFail.raise(nPTId);
Error err = new Error();
err.setColVal(Error.TYPE, "DUPL");
err.setColVal(Error.COMPONENT_TYPE, "ACTION");
err.setColVal(Error.COMPONENT_NAME, "A_DoValInPt.java");
err.setColVal(Error.DESCRIPTION, "There is an existing Transmission Object with the same CID");
err.setColVal(Error.OBJ_ID, nPTId);
//Mark the error to be raised when exiting the node
err.create("Error");
}
}
return bDup;
}
/**
* @throws MbException
*/
private boolean checkAllValidationComplete() throws MbException {
boolean bComplete = true;
// For events E_BatchValPass and E_BatchValFail and E_InBatFailed
if (getInputEvent().getType().equals("E_BatchValPass") || getInputEvent().getType().equals("E_BatchValFail")
||getInputEvent().getType().equals("E_InBatFailed")){
// set new count = number of IDs in BATCH context
ContextData batchContextData=getInputEvent().getContextData("BATCH");
int nBatchContextCount = (batchContextData==null)? 0 :batchContextData.getValueCount();
SQL_GET_CNTRS_PARAMS.setParam(0, nPTId);
SQL_GET_CNTRS_PARAMS.setParam(1, "BAT_VAL_PASS_COUNT");
SQL_GET_CNTRS_PARAMS.setParam(2, nPTId);
SQL_GET_CNTRS_PARAMS.setParam(3, "BAT_VAL_FAIL_COUNT");
dbHelper.doQuery(SQL_GET_CNTRS, SQL_GET_CNTRS_PARAMS);
Map<String, Object> rs = new HashMap<String, Object>();
dbHelper.getNextResult(rs);
Integer batValPassCountInt = (Integer)rs.get("BAT_VAL_PASS_COUNT");
Integer batValFailCountInt = (Integer)rs.get("BAT_VAL_FAIL_COUNT");
int batValPassCount= (batValPassCountInt==null)? 0: batValPassCountInt.intValue();
int batValFailCount= (batValFailCountInt==null)? 0: batValFailCountInt.intValue();
int nBatValPassCount= batValPassCount ;
int nBatValFailCount=batValFailCount;
boolean bInsertPass = batValPassCount==0;
boolean bInsertFail = batValFailCount==0;
Long nBatchCountLong = ElementHelper.getElementValueAsLong(transitionObjElem,Constants.STR_BAT_COUNT,0);
Long nFailedCountLong = ElementHelper.getElementValueAsLong(transitionObjElem,Constants.STR_BATFAILCNTR,0);
int nFailedCount = (nFailedCountLong==null)?0: nFailedCountLong.intValue();
// The Mapper should have set BAT_COUNT - but if it has not - we'll fix it now
if (nBatchCountLong== null){
SQL_GET_PT_BAT_COUNT_PARAMS.setParam(0, nPTId);
dbHelper.doQuery(SQL_GET_PT_BAT_COUNT, SQL_GET_PT_BAT_COUNT_PARAMS);
rs = new HashMap<String, Object>();
dbHelper.getNextResult(rs);
nBatchCountLong = (Long)rs.get("BAT_COUNT");
SQL_UPDATE_PT_PARAMS.setParam(0, nBatchCountLong);
SQL_UPDATE_PT_PARAMS.setParam(1, nPTId);
dbHelper.doQuery(SQL_UPDATE_PT, SQL_UPDATE_PT_PARAMS);
}
int nBatchCount = nBatchCountLong.intValue();
if (getInputEvent().getType().equals("E_BatchValPass")){
// If OBJ_VALUE record does not exist (category EPP, key BAT_VAL_PASS_COUNT)
// insert record, value new count
// else
// increment by new count & update record
nBatValPassCount = nBatValPassCount+ nBatchContextCount;
this.busHelper.incrementCounter(this.dbHelper,nPTId,bInsertPass, "BAT_VAL_PASS_COUNT", nBatValPassCount);
} else if (getInputEvent().getType().equals("E_BatchValFail")){
// If OBJ_VALUE record does not exist (category EPP, key BAT_VAL_FAIL_COUNT)
// insert record, value new count
// else
// increment by new count & update record
nBatValFailCount = nBatValFailCount + nBatchContextCount;
this.busHelper.incrementCounter(this.dbHelper,nPTId,bInsertFail, "BAT_VAL_FAIL_COUNT", nBatValFailCount);
} else if (getInputEvent().getType().equals("E_InBatFailed")){
// Increment count of failed batched:
// increment BAT_FAILED_CNTR by new count
SQL_INC_FAILED_PARAMS.setParam(0,new Integer(nBatchContextCount));
SQL_INC_FAILED_PARAMS.setParam(1,nPTId);
dbHelper.doQuery(SQL_INC_FAILED, SQL_INC_FAILED_PARAMS);
nFailedCount += nBatchContextCount;
}
// first check whether validation has completed for all contained batches
// (i.e., new BAT_VAL_PASS_COUNT + new BAT_VAL_FAIL_COUNT + new BAT_FAILED_CNTR = BAT_COUNT
bComplete = (nBatValPassCount + nBatValFailCount + nFailedCount == nBatchCount);
if (bComplete) {
// lookup VALUE table, with category = "IGNORE_BAT_FAILED_PTTYPE", and key = file type (OBJ.SUBTYPE)
// (if not present assume 'N' )
String cIgnoreBatFailed = getCache().getObjectValues().getValueInCategory("IGNORE_BAT_FAILED_PTTYPE",ptType);
if (cIgnoreBatFailed==null){
cIgnoreBatFailed="N";
}
if ((nFailedCount == nBatchCount) || (nFailedCount > 0 && "N".equals( cIgnoreBatFailed))) {
//raise event E_InPTFailed
e_InPTFailed.raise(ptType,nPTId);
}
}
}
return bComplete;
}
/*
* Called after processing all transition objects.
* Put any clean up code here.
*/
protected void ActionFinalize() throws MbException
{
// none
}
/*---------------------------------------------------------------------------
-- Action Functions / Procedures : Begin
---------------------------------------------------------------------------*/
// none
/*---------------------------------------------------------------------------
-- Action Functions / Procedures : End
---------------------------------------------------------------------------*/
}