CLOVER🍀

That was when it all began.

Infinispanの設定ファイルのdefaultタグについて

Infinispanの設定ファイルのdefaultタグですが、どうもちゃんと理解しないまま使っていたようです…。まあ、なんとなくそんな素振りは見えていた気がしますが。

設定ファイルに書く

<default>
  <!-- 各種設定 -->
</default>

の部分は、他のCacheのデフォルトの設定となり、namedCacheタグやConfigurationのAPIで再定義することで、オーバーライドすることができます。

Configuring Cache declaratively
https://docs.jboss.org/author/display/ISPN/Configuring+Cache+declaratively

Every time you define element in XML configuration file, in addition to cache element, you are effectively configuring additional caches whose settings are inheriting and/or overriding the default cache.

https://docs.jboss.org/author/display/ISPN/Configuring+Cache+declaratively

defaultの内容を継承するって書いてますねー。

ConfigurationのAPIで組み立てる場合は、defaultは設定ファイルで決めなくてはならない感じがしますけど。

Configuring cache programmatically
https://docs.jboss.org/author/display/ISPN/Configuring+cache+programmatically

で、気付いてしまったからには、ちょっと確認してみましょう。

確認のために、こんなトレイトを用意しました。

import org.infinispan.Cache
import org.infinispan.configuration.cache._
import org.infinispan.configuration.global.GlobalConfigurationBuilder
import org.infinispan.manager.{DefaultCacheManager, EmbeddedCacheManager}
import org.infinispan.transaction.{LockingMode, TransactionMode}
import org.infinispan.transaction.lookup.GenericTransactionManagerLookup

trait InfinispanCacheConfigurationPrintSupport {
  protected def createCacheManager: EmbeddedCacheManager

  def run(): Unit = {
    val manager = createCacheManager

    val defaultCache = manager.getCache[Any, Any]()
    val simpleNamedCache = manager.getCache[Any, Any]("simpleNamedCache")
    val namedCacheOverride = manager.getCache[Any, Any]("namedCacheOverride")

    try {
      for (cache <- List(
        defaultCache,
        simpleNamedCache,
         namedCacheOverride)) {
        println(s"========================= CacheName[${cache.getName}] =========================")
        print(cache.getCacheConfiguration.toString.replaceAll("(\\{|\\})", "$1\n"))
        println(s"========================= CacheName[${cache.getName}] =========================")
      }

      println(System.lineSeparator * 3)

      val cacheConfigurationString =
      (cache: Cache[_, _]) =>
      cache
        .getCacheConfiguration
        .toString
        .replaceAll("(\\{|\\})", "$1\n")
        .replaceAll("""@[0-9a-z]+""", "")

      val defaultCacheDefinition = cacheConfigurationString(defaultCache)

      for ((name, definition) <- List(
        (simpleNamedCache.getName, cacheConfigurationString(simpleNamedCache)),
        (namedCacheOverride.getName, cacheConfigurationString(namedCacheOverride))
      )) {
        val (_, diff) =
          defaultCacheDefinition.zip(definition)
            .span { case (c1, c2) => c1 == c2 }

        println(s"******************** defaultCache diff $name, Start ********************")
        diff.foreach { case (_, c) => print(c) }
        println(s"******************** defaultCache diff $name, End   ********************")
      }
    } finally {
      defaultCache.stop()
      simpleNamedCache.stop()
      namedCacheOverride.stop()

      manager.stop()
    }
  }
}

利用するCacheは3つ、default、何も設定しないCache(simpleNamedCache)、追加の設定を行ったCache(namedCacheOverride)です。これらの設定内容を、Cache#getCacheConfiguration#toStringで文字列化し、簡易的に差分を見てみようというコードです。

最初に、それぞれの設定内容が出力され、その後にdefaultの定義内容と相違が検出された場合は、検出地点からの内容が出力されます。

この部分です。

        println(s"******************** defaultCache diff $name, Start ********************")
        diff.foreach { case (_, c) => print(c) }
        println(s"******************** defaultCache diff $name, End   ********************")

