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:
Figure 1. Java Action in RSA
javaActionsRSApic.jpg

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
		---------------------------------------------------------------------------*/		
	}