150 likes | 284 Views
Admin Server. Sybase epbdb1d.ny.ssmb.com:4100. PBOnline. epblnx50d. epblnx51d. AHCluster – 3GB. ENTCluster – 3GB. GPFCluster – 4GB. CSLCluster – 3GB. REFCluster – 3GB. SQL Server eqpfsqtpdv01.nam.nsroot.net:2431. gpfNode7. gpfNode9. gpfNode5. gpfNode3. gpfNode1. gpfNode10.
E N D
Admin Server Sybase epbdb1d.ny.ssmb.com:4100 PBOnline epblnx50d epblnx51d AHCluster – 3GB ENTCluster – 3GB GPFCluster – 4GB CSLCluster – 3GB REFCluster – 3GB SQL Servereqpfsqtpdv01.nam.nsroot.net:2431 gpfNode7 gpfNode9 gpfNode5 gpfNode3 gpfNode1 gpfNode10 gpfNode2 gpfNode8 gpfNode6 gpfNode4 AccountsData SubLedger InstrumentRefData MarketData GPF Dev Weblogic Domain Structure Container-Level Data Sources AHDatasource SubLedgerFinderXADataSource SubLedgerXADatasource ReferenceDatasource MarketDatasource ProductProcessorDS 11 Processes needed for whole deployement.
Save() Delete() Merge() attachClean() attachDirty() findById() …… PfclientAcctDAO PffundAcctDAO PfsubAcctDAO PfgroupAcctDAO PfrefCodesAcctDAO …. 45 in total Database Core Business Logic and Data Access Classes AHFinderServiceImpl AHFinderProxyImp AHDAOManager AHManagerServiceImpl AHManagerProxyImpl AHCacheAspect clientAcctRegion fundAcctRegion subAcctRegion groupAcctRegion
AHGui Application AHGui.jar Esf_config.xml Container4.0.jar Mule1.4.1.jar GPFServices Application GPFServices.jar Esf_config.xml Container4.0.jar Mule1.4.1.jar ESF (Enterprise Service Framework) Stack Axis:Servlet Axis:JMS
Data Bus Data Bus Data Bus AH DB GPFServices EMS Server AH_esf_config_client.xmlESFAxisConnector AHGUI ESFClient.send() AHFinderServiceFacade.execWSMethod()
Finder Service Functions Common Accounts Getters PfAccount getCSLSubAccount() PfAccount[] getPfClientAccountsByAcronym() PfAccount[] getPfFundAccountsByAcronym() PfAccount[] getPfSubAccountsByProductProcessor() ...... 33 in total Pfgroup getPfGroupByPfGrpId() ...... 6 in total Abstract entities based only on cached data PfAccount getAccountHierarchyByPfId() ClientSummary[] getAllClientSummary() FundSummary[] getAllFundSummary() GroupSummary[] getAllGroupSummary() SubAcctSummary[] getAllSubAcctSummary() Data not cached by Gemfire PfacctAddress getPfacctAddress() PfacctAddress[] getPfacctAddresses() PfrefCodes[] getAllPfrefCodes() Pfexception[] getPfexceptions() True if specified entity exist in cache or DB Boolean isValidClientAcct() Boolean isValidFundAcct() Boolean isValidSubAcct() Boolean isValidSubAcctById() Boolean isValidSubAcctByRootIdAndPortfolioId() Clear caches and Reload From Database void refreshCache() Manager Service Functions Hibernate Save, children entities will also be saved. E.g. SubAcctEQRef PfAccount updateClientAccount(PfclientAcct clientAccount) PfAccount updateFundAccount(PffundAcct fundAccount) PfAccount updateSubAccount(PfsubAcct subAccounts) Hibernate Save, children entities will NOT be saved, e.g. childrenAccounts PfAccount updateAccount(PfAccount account) Pfgroup addGroup(Pfgroup pfgroup) Pfgroup updateGroup(Pfgroup pfgroup) Integer deleteGroup(Integer pfGrpId, Integer version) Changing Hierarchy Structure, ActionXXX stored procedures Handled PfAccount addClientAccount(AddClient addClient) Integer deleteClientAccount(DeleteClient deleteClient) PfAccount mergeClientAccount(MergeClient mergeClient) PfAccount addFundAccount(AddFund addFund) Integer deleteFundAccount(DeleteFund deleteFund) PfAccount mergeFundAccount(MergeFund mergeFund) PfAccount addSubAccount(AddSubAcct addSubAccount) Integer deleteSubAccount(DeleteSubAcct deleteSubAccount) PfAccount updateParentAccount(UpdateParent updateParent) Convert CITI data to PF data, UpdDDIXXX stored procedures handled PfAccount[] setPFFundAcctFromDDI(Integer citiId) PfAccount[] setPFSubAcctFromDDI(Integer citiId)
Cache Handling – CacheAspect Spring Advice Types Before advice: Executes before a method enters execution. After returning advice: Executed after a method completes normally. After throwing advice: Executed if a method exits by throwing an exception. After (finally) advice: Executed regardless of the means by which a method exits. Around advice: Perform custom behavior before and after the method invocation. Objective When reading data, use cache instead of database When writing data, update cache as necessary Aspects Defined in AHServiceContext.xml <aop:around method="getAccountsFromCache" pointcut="execution(* .AHFinderService.getPf*Accounts*(..))" /> <aop:around method="getAccountFromCache" pointcut="execution(* .AHFinderService.getPf*AccountBy*(..))" /> <aop:around method="getAccountFromCache" pointcut="execution(* .AHFinderService.getCSLSubAccount(..))" /> <aop:around method="getGroupsFromCache" pointcut="execution(* .AHFinderService.getPf*Groups*(..))" /> <aop:around method="getGroupFromCache" pointcut="execution(* .AHFinderService.getPfGroupBy*(..))" /> <aop:around method="isValid" pointcut="execution(* .AHFinderService.isValid*(..))" /> <aop:around method="getAccountHierarchyByPfId" pointcut="execution(* .AHFinderService.getAccountHierarchyByPfId(..))" /> <aop:around method="getAllClientSummary" pointcut="execution(* .AHFinderService.getAllClientSummary(..))" /> <aop:around method="getAllFundSummary" pointcut="execution(* .AHFinderService.getAllFundSummary(..))" /> <aop:after-returning method="putInCache" pointcut="execution(* AHManagerService.add*Account(..))" /> <aop:after-returning method="putInCache" pointcut="execution(* AHManagerService.update*Account(..))" /> <aop:after-returning method="putPfAccountsInCache" pointcut="execution(* AHManagerService.set*(..))" /> <aop:after-returning method="putInCache" pointcut="execution(* AHManagerService.merge*Account(..))" /> <aop:after-returning method="removeFromCache" pointcut="execution(* AHManagerService.delete*Account(..))" /> <aop:after-returning method="removeGroupFromCache" pointcut="execution(* AHManagerService.deleteGroup(..))" /> <aop:after-returning method="putGroupInCache" pointcut="execution(* AHManagerService.addGroup(..))" />
public PfAccount getPfClientAcctByAcronymFromCache(ProceedingJoinPoint joinPoint) { • try { • Object[] args = joinPoint.getArgs(); • PfAccount pfAccount = null; • String queryString = "SELECT * FROM /root/ClientAccount r " + • "WHERE r.pfclientAcct.pfClientAcronym = “ + "'" + args[0] + "'"; • Query query = cacheManager.getQueryService().newQuery(queryString); • SelectResults results = (SelectResults) query.execute(); • Iterator iter = sr.iterator(); • if (iter.hasNext()) { • pfAccount = (PfAccount) iter.next(); • } • } • if (null == pfAccount) { • pfAccount = (PfAccount) joinPoint.proceed(); • if (pfAccount != null) { • Region region = cacheManager.getRegion("root/ClientAccount"); • region.put(pfAccount.getPfId(), pfAccount); • AhEventPublisher ahEventPublisher = new AhEventPublisher(); • ahEventPublisher.publish(pfAccount); • ahEventPublisher.close(); • } • } else { • pfAccount.setPfChildAccounts(new PfAccount[0]); • pfAccount.setPfIndirectChildAccounts(new PfAccount[0]); • } • return pfAccount; • } catch (Throwable t) { • AHExceptionUtil.throwAHException(t); • } • } Sample Read Data From Cache Gemfire query to find data, similar to Hibernate If no data found in cache, proceed to AHFinderService to try getting it from database Publish cached data changes to JMS queue Nullify children references to Shrink the size of return object
Mule Data Flow Supported Transports Axis BPM CXF EJB Email File FTP HTTP HTTPS IMAP JDBC Jetty JMS Multicast POP3 RMI Servlet SMTP SOAP STDIO TCP UDP VM WebSphere MQ XMPP
PfAccount AHGUI Data & Function PfClientAccount PfFundAccount PfSubAccount PfGroup PfAccount Challenges SSL HandShaking Exception (certificate file) NoSuchElementException vo object unmatched) Update function doesnot return updated result
ESF Service Config Elements Esf_config_deploy.xml Transformers mule : ObjectToXML mule : JMSMessageToObject mule : ObjectToJMSMessage Mule : ByteArrayToSerializable Ah : AHTransformer Connectors Esf : JmsConnector Esf : AxisConnector Mule : VMConnector Interceptor-Stack Esf : LoggingInterceptor Esf : TimerInterceptor Exception Strategy AHDefaultConnectorExceptionStrategy Profiles Threading Profile Pooling Profile Queue Profile Services Ah : AHFinderService inbound : axis:servlet://AHFinderService inbound : axis:jms://gpf_159122.AHFinderService.request Ah : AHManagerService inbound : axis:servlet://AHManagerService inbound : axis:jms://gpf_159122.AHManagerService.request Mule : BridgeComponent inbound : vm://ahJmsProxy outbound : axis:jms://gpf_159122.Equity.AHNotificationReceiver.request?method=receiveAHEvent outbound : axis:jms://gpf_159122.IPB.AHNotificationReceiver.request?method=receiveAHEvent
<esf-environment-properties> <threading-profile /> <pooling-profile /> <queue-profile /> </esf-environment-properties> <container-context className="org.mule.extras.spring.SpringContainerContext" /> <connector className="com.citi.cibtech.esf.providers.jms.JmsConnector" name="jmsQueueConnector"> <exception-strategy className="com.citi.gpf.ah.utils.AHDefaultConnectorExceptionStrategy" /> </connector> <connector className="com.citi.cibtech.esf.ESFAxisConnector" name="axisConnector" /> <connector name="vmConnector“ className="org.mule.providers.vm.VMConnector" /> <transformers> <transformer name="ObjectToXml" className="org.mule.transformers.xml.ObjectToXml“ returnClass="java.lang.String" /> <transformer name="AHTransformer“ className="com.citi.gpf.ah.utils.AHJmsTransformer" returnClass="java.lang.Object" /> </transformers> <interceptor-stack name="ahIntercept"> <interceptor className="com.citi.cibtech.esf.interceptors.LoggingInterceptor" /> <interceptor className="com.citi.cibtech.esf.interceptors.TimerInterceptor" /> </interceptor-stack> <model name="AHModel"> <esf-descriptor implementation="ahFinderService" name="AHFinderService"> <inbound-router> <endpoint address="axis:servlet://AHFinderService" /> <endpoint address="axis:jms://citi.eqpb.ny.pbapps.gpf_159122.AHFinderService.request" /> </inbound-router> <interceptor name="ahIntercept" /> <properties> <map name="axisOptions"> <property name="allowedMethods" value="getVersionResult,getPfClientAccounts,getPfFundAccounts,getPfSubAccounts,,getAllSubAcctSummary..." /> </map> </properties> </esf-descriptor> </model> ESF Service Config Structure
Utility Classes UIDGenerator – A 24 character-length unique string generator, based on System.currentTimeMillis(), host IP address, and java.security.SecureRandom(“SHA1PRN”). It’s used by AHEventPublished to assign event id. Also used by AhJmsTopicMsgPublisher to set service call id. AHSizeAgent – Make rough calculation of memory consumption size for those stored in cache. Was used by AHCacheAspect getAccountsFromCache(), getAccountHierarchyByID(). Not in use right now. AHContextListener – Registered in web.xml as a listener class. Upon context initilization being finished, it calls AHStartupLoader to load data from database into cach. It also pass the ESF config file to ESFXMLConfigurationBuilder to initilize the ESF framework components. AHDefaultConnectorExceptionStrategy – An extension class to org.mule.impl.DefaultExceptionStrategy, in its defaultHandler(Throwable t) method, it simply output the error message via Log4J, its declared as the exception strategy for JMS connection in esf_config_deploy.xml AHEventPublisher – It’s frequently used AHCacheAspect during most cache data change situations. The method publish(Serializable) convert a cached object (e.g. PfClientAcct) into AHEvent object. The AHEvent object is then dispatched through ESFClient to “vm://ahJmsProxy”. A BridgeComponent declared in esf_config_deploy.xml then resend it to citi.eqpb.ny.pbapps.gpf_159122.Equity.AHNotificationReceiver via Axis JMS channel
The Others Performance Most functions running 2-3 times longer than typical hibernate implementation If service guanrentees that data consistency between Gemfire cache and database why should we get the data from service? Function Flexibility What if we only want part of the result object? What if we need complex searching logic? Data Integrity Does the service always know what’s been changed? Are the interfaces thread safe? Maintain Effort Why so many files need to be changed when we only want to add a single attribute to vo object? Be able to run it in local, for easier coding and debug.