Configuring Cache declaratively

では、まずは設定ファイルで明示的に定義する方から。用意した設定ファイルは、こんな感じです。

<?xml version="1.0" encoding="UTF-8"?>
<infinispan
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:infinispan:config:5.3 http://www.infinispan.org/schemas/infinispan-config-5.3.xsd"
    xmlns="urn:infinispan:config:5.3">

  <global>
    <transport clusterName="configuration-cluster">
      <properties>
        <property name="configurationFile" value="jgroups.xml" />
      </properties>
    </transport>
    <globalJmxStatistics
        enabled="true"
        jmxDomain="org.infinispan"
        cacheManagerName="DefaultCacheManager"
        />
  </global>

  <default>
    <clustering mode="distribution" />
    <transaction
        transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
        transactionMode="TRANSACTIONAL"
        lockingMode="PESSIMISTIC"
        autoCommit="true" />
  </default>

  <namedCache name="simpleNamedCache" />

  <namedCache name="namedCacheOverride">
    <storeAsBinary enabled="true" />
    <invocationBatching enabled="true" />

    <transaction
        lockingMode="OPTIMISTIC"
        autoCommit="false" />
  </namedCache>
</infinispan>

namedCacheOverrideは、storeAsBinary、バッチの有効化、トランザクションの属性を一部変更って感じにしてます。

で、先ほどのトレイトを単純にMix-inしたオブジェクトを定義して

object InfinispanDeclarativeConfiguration extends InfinispanCacheConfigurationPrintSupport {
  protected def createCacheManager: EmbeddedCacheManager =
    new DefaultCacheManager("infinispan.xml")

  def main(args: Array[String]): Unit =
    run()
}

実行します。

> run-main InfinispanDeclarativeConfiguration
[info] Running InfinispanDeclarativeConfiguration

最初の出力結果は、こんな感じ。

