EmbeddedCacheManager manager = new DefaultCacheManager("my-config-file.xml"); Cache defaultCache = manager.getCache();
Programmatic Infinispan configuration is centered around CacheManager and ConfigurationBuilder API. Although every single aspect of Infinispan configuration could be set programmatically, the most usual approach is to create a starting point in a form of XML configuration file and then in runtime, if needed, programmatically tune a specific configuration to suit the use case best.
EmbeddedCacheManager manager = new DefaultCacheManager("my-config-file.xml"); Cache defaultCache = manager.getCache();
Configuration c = new ConfigurationBuilder().clustering().cacheMode(CacheMode.REPL_SYNC).build(); String newCacheName = "repl"; manager.defineConfiguration(newCacheName, c); Cache<String, String> cache = manager.getCache(newCacheName);
EmbeddedCacheManager manager = new DefaultCacheManager("infinispan-config-file.xml"); Configuration dcc = cacheManager.getDefaultCacheConfiguration(); Configuration c = new ConfigurationBuilder().read(dcc).clustering().cacheMode(CacheMode.DIST_SYNC).l1().lifespan(60000L).build(); String newCacheName = "distributedWithL1"; manager.defineConfiguration(newCacheName, c); Cache<String, String> cache = manager.getCache(newCacheName);
As long as the based configuration is the default named cache, the previous code works perfectly fine. However, other times the base configuration might be another named cache. So, how can new configurations be defined based on other defined caches? Take the previous example and imagine that instead of taking the default cache as base, a named cache called "replicatedCache" is used as base. The code would look something like this:
EmbeddedCacheManager manager = new DefaultCacheManager("infinispan-config-file.xml"); Configuration rc = cacheManager.getCacheConfiguration("replicatedCache"); Configuration c = new ConfigurationBuilder().read(rc).clustering().cacheMode(CacheMode.DIST_SYNC).l1().lifespan(60000L).build(); String newCacheName = "distributedWithL1"; manager.defineConfiguration(newCacheName, c); Cache<String, String> cache = manager.getCache(newCacheName);
Refer to CacheManager, ConfigurationBuilder, Configuration, and GlobalConfiguration javadocs for more details.
However, users do not have to first read an XML based configuration and then modify it in runtime; they can start from scratch using only programmatic API. This is where powerful ConfigurationBuilder API comes to shine. The aim of this API is to make it easier to chain coding of configuration options in order to speed up the coding itself and make the configuration more readable. This new configuration can be used for both the global and the cache level configuration. GlobalConfiguration objects are constructed using GlobalConfigurationBuilder while Configuration objects are built using ConfigurationBuilder. Let's look at some examples on configuring both global and cache level options with this new API:
One of the most commonly configured global option is the transport layer, where you indicate how an Infinispan node will discover the others:
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder().transport() .clusterName("qa-cluster") .addProperty("configurationFile", "jgroups-tcp.xml") .machineId("qa-machine").rackId("qa-rack") .build();
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .globalJmxStatistics() .build();
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .globalJmxStatistics() .cacheManagerName("SalesCacheManager") .mBeanServerLookupClass(JBossMBeanServerLookup.class) .build();
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .replicationQueueScheduledExecutor() .factory(DefaultScheduledExecutorFactory.class) .addProperty("threadNamePrefix", "RQThread") .build();
Configuration config = new ConfigurationBuilder() .clustering() .cacheMode(CacheMode.DIST_SYNC) .sync() .l1().lifespan(25000L) .hash().numOwners(3) .build();
Configuration config = new ConfigurationBuilder() .eviction() .maxEntries(20000).strategy(EvictionStrategy.LIRS).expiration() .wakeUpInterval(5000L) .maxIdle(120000L) .build();
Configuration config = new ConfigurationBuilder() .locking() .concurrencyLevel(10000).isolationLevel(IsolationLevel.REPEATABLE_READ) .lockAcquisitionTimeout(12000L).useLockStriping(false).writeSkewCheck(true) .transaction() .recovery() .transactionManagerLookup(new GenericTransactionManagerLookup()) .jmxStatistics() .build();
Configuration config = new ConfigurationBuilder() .loaders() .shared(false).passivation(false).preload(false) .addFileCacheStore().location("/tmp").streamBufferSize(1800).async().enable().threadPoolSize(20).build();
The fluent configuration can also be used to configure more advanced or exotic options, such as advanced externalizers:
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .serialization() .addAdvancedExternalizer(PersonExternalizer.class) .addAdvancedExternalizer(999, AddressExternalizer.class) .build();
Configuration config = new ConfigurationBuilder() .customInterceptors().interceptors() .add(new FirstInterceptor()).first() .add(new LastInterceptor()).last() .add(new FixPositionInterceptor()).atIndex(8) .add(new AfterInterceptor()).after(LockingInterceptor.class) .add(new BeforeInterceptor()).before(CallInterceptor.class) .build();