Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
EHcache Replication Caching based on MDB The current implementation of the JMS based EHcache replication mechanism is based on industrial standards and was developed to work in a non-managed environment (i.e. outside an Application Server). In a managed environment, the allocation and management of resource (e.g. data sources, queue listeners…) is in the responsibility of the container and clearly regulated by the Java EE specification. This fact causes problems to the current EHcache JMS replication implementation, as it tries to open a listener to a JMS queue by itself. In regard of Java EE, queue listeners have to be implemented as MDB (message driven bean) that is configured as component within the EJB module of a Java EE application. The following MDB replication mechanism takes care of this fact and tries to leverage all the features of a Java EE compatible application design: Transaction management; the data changes which are responsible for the change in the cache are running in the same transaction as the delivering of the message to the queue. Resource management; the references to the queue are no longer part of the application. The application is able to retrieve the required resources via references to resources that are defined on container level. Changes on the infrastructure (e.g. physical location of queues…) can be handled on Application Server level and no application redeployment/reconfiguration is required. Security; the security credentials for accessing protected resources are not longer part of the application. These settings belong to the resource configuration on the Application Server and ensures that developers do not have to care on productive passwords. Required Configuration on the Application Server Due to the vendor specific differences, this chapter will not describe how to configure the resources. It will show what kind of resources have to be available and configured. Topic Provider; a topic queue has to be available where the message can be published to and consumed from. JMS Topic Connection Factory; required for open a connection to the topic and placing messages. JMS Topic; required for publishing messages a message into the topic. Activation Specification; will be responsible that MDB is called when new messages are published in the topic. Required Configuration of the Java EE Module There are additional configurations required within the EJB module of a Java EE application to ensure EHcache is capable to replicate its state via a JMS topic: 1. Each EJB that makes use of EHcache requires two additional resource references. One to the JMS Topic and one for the JMS Topic Connection Factory. 2. One additional MDB has to be configured that is activated by the Activation Specification. All these configurations have to happening in the ejb-jar.xml of the EJM module. In the example configuration it’s assumed that only one session bean exists that is EHcache. The bean is using a data source for reading the data from a database and caches the entities. To ensure updates on entities are propagated within the whole cluster, the session bean requires to message destination references, one to the JMS Topic and one to the JMS Topic Connection Factory. <session id="MyService"> <ejb-name>MyServiceName</ejb-name> <home>com.org.prj.module.MyServiceHome</home> <remote>com.org.prj.module.MyService</remote> <ejb-class>com.org.prj.module.MyServiceBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <resource-ref id="ResourceRef_1268037117237"> <description/> <res-ref-name>jdbc/myDS</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> <message-destination-ref id="MessageDestinationRef_1268081747511"> <description/> <message-destination-ref-name>jms/myTopic</message-destination-ref-name> <message-destination-type>javax.jms.Topic</message-destination-type> <message-destination-usage>Produces</message-destination-usage> <message-destination-link>MyDestination</message-destination-link> </message-destination-ref> <message-destination-ref id="MessageDestinationRef_1268081747495"> <description/> <message-destination-ref-name>jms/myTopicCF</message-destination-ref-name> <message-destination-type>javax.jms.TopicConnectionFactory</message-destination-type> <message-destination-usage>Produces</message-destination-usage> <message-destination-link>MyDestination</message-destination-link> </message-destination-ref> </session> Further more, it has to be ensured that the caches can consume update notifications from other Application Servers which build a cluster. For doing so, an additional MDB has to be configured. There’s no programming required, the MDB is provided as part of the MDB replication extension of EHcache. The following configuration has to be added to the enterprise bean section of the ejb-jar.xml: <message-driven id="CachePeerBean"> <ejb-name>EHcachePeerBean</ejb-name> <ejb-class>net.sf.ehcache.distribution.mdb.CachePeerBean</ejb-class> <messaging-type>javax.jms.MessageListener</messaging-type> <transaction-type>Container</transaction-type> <message-destination-type>javax.jms.Topic</message-destination-type> <message-destination-link>MyDestination</message-destination-link> <activation-config> <activation-config-property> <activation-config-property-name>acknowledgeMode</activation-config-propertyname> <activation-config-property-value>Auto-acknowledge</activation-config-propertyvalue> </activation-config-property> <activation-config-property> <activation-config-property-name>destinationType</activation-config-propertyname> <activation-config-property-value>javax.jms.Topic</activation-config-propertyvalue> </activation-config-property> <activation-config-property> <activation-config-property-name>subscriptionDurability</activation-configproperty-name> <activation-config-property-value>NonDurable</activation-config-property-value> </activation-config-property> </activation-config> </message-driven> And last, the assembly descriptor section has to be extended/created. <assembly-descriptor> <message-destination> <description/> <message-destination-name>MyDestination</message-destination-name> </message-destination> </assembly-descriptor> Most Application Server vendors do offer to deploy there logical to physical bindings in so called xmi files (e.g. ejb-jar-bnd.xmi). This document will not going more deeper into this and assumes that the reader is familiar with its own container specific deployment and mapping procedure. Required Configuration for the EHcache The configuration of the EHcache configuration file is very simple as most of the configuration work was done in the Application Server and application level. The cache manager peer provider factory does not required any specific properties as the configuration is managed in the ejb-jar.xml file. The only reason of adding this configuration is to ensure EHcache knows about MDB that is configured. For each replicated cache, a cache event listener factory has to be defined. This factory ensures that the changes in the cache are propagated to its peers. The type of changes that can be propagated are defined in the properties of the factory. In addition to the replication settings, the topic configurations are required. <?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false" monitoring="autodetect"> <diskStore path="java.io.tmpdir"/> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.mdb.MDBCacheManagerPeerProviderFactory" properties="" propertySeparator="," /> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskSpoolBufferSizeMB="30" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <cache name="MyCache" maxElementsInMemory="5000" eternal="fase" overflowToDisk="true"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.mdb.MDBCacheReplicationFactory" properties="replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true, topicConnectionFactoryBindingName=java:comp/env/jms/myTopicCF, topicBindingName=java:comp/env/jms/myTopic, topicTransacted=false, topicAcknowledgeMode=1" propertySeparator=","/> </cache> </ehcache> Configuration properties (default value are marked with a *): replicatePuts: [true|false*], if true all element put actions will be replicated to peers. replicateUpdates: [true*|false], if true all element update actions will be replicated to peers. replicateUpdatesViaCopy: [true|false*], if true the new element will be submitted with the message, else the element will be removed in the peer caches. replicateRemovals: [true|false*], if true all element remove actions will be replicated to peers. topicConnectionFactoryBindingName: JNDI reference to the topic connection factory as defined on the EJB deployment descriptor. topicBindingName: JNDI reference to the topic as defined on the EJB deployment descriptor. topicTransacted: [true|false*] if true the JMS session is created as transacted. topicAcknowledgeMode: [1*|2|3] indicates whether the consumer or the client will acknowledge any messages it receives; ignored if the session is transacted. Acknowledge modes are the constant field values of the javax.jms.Session: 1: AUTO_ACKNOWLEDGE 2: CLIENT_ACKNOWLEDGE 3: DUPS_OK_ACKNOWLEDGE Limitations In contrary to the EHcache JMS replication mechanism no asynchronous replication feature is provided where several changes can be buffered and submitted as one “package”. This is due to the container limitations of the Java EE specification, where it is not allowed to create threads. This makes absolutely sense, as with an own thread, both the transaction and security context would be lost, and a proper replication can’t be ensured. Further more, there’s no support for message types different than a Java object. Meaning, only Java clients can participate in the cache cluster. If the transactional support is enabled, and multiple resources are participating in such a transaction, it has to be ensured that all resources are XA capable. The current implementation assumes that both, the services that are using the cache and the MDB are part of the same EJB module of the Java EE application. Depending of the application’s and the Application Server’s configuration, this implementation is not working properly when the cache usage is part of a web or separate EJB module (i.e. if the EJB and web module do have different class loaders the implementation will fail). The Outlook chapter is going into this topic. By the same reason, this implementation is not capable to handle multiple cache manager instances. Outlook The current implementation is very fragile in regard of an Application Server’s class loader configuration (i.e. the MDB does has a static reference to the cache manager). This is some kind of a hack that should be implemented in a better, a JDNI based way. For doing so, the MDBCacheReplicatorFactory would require an additional property which is specifying where in the JNDI the cache manager has to be placed. In addition to this, the MDBCacheManagerPeerProviderFactory requires the same property, to know from where in the JNDI the cache manager has to be retrieved. With this approach, also the multi cache manager support would be ensured. One additional improvement would be to usage of a message selector as part of the Activation Specification of the MDB. With this, it could be ensured that message produced by the replicator that is referencing the same instance of the cache manager as the MDB, is filtered out. Currently the MDB is re-applying the changes to the cache for the actions that are produced on its own application node. For the case the non-Java clients are part of a cache cluster, a technology independent message format could be introduced (e.g. XML based string message).