[info] ========================= CacheName[___defaultcache] =========================
[info] Configuration{
[info] classLoader=java.lang.ref.WeakReference@7f676908, clustering=ClusteringConfiguration{
[info] async=AsyncConfiguration{
[info] asyncMarshalling=false, replicationQueue=null, replicationQueueInterval=5000, replicationQueueMaxElements=1000, useReplicationQueue=false}
[info] , cacheMode=DIST_SYNC, hash=HashConfiguration{
[info] consistentHashFactory=null, hash=MurmurHash3, numOwners=2, numSegments=60, groupsConfiguration=GroupsConfiguration{
[info] enabled=false, groupers=[]}
[info] , stateTransferConfiguration=StateTransferConfiguration{
[info] chunkSize=10000, fetchInMemoryState=true, originalFetchInMemoryState=null, timeout=240000, awaitInitialTransfer=true, originalAwaitInitialTransfer=null}
[info] }
[info] , l1=L1Configuration{
[info] enabled=false, invalidationThreshold=0, lifespan=600000, onRehash=false, cleanupTaskFrequency=600000}
[info] , stateTransfer=StateTransferConfiguration{
[info] chunkSize=10000, fetchInMemoryState=true, originalFetchInMemoryState=null, timeout=240000, awaitInitialTransfer=true, originalAwaitInitialTransfer=null}
[info] , sync=SyncConfiguration{
[info] replTimeout=15000}
[info] }
[info] , customInterceptors=CustomInterceptorsConfiguration{
[info] interceptors=[]}
[info] , dataContainer=DataContainerConfiguration{
[info] dataContainer=null, keyEquivalence=org.infinispan.commons.equivalence.AnyEquivalence@5e20cd90, valueEquivalence=org.infinispan.commons.equivalence.AnyEquivalence@5e20cd90}
[info] , deadlockDetection=DeadlockDetectionConfiguration{
[info] enabled=false, spinDuration=100}
[info] , eviction=EvictionConfiguration{
[info] maxEntries=-1, strategy=NONE, threadPolicy=DEFAULT}
[info] , expiration=ExpirationConfiguration{
[info] lifespan=-1, maxIdle=-1, reaperEnabled=true, wakeUpInterval=60000}
[info] , indexing=IndexingConfiguration{
[info] enabled=false, indexLocalOnly=false}
[info] , invocationBatching=InvocationBatchingConfiguration{
[info] enabled=false}
[info] , jmxStatistics=JMXStatisticsConfiguration{
[info] enabled=false}
[info] , loaders=LoadersConfiguration{
[info] cacheLoaders=[], passivation=false, preload=false, shared=false}
[info] , locking=LockingConfiguration{
[info] concurrencyLevel=32, isolationLevel=READ_COMMITTED, lockAcquisitionTimeout=10000, useLockStriping=false, writeSkewCheck=false}
[info] , modules={
[info] }
[info] , storeAsBinary=StoreAsBinaryConfiguration{
[info] enabled=false, storeKeysAsBinary=true, storeValuesAsBinary=true, defensive=false}
[info] , transaction=TransactionConfiguration{
[info] autoCommit=true, cacheStopTimeout=30000, eagerLockingSingleNode=false, lockingMode=PESSIMISTIC, syncCommitPhase=true, syncRollbackPhase=false, transactionManagerLookup=org.infinispan.transaction.lookup.GenericTransactionManagerLookup@3b97d937, transactionSynchronizationRegistryLookup=null, transactionMode=TRANSACTIONAL, useEagerLocking=false, useSynchronization=true, recovery=RecoveryConfiguration{
[info] enabled=true, recoveryInfoCacheName='__recoveryInfoCacheName__'}
[info] , reaperWakeUpInterval=1000, completedTxTimeout=15000, use1PcForAutoCommitTransactions=false}
[info] , versioning=VersioningConfiguration{
[info] enabled=false, scheme=NONE}
[info] , unsafe=UnsafeConfiguration{
[info] unreliableReturnValues=false}
[info] , sites=SiteConfiguration{
[info] allBackups=[], backupFor=BackupForConfiguration{
[info] remoteCache='null', remoteSite='null'}
[info] , disableBackups=false, inUseBackupSites=[]}
[info] , compatibility=CompatibilityModeConfiguration{
[info] enabled=false, marshaller=null}
[info] }
[info] ========================= CacheName[___defaultcache] =========================
[info] ========================= CacheName[simpleNamedCache] =========================
[info] Configuration{
[info] classLoader=java.lang.ref.WeakReference@6e35c871, clustering=ClusteringConfiguration{
[info] async=AsyncConfiguration{
[info] asyncMarshalling=false, replicationQueue=null, replicationQueueInterval=5000, replicationQueueMaxElements=1000, useReplicationQueue=false}
[info] , cacheMode=DIST_SYNC, hash=HashConfiguration{
[info] consistentHashFactory=null, hash=MurmurHash3, numOwners=2, numSegments=60, groupsConfiguration=GroupsConfiguration{
[info] enabled=false, groupers=[]}
[info] , stateTransferConfiguration=StateTransferConfiguration{
[info] chunkSize=10000, fetchInMemoryState=true, originalFetchInMemoryState=null, timeout=240000, awaitInitialTransfer=true, originalAwaitInitialTransfer=null}
[info] }
[info] , l1=L1Configuration{
[info] enabled=false, invalidationThreshold=0, lifespan=600000, onRehash=false, cleanupTaskFrequency=600000}
[info] , stateTransfer=StateTransferConfiguration{
[info] chunkSize=10000, fetchInMemoryState=true, originalFetchInMemoryState=null, timeout=240000, awaitInitialTransfer=true, originalAwaitInitialTransfer=null}
[info] , sync=SyncConfiguration{
[info] replTimeout=15000}
[info] }
[info] , customInterceptors=CustomInterceptorsConfiguration{
[info] interceptors=[]}
[info] , dataContainer=DataContainerConfiguration{
[info] dataContainer=null, keyEquivalence=org.infinispan.commons.equivalence.AnyEquivalence@5e20cd90, valueEquivalence=org.infinispan.commons.equivalence.AnyEquivalence@5e20cd90}
[info] , deadlockDetection=DeadlockDetectionConfiguration{
[info] enabled=false, spinDuration=100}
[info] , eviction=EvictionConfiguration{
[info] maxEntries=-1, strategy=NONE, threadPolicy=DEFAULT}
[info] , expiration=ExpirationConfiguration{
[info] lifespan=-1, maxIdle=-1, reaperEnabled=true, wakeUpInterval=60000}
[info] , indexing=IndexingConfiguration{
[info] enabled=false, indexLocalOnly=false}
[info] , invocationBatching=InvocationBatchingConfiguration{
[info] enabled=false}
[info] , jmxStatistics=JMXStatisticsConfiguration{
[info] enabled=false}
[info] , loaders=LoadersConfiguration{
[info] cacheLoaders=[], passivation=false, preload=false, shared=false}
[info] , locking=LockingConfiguration{
[info] concurrencyLevel=32, isolationLevel=READ_COMMITTED, lockAcquisitionTimeout=10000, useLockStriping=false, writeSkewCheck=false}
[info] , modules={
[info] }
[info] , storeAsBinary=StoreAsBinaryConfiguration{
[info] enabled=false, storeKeysAsBinary=true, storeValuesAsBinary=true, defensive=false}
[info] , transaction=TransactionConfiguration{
[info] autoCommit=true, cacheStopTimeout=30000, eagerLockingSingleNode=false, lockingMode=PESSIMISTIC, syncCommitPhase=true, syncRollbackPhase=false, transactionManagerLookup=org.infinispan.transaction.lookup.GenericTransactionManagerLookup@3b97d937, transactionSynchronizationRegistryLookup=null, transactionMode=TRANSACTIONAL, useEagerLocking=false, useSynchronization=true, recovery=RecoveryConfiguration{
[info] enabled=true, recoveryInfoCacheName='__recoveryInfoCacheName__'}
[info] , reaperWakeUpInterval=1000, completedTxTimeout=15000, use1PcForAutoCommitTransactions=false}
[info] , versioning=VersioningConfiguration{
[info] enabled=false, scheme=NONE}
[info] , unsafe=UnsafeConfiguration{
[info] unreliableReturnValues=false}
[info] , sites=SiteConfiguration{
[info] allBackups=[], backupFor=BackupForConfiguration{
[info] remoteCache='null', remoteSite='null'}
[info] , disableBackups=false, inUseBackupSites=[]}
[info] , compatibility=CompatibilityModeConfiguration{
[info] enabled=false, marshaller=null}
[info] }
[info] ========================= CacheName[simpleNamedCache] =========================
[info] ========================= CacheName[namedCacheOverride] =========================
[info] Configuration{
[info] classLoader=java.lang.ref.WeakReference@cfaab3e, clustering=ClusteringConfiguration{
[info] async=AsyncConfiguration{
[info] asyncMarshalling=false, replicationQueue=null, replicationQueueInterval=5000, replicationQueueMaxElements=1000, useReplicationQueue=false}
[info] , cacheMode=DIST_SYNC, hash=HashConfiguration{
[info] consistentHashFactory=null, hash=MurmurHash3, numOwners=2, numSegments=60, groupsConfiguration=GroupsConfiguration{
[info] enabled=false, groupers=[]}
[info] , stateTransferConfiguration=StateTransferConfiguration{
[info] chunkSize=10000, fetchInMemoryState=true, originalFetchInMemoryState=null, timeout=240000, awaitInitialTransfer=true, originalAwaitInitialTransfer=null}
[info] }
[info] , l1=L1Configuration{
[info] enabled=false, invalidationThreshold=0, lifespan=600000, onRehash=false, cleanupTaskFrequency=600000}
[info] , stateTransfer=StateTransferConfiguration{
[info] chunkSize=10000, fetchInMemoryState=true, originalFetchInMemoryState=null, timeout=240000, awaitInitialTransfer=true, originalAwaitInitialTransfer=null}
[info] , sync=SyncConfiguration{
[info] replTimeout=15000}
[info] }
[info] , customInterceptors=CustomInterceptorsConfiguration{
[info] interceptors=[]}
[info] , dataContainer=DataContainerConfiguration{
[info] dataContainer=null, keyEquivalence=org.infinispan.commons.equivalence.AnyEquivalence@5e20cd90, valueEquivalence=org.infinispan.commons.equivalence.AnyEquivalence@5e20cd90}
[info] , deadlockDetection=DeadlockDetectionConfiguration{
[info] enabled=false, spinDuration=100}
[info] , eviction=EvictionConfiguration{
[info] maxEntries=-1, strategy=NONE, threadPolicy=DEFAULT}
[info] , expiration=ExpirationConfiguration{
[info] lifespan=-1, maxIdle=-1, reaperEnabled=true, wakeUpInterval=60000}
[info] , indexing=IndexingConfiguration{
[info] enabled=false, indexLocalOnly=false}
[info] , invocationBatching=InvocationBatchingConfiguration{
[info] enabled=true}
[info] , jmxStatistics=JMXStatisticsConfiguration{
[info] enabled=false}
[info] , loaders=LoadersConfiguration{
[info] cacheLoaders=[], passivation=false, preload=false, shared=false}
[info] , locking=LockingConfiguration{
[info] concurrencyLevel=32, isolationLevel=READ_COMMITTED, lockAcquisitionTimeout=10000, useLockStriping=false, writeSkewCheck=false}
[info] , modules={
[info] }
[info] , storeAsBinary=StoreAsBinaryConfiguration{
[info] enabled=true, storeKeysAsBinary=true, storeValuesAsBinary=true, defensive=false}
[info] , transaction=TransactionConfiguration{
[info] autoCommit=false, cacheStopTimeout=30000, eagerLockingSingleNode=false, lockingMode=OPTIMISTIC, syncCommitPhase=true, syncRollbackPhase=false, transactionManagerLookup=org.infinispan.transaction.lookup.GenericTransactionManagerLookup@3b97d937, transactionSynchronizationRegistryLookup=null, transactionMode=TRANSACTIONAL, useEagerLocking=false, useSynchronization=true, recovery=RecoveryConfiguration{
[info] enabled=true, recoveryInfoCacheName='__recoveryInfoCacheName__'}
[info] , reaperWakeUpInterval=1000, completedTxTimeout=15000, use1PcForAutoCommitTransactions=false}
[info] , versioning=VersioningConfiguration{
[info] enabled=false, scheme=NONE}
[info] , unsafe=UnsafeConfiguration{
[info] unreliableReturnValues=false}
[info] , sites=SiteConfiguration{
[info] allBackups=[], backupFor=BackupForConfiguration{
[info] remoteCache='null', remoteSite='null'}
[info] , disableBackups=false, inUseBackupSites=[]}
[info] , compatibility=CompatibilityModeConfiguration{
[info] enabled=false, marshaller=null}
[info] }
[info] ========================= CacheName[namedCacheOverride] =========================

