Per Infinispan Cache Properties - infinispan

We have some generic code that operates on the caches in an Infinispan cache container. The code identifies certain caches for which a certain operation has to be performed by a custom property. The cache container and caches are configured through infinspan.xml or the Infinispan subsystem in WildFly.
Previously we would set a custom property on the datastore of the cache. With Infinispan 10+ this is no longer possible. We would have to implement a custom persistence store in order to set arbitrary properties on a cache. This seems like overkill especially since our caches are not persistent.
Is there a way to achieve this from an infinspan.xml, eg. without putting a custom object under a well known key in the cache?
Edit
The previous configuration looked something like this:
<local-cache name="stackoverflow-cache" configuration="default-configuration">
<data-container>
<property name="custom-property-key">custom-property-value</property>
</data-container>
</local-cache>
With version 10 of the Infinispan schema this is no longer supported.

I've made an example of how you can set some custom properties in the configuration here. It isn't trivial...
If you are using Infinispan server, you need a Jar with your classes and put it in server/lib folder.
Let me know if it fits your use case (I hope I didn't misunderstand it).
ps. since you control the parser, you can set your own XML structure if you want.

Related

Camel readlock strategy in cluster

We are trying to move to cluster with Apache Camel. So far we had it on one node and worked well.
One node:
I have readlock strategy set to 'changed' which keeps track of file changes with camelLock file and only when the file has finished downloading, it will be picked up for processing. But camel readlock strategy 'changed' is discouraged in clustering. According to the camel documentation 'idempotent' is recommended. This is what happens when I am testing with 5GB file.
Two nodes:
I have readlock strategy to 'idempotent' which distributes files to one of the nodes but camel starts processing the file even before the file has finished downloading.
Is there a way to stop camel from processing even before file has downloaded when readlock strategy is idempotent?
Even though both "readLock=changed" and "readLock=idempotent" cause the file-consumer to wait, they really address quite different use-cases: while "readLock=changed" guards against the file being incomplete (i.e. still being written by some producer/sender), "readLock=idempotent" guards against a file being read by two consumer routes. It's a bit confusing that they're addressed by the same option.
First, to address the "changed" scenario: can the sender be changed so that it writes the file in one directory and then, when it is done writing, it copies it into the directory being monitored by your file-consumer? If this is under your control, this is a good way of letting the OS handle things instead of trying to deal with it yourself. (This does not address the issue of the multiple readers.) Otherwise, I suggest you revert back to readLock=changed
Next, on multiple readers, one work around is to only have this route run on only one node of your cluster. Sometimes this might defeat the purpose of clustering, but it is quite possible that you're starting up additional nodes to help with some other routes, and you're fine with this particular route running on just one node. It's a bit of a hack to do something like this, because all nodes are no longer equal, but it is still an option to consider. Simplest would be to start one node with some environment property that flags it as the node that will handle file-reading... or some similar approach.
If you do want the route on multiple nodes, you can start by using the option "idempotent=true" but this is not good enough on its own. The option uses a repository, where it records what files have been read before, and the default repository is in-memory (i.e. each node has its own). So, the default implementation is helpful if the same file is actually being received more than once, and you wish to skip it. However, if you want it to work across nodes, you have to use a different repository.
One central repository could be a database. In that case use can use Camel's JDBC or JPA based repositories. Or, you could use something like Hazelcast. See here for your options: http://camel.apache.org/idempotent-consumer.html
You can use readLock=idempotent-changed.
idempotent-changed is for using an idempotentRepository and changed as the combined read-lock. This allows you to use read locks that supports clustering if the idempotent repository implementation supports that.
You can read more about these idempotent-changed options here: https://camel.apache.org/components/3.13.x/file-component.html
We also used readLock=changed in Docker clustered mode and worked perfectly since we used readLockMinAge for certain interval.

Reading different properties for different cluster/node

I have developed a hybrid worklight app and everything is set up. Now my case is that I have a load balance and two clusters. These two clusters have been synchronized with only one WAR file. Due to some reason, we have a server java file in the WAR for sharing some global variables with worklight adapters.
The problem now is that these 2 clusters are working independently (will be redirected by the load balance). The global variables in the JAVA file inside their WAR will not be shared. How can we maintain only one set of global variable in this case?
Or is there any method for the JAVA to read the current cluster detail(for example cluster id or IP address) so that I can write logic to point to different properties in worklight.properties
[PS: not good at English. I will clarify more if you guys don't understand me]
What you actually need here is not to use static variables to share this information.
I suggest using Redis or Memcached (or some other free solution) to share information across the cluster.
A simpler solution (but less efficient) can be using an SQL database to store/load those shared properties. You can actually create a "configuration" adapter (SQL adapter) which will be called by the other adapters to read/write the configuration properties.

Tools used to update dynamic properties without even restarting the application/server

In my project I am trying to do the setting where in I can update the dynamic properties in the server/application without even restarting it.
We face this problem that whenever we have to update or change some properties which are dynamic in nature, then every time we have to restart the server/application and this results in unavailability of the server for that time stamp.
I have already found one tool Archaius-ZooKeeper to set it.https://github.com/Netflix/archaius/
We are trying to do it for JBoss servers where we use war file to deploy on server.
Please suggest are there any other method or tool or technology that can be used to set it.
Thanks in advance.
You could consider jRebel, allows you to redeploy your app without any downtime, then you can use jRebel Remoting to redeploy from eclipse to a remote server
You may use Zookeeper. You have to create a Znode and add the properties in the Znode. All your servers/applications should read from this Znode and also put an watch on this Znode for data changes.
Alternately, you may use a database to store the properties along with their modification time. Whenever you change the value of a property, the corresponding modification time is changed. All your applications/servers keep pulling the delta at some intervals (may be 2 secs/ 5 secs etc.).
Or you may have the properties hosted on a web server, or on NFS, or on some distributed cache etc. All your applications/servers keep reading it at some intervals for detecting any changes.
You can use Spring Cloud Zookeeper. I shared a little example here.

Custom cache dependencies in NHibernate

Anyone ever got custom cache dependencies working with NHibernate second level query cache (i.e. using overrides of the .NET CacheDependency)?
I'm pretty sure it is not possible out-of-the-box, but I know that NHibernate is pretty hackable.
The cache region system doesn't really support the flexibility you have when you can instantiate a cache dependency as you put data into the cache.
Here's what the code might look like:
Session.CreateCriteria<Foo>("foo")
.SetCacheable()
.Add(Restriction.Eq("foo.Name", fooName))
.AddCacheDependency(new MyCustomCacheDependency(fooName))
.List<Foo>();
Cache dependencies are handled by the cache providers, not the core.
There are some examples of DB-based expiration in the documentation for the SysCache2 provider.

Disable cache for one model

I got a table which is modified by two applications. One of them is using nhibernate. How do I disable caching for that table? Can it be done in the mapping file?
Cache is not enabled by default.
If you are referring to the "first level cache", i.e. the Session, there is something wrong with your usage pattern.
Assuming you have the L2 cache enabled for the session factory (via cache.use_second_level_cache), you should be able to exclude the <cache> element in your mapping file for that model.