Search code examples
cachingjmsdistributedofbiz

How to implement "Distributed cache clearing" in Ofbiz?


We have multiple instances of Ofbiz/Opentaps running. All the instances talk to the same database. There are many tables that are rarely updated hence they are cached and all the instances maintain their individual copies of cache as a standard Ofbiz cache mechanism. But in rare situations when we update some entity using one of many instances then all other instances keep showing dirty cache data. So it requires a manual action to go and clear all the cache copies on other instances as well.

I want this cache clearing operation on all the instances to happen automatically. On Ofbiz confluence page here there is a very brief mention of "Distributed cache clearing". It relies on JMS it seems so whenever an instance's cache is cleared it sends notification over JMS to a topic and other instances subscribing to the same JMS topic clear their corresponding copies of cache upon this notification. But I could not find any other reference or documentation on how to do that? What are the files that need to be updated to set it all up in Ofbiz? An example page/link is what I'm looking for.


Solution

  • Alright I believe I've figured it all out. I have used ActiveMQ as my JMS broker to set it up so here are the steps in Ofbiz to make it working:

    1. Copy activemq-all.jar to framework/base/lib folder inside your Ofbiz base directory.

    2. Edit File base/config/jndiservers.xml: Add following definition inside <jndi-config> tag:

       <jndi-server name="activemq"
         context-provider-url="failover:(tcp://jms.host1:61616,tcp://jms.host2:61616)?jms.useAsyncSend=true&amp;timeout=5000"
         initial-context-factory="org.apache.activemq.jndi.ActiveMQInitialContextFactory"
         url-pkg-prefixes=""
         security-principal=""
         security-credentials=""/>
    

    3. Edit File base/config/jndi.properties: Add this line at the end:

    topic.ofbiz-cache=ofbiz-cache
    

    4. Edit File service/config/serviceengine.xml: Add following definition inside <service-engine> tag:

        <jms-service name="serviceMessenger" send-mode="all">
           <server jndi-server-name="activemq"
           jndi-name="ConnectionFactory"
           topic-queue="ofbiz-cache"
           type="topic"
           listen="true"/>
        </jms-service>
    

    5. Edit File entityengine.xml: Change default delegator to enable distributed caching:

    <delegator name="default" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main" distributed-cache-clear-enabled="true">
    

    6. Edit File framework/service/src/org/ofbiz/service/jms/AbstractJmsListener.java: This one is probably a bug in the Ofbiz code

    Change following line from:

    this.dispatcher = GenericDispatcher.getLocalDispatcher("JMSDispatcher", null, null, this.getClass().getClassLoader(), serviceDispatcher);
    

    To:

    this.dispatcher = GenericDispatcher.getLocalDispatcher("entity-default", null, null, this.getClass().getClassLoader(), serviceDispatcher);
    

    7. And finally build the serviceengine code by issuing following command:

    ant -f framework/service/build.xml
    

    With this entity data changes in Ofbiz on one instances are immediately propagated to all the other Ofbiz instances clearing cache line item on its own without any need of manual cache clearing.

    Cheers.