違いが分かりにくい…。

差分の方は、こんな感じです。

[info] ******************** defaultCache diff simpleNamedCache, Start ********************
[info] ******************** defaultCache diff simpleNamedCache, End   ********************
[info] ******************** defaultCache diff namedCacheOverride, Start ********************
[info] true}
[info] , jmxStatistics=JMXStatisticsConfiguration{
[info] enabled=false}
[info] , loaders=LoadersConfiguration{
[info] cacheLoaders=[], passivation=false, preload=false, shared=false}
[info] , locking=LockingConfiguration{
[info] concurrencyLevel=32, isolationLevel=READ_COMMITTED, lockAcquisitionTimeout=10000, useLockStriping=false, writeSkewCheck=false}
[info] , modules={
[info] }
[info] , storeAsBinary=StoreAsBinaryConfiguration{
[info] enabled=true, storeKeysAsBinary=true, storeValuesAsBinary=true, defensive=false}
[info] , transaction=TransactionConfiguration{
[info] autoCommit=false, cacheStopTimeout=30000, eagerLockingSingleNode=false, lockingMode=OPTIMISTIC, syncCommitPhase=true, syncRollbackPhase=false, transactionManagerLookup=org.infinispan.transaction.lookup.GenericTransactionManagerLookup, transactionSynchronizationRegistryLookup=null, transactionMode=TRANSACTIONAL, useEagerLocking=false, useSynchronization=true, recovery=RecoveryConfiguration{
[info] enabled=true, recoveryInfoCacheName='__recoveryInfoCacheName__'}
[info] , reaperWakeUpInterval=1000, completedTxTimeout=15000, use1PcForAutoCommitTransactions=false}
[info] , versioning=VersioningConfiguration{
[info] enabled=false, scheme=NONE}
[info] , unsafe=UnsafeConfiguration{
[info] unreliableReturnValues=false}
[info] , sites=SiteConfiguration{
[info] allBackups=[], backupFor=BackupForConfiguration{
[info] remoteCache='null', remoteSite='null'}
[info] , disableBackups=false, inUseBackupSites=[]}
[info] , compatibility=CompatibilityModeConfiguration{
[info] enabled=false, marshaller=null}
[info] }

