Monday, September 24, 2012

Transaction Audit Information Log - TAIL



TAIL :


Transaction Audit Information Log is a component in MDM Server used to store the audit information associated with mdm server transactions.


This component will be helpful when we are tracking a particular transaction/particualr set of transaction for its behaviour.


For eg: how many times a custom BP is getting invoked,what all are the channels invoking it,what time we are having maximum load/request for a particular transaction etc.


From the name itself it says ,it is an inforamtion log ,so the information should be stored somewhere so that it can be retreived.


The main tables are TRANSACTIONLOG,TRANSACTIONLOGERR(i think it is there only from 9.0.x++) not sure about the lower version.
(A few more tables to log the keys like party id etc are availble pls refere the developer guide for them )
Then how do we retreive these info from the tables ?
Hey we got OOTB transactions like getTransactionLog to do so.
I will try to give a high level picture about the configurations required for enabling TAIL in MDM.


Global :
The TAIL feature is enabled by setting the following property in CONFIGELEMENT
/IBM/DWLCommonServices/TAIL/enabled to true.


By default it will be disbaled.
This configuration we call as the global tail configuration.
Now there are 2 flavours of TAIL.


Sync vs Asycn


I know you already guessed out the difference from the name.


The difference is ,for synchronus behaviour ,the TAIL information should gets lgged along with the transaction as a single unit of work.


i.e the transaction for eg:addPerson(for which we enabled TAIL) is complete only after the TAIL info is logged in the TAIL tables.


In the asychronus way the TAIL info are pushed to TAILQueue(hope u remember this queue-if u dont then have alook at the AdminConsole for the queue configurations) first.


But we cannot run our getTransactionLog txn against a data in the queue,hence what will we do ?


We should have our data some how in the table.Dont worry about that.There is an MDB(Message Driven Bean) TAILMDB which listens to the TAILQueue.


So when ever a message is placed in the tail queue the onMessage() of the MDB gets invoked and this function will call the addTransactionLog function and


write the data to our tables.Hence writing to the tables happens as a seperate unit of work and doesnt stops you transctions(say addPerson) from being complete.


Hence it is called asynchronus.
The configuration for this is /IBM/DWLCommonServices/TAIL/Asynchronous/enabled should be true to enable the same.


Now we need to define for which transaction the TAIL should be enabled.This is done at the CDBUSINESSTXTP with the LOG_IND.


Set this to Y for transactions you need to have the TAIL enabled.There is again a concept of external vs internal transaction which is clearly explained in the developer guide.


Now one behaviour of TAIL we observed is.Assume we have disabled TAIL for a composite transaction in CDBUSINESSTXTP.The global and async are enabled.
i.e
/IBM/DWLCommonServices/TAIL/enabled TRUE


/IBM/DWLCommonServices/TAIL/Asynchronous/enabled TRUE


addCustomer - CDBUSINESSTXTP N


When the transaction say addCustomer(say implemented as a BP) runs successfully nothing will be logged in the tables as we have disbaled tail in the CDBUSINESSTXTP.


But for failures in the transaction the details will be logged in the table.This is governed by another property


/IBM/DWLCommonServices/TAIL/LogNegativeCompositeTransaction/enabled.If the property is enabled I mean set to TRUE , it will log the failures and it will do it for composites only.Look for transactionlogerr table for the error reson code and the error message.

Consider the case where you want to enable TAIL for a custom business proxy ,say maintainCustomerBP(which add/updates).
Enable :
maintainCustomerBP - CDBUSINESSTXTP Y BUSINESS_TX_TP_CD (say 200000).
Also you want to log the party id which is getting add/updated in the EXTERNALLOGTXNKEY.
The transactions called from a BP will not get logged in the TRANSACTIONLOG.(i.e addPerson,addContract,updateParty etc
 called from the custom BP doesnt gets logged even if you enable them in CDBUSINESSTXTP).