simpleNamedCacheの方は、差分ゼロ。namedCacheOverrideの方は、invocationBatchingの部分から差が出ています。まあ、名前は切れちゃってますけど…。


よくよく見ると、storeAsBinaryや

## default
[info] , storeAsBinary=StoreAsBinaryConfiguration{
[info] enabled=false, storeKeysAsBinary=true, storeValuesAsBinary=true, defensive=false}

## namedCacheOverride
[info] , storeAsBinary=StoreAsBinaryConfiguration{
[info] enabled=true, storeKeysAsBinary=true, storeValuesAsBinary=true, defensive=false}

トランザクションの設定内容に差がありますが、

## default
[info] , transaction=TransactionConfiguration{
[info] autoCommit=true, cacheStopTimeout=30000, eagerLockingSingleNode=false, lockingMode=PESSIMISTIC, syncCommitPhase=true, syncRollbackPhase=false, transactionManagerLookup=org.infinispan.transaction.lookup.GenericTransactionManagerLookup@3b97d937, transactionSynchronizationRegistryLookup=null, transactionMode=TRANSACTIONAL, useEagerLocking=false, useSynchronization=true, recovery=RecoveryConfiguration{
[info] enabled=true, recoveryInfoCacheName='__recoveryInfoCacheName__'}
[info] , reaperWakeUpInterval=1000, completedTxTimeout=15000, use1PcForAutoCommitTransactions=false}

## namedCacheOverride
[info] , transaction=TransactionConfiguration{
[info] autoCommit=false, cacheStopTimeout=30000, eagerLockingSingleNode=false, lockingMode=OPTIMISTIC, syncCommitPhase=true, syncRollbackPhase=false, transactionManagerLookup=org.infinispan.transaction.lookup.GenericTransactionManagerLookup@3b97d937, transactionSynchronizationRegistryLookup=null, transactionMode=TRANSACTIONAL, useEagerLocking=false, useSynchronization=true, recovery=RecoveryConfiguration{
[info] enabled=true, recoveryInfoCacheName='__recoveryInfoCacheName__'}
[info] , reaperWakeUpInterval=1000, completedTxTimeout=15000, use1PcForAutoCommitTransactions=false}

namedCacheOverrideの方、TRANSACTIONALって書いてませんけど、TRANSACTIONALになってますね!!差分定義した属性だけがきっちり変わってますわ…。

Configuring cache programmatically

続いて、ConfigurationのAPIJava側で組み立てる場合。こちらも、先のトレイトをMix-inしたオブジェクトを用意しました。

なお、このパターンは2つの方法で試しています。まずは、defaultのCacheの内容は、設定ファイルで定義する方法。

object InfinispanProgrammaticalConfiguration extends InfinispanCacheConfigurationPrintSupport {
  protected def createCacheManager: EmbeddedCacheManager = {
    val manager = new DefaultCacheManager("infinispan-default.xml")
    val defaultCacheConfiguration = manager.getDefaultCacheConfiguration

    manager.defineConfiguration("namedCacheOverride",
                                new ConfigurationBuilder()
                                  .read(defaultCacheConfiguration)
                                  .storeAsBinary
                                  .enable
                                  .invocationBatching
                                  .enable
                                  .transaction
                                  .lockingMode(LockingMode.OPTIMISTIC)
                                  .autoCommit(false)
                                  .build)

    manager
  }