To log the partyid,contract id you need to do the below config.
I have an extensio for both if you dont have just use Party or Contract.
INSERT INTO EXTERNALTXNKEY(EXTERN_TX_KEY_ID,BUSINESS_TX_TP_CD,APPLICATION,GROUP_NAME,ELEMENT_NAME,LAST_UPDATE_USER,LAST_UPDATE_DT)
  VALUES(PK1,200000,'TCRM','XPersonBObjExt','PartyId','cusadmin',CURRENT_TIMESTAMP);
 
  
  INSERT INTO EXTERNALTXNKEY(EXTERN_TX_KEY_ID,BUSINESS_TX_TP_CD,APPLICATION,GROUP_NAME,ELEMENT_NAME,LAST_UPDATE_USER,LAST_UPDATE_DT)
  VALUES(PK2,200000,'TCRM','XContractBObjExt','ContractIdPK','cusadmin',CURRENT_TIMESTAMP);
With the above config ,you will start seeing entries in your  EXTERNALLOGTXNKEY.





Tuesday, September 18, 2012

Exploring Websphere(WAS) default queues using WAS Admin Console

This is has got very less to do with MDM .

But it can come handy for people working on EM,Notifcaiotns etc and using the WAS default queue instead of a WMQ for their development works.
Most of the time I wondered about how easy it could have been if there is something like MQ explorer available with WMQ  in  WAS admin console to explore the default queues.

I noticed that it is available in WAS 7(may be even available with 6.1 ) .You can use the following path to explore the messages in the default queues.


Admin console Resources->JMS->Queues > Customer Tail(Your Queue) > Buses > MDM.SIB.server1 > Destinations > CUSTOMER.TAIL(Your Queue) > Queue points > CUSTOMER.TAIL@MDMNode01.server1-MDM.SIB.server1(Runtime) > Messages

You can view the Message body too along with other properties like when the message is placed at the queue etc






Saturday, January 7, 2012

Disabling MDM validations for OOTB business objects

Problem:
Consider a scenario where we need to provide the following fields in the request object
1)AdminContractId,AdminSystemType
2)Phone number/Email -Contact Method
3) Attach Privacy Preferene type/reason ,value etc to the contact methods listed above
The object that will come to our mind are
1)TCRMAdminNativeKeyBObj
2)TCRMContactMethodBObj
3)TCRMPartyContactMethodPrivPrefBObj
Yes you are correct on that.
All these objects can be included in TCRMContractBObj. I decided to create a custom MDM txn(say addMyPreferenceTxn)- (I am using MDM8.5) with TCRMContractBObj as the request object.The response objects doesn't matter for this scenario.
I generated the code,and wrote my logic in the component class which got generated.
When I am about to test the code, it throwed the following errors at my face .

Currency type,ContractStatusType ,Role Type are mandatory. There are a few OOTB external/internal validation on the TCRMContractBObj which makes it mandatory. But for my custom addMyPreferenceTxn I dont want the consumer of the service to provide any dummy values for these 3 fields.

Soultion:
When you genrate the code you will get an EJB project which contains the following class.
 yourmoduleprojectNameTxnBean.
Open that class ,there will be a method  public DWLResponse addMyPreferenceTxn(TCRMContractBObj theBObj) throws DWLBaseException

Here is where you are going to put the extra piece of code to bypass the validation logic.
This piece will be executed after the validations happens but before it enters your component.

I am providing the  code outline for the  addMyPreferenceTxn method.

DWLTransaction txObj = new DWLTransactionPersistent("addMyPreferenceTxn", theBObj, theBObj.getControl());
        DWLResponse retObj = null;
        retObj = executeTx(txObj);
       
        Vector vector = retObj.getStatus().getDwlErrorGroup();
        //Create an iterator for the vector ,iterator through it.


                 DWLError error = vector.get(); 
                //The component ids for currncy typ,role type,status type etc..
                if(error.getComponentType() == 2000 || error.getComponentType() == 2001 || error.getComponentType() == 2002) {

                    //Remove from the iterator.       
           
        }   
     
        //It will be zero if all the validations where success.If it failed for eg:PrivPrefType is empty ,the
        //vector still contains data and that will be returned back.
        if(vector.size() == 0 ) {               
            retObj.setData(theBObj);
            DWLStatus status = new DWLStatus();
            status.setStatus(DWLStatus.SUCCESS);
            retObj.setStatus(status);
           
            try {
                retObj = handleAddMyPreferenceTxn(theBObj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
       
        return retObj;



 Hope that helps!.