  def main(args: Array[String]): Unit =
    run()
}

defaultのConfigurationを取得して、ConfigurationBuilder#readでコピーしているところがポイントです。

    val defaultCacheConfiguration = manager.getDefaultCacheConfiguration

    manager.defineConfiguration("namedCacheOverride",
                                new ConfigurationBuilder()
                                  .read(defaultCacheConfiguration)

defaultのCacheを定義した、XMLファイル。

<?xml version="1.0" encoding="UTF-8"?>
<infinispan
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:infinispan:config:5.3 http://www.infinispan.org/schemas/infinispan-config-5.3.xsd"
    xmlns="urn:infinispan:config:5.3">

  <global>
    <transport clusterName="configuration-cluster">
      <properties>
        <property name="configurationFile" value="jgroups.xml" />
      </properties>
    </transport>
    <globalJmxStatistics
        enabled="true"
        jmxDomain="org.infinispan"
        cacheManagerName="DefaultCacheManager"
        />
  </global>

  <default>
    <clustering mode="distribution" />
    <transaction
        transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
        transactionMode="TRANSACTIONAL"
        lockingMode="PESSIMISTIC"
        autoCommit="true" />
  </default>
</infinispan>

ここには、名前付きCacheの設定は書きません。

では、実行。

> run-main InfinispanProgrammaticalConfiguration
[info] Running InfinispanProgrammaticalConfiguration

結果は、先の設定ファイルで書いた例と変わらないので、割愛します。

もう1パターンは、全部APIで書いてしまう方法。

object InfinispanProgrammaticalConfiguration extends InfinispanCacheConfigurationPrintSupport {
  protected def createCacheManager: EmbeddedCacheManager = {
    val globalConfiguration =
      new GlobalConfigurationBuilder()
        .transport
        .defaultTransport
        .clusterName("configuration-cluster")
        .addProperty("configurationFile", "jgroups.xml")
        .globalJmxStatistics
        .enable
        .jmxDomain("org.infinispan")
        .cacheManagerName("DefaultCacheManager")
        .build

    val defaultCacheConfiguration =
      new ConfigurationBuilder()
        .clustering
        .cacheMode(CacheMode.DIST_SYNC)
        .transaction
        .transactionManagerLookup(new GenericTransactionManagerLookup)
        .transactionMode(TransactionMode.TRANSACTIONAL)
        .lockingMode(LockingMode.PESSIMISTIC)
        .autoCommit(true)
        .build

    val manager = new DefaultCacheManager(globalConfiguration, defaultCacheConfiguration)

    manager.defineConfiguration("namedCacheOverride",
                                new ConfigurationBuilder()
                                  .read(defaultCacheConfiguration)
                                  .storeAsBinary
                                  .enable
                                  .invocationBatching
                                  .enable
                                  .transaction
                                  .lockingMode(LockingMode.OPTIMISTIC)
                                  .autoCommit(false)
                                  .build)

    manager
  }

  def main(args: Array[String]): Unit =
    run()
}

こちらも、結果は割愛です。

というわけで、defaultのCacheで定義した内容は

  • 設定ファイルで名前付きCacheを設定した場合は、defaultの定義内容を引き継ぐ
  • ConfigurationのAPIを使用した場合は、ConfigurationBuilder#readで引数に指定したConfigurationの内容をテンプレートとして使用する

と共に、個別に設定を上書きできることを確認しました。