WildFlyでは、設定を行うのは管理CLIからが推奨だと聞いて。
そういえば、これまで設定ファイルを直接編集してしか、InfinispanのCacheContainerやCacheを定義したり追加したりしたことなかったなぁと思いまして。
その他、最近このあたりのサイト・スレッドを見てやってみようかなと思いまして。
Wildfly 8.1, standalone-ha, use of Infinispan (lib mode) - simple clustering- any hints? tips?
https://community.jboss.org/thread/243428?start=0&tstart=0
Using Infinispan with WildFly 8
http://www.mastertheboss.com/infinispan/using-infinispan-with-wildfly-8
Using Infinispan as a persistency solution
http://blog.arungupta.me/2014/08/using-infinispan-as-persistency-solution/
管理CLIを操作するのにあたり、参考にしたのはもちろんWildFlyとInfinispanのドキュメント。
Infinispan Subsystem
https://docs.jboss.org/author/display/WFLY8/Infinispan+Subsystem
15.5. Use a JBoss AS 7 configured cache
http://infinispan.org/docs/6.0.x/user_guide/user_guide.html#_use_a_jboss_as_7_configured_cache
では、始めてみましょう。
はじめに
とりあえず、WildFlyを起動して管理CLIで接続しないと、話が進みません。
起動。
$ wildfly-8.1.0.Final/bin/standalone.sh
管理CLIで接続。
$ wildfly-8.1.0.Final/bin/jboss-cli.sh You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands. [disconnected /] connect [standalone@localhost:9990 /]
はい。
CacheConatiner/Cacheを定義する
それでは、管理CLIでCacheContainer/Cacheを定義してみましょう。
参考にするのは、こちらです。
Infinispan Subsystem
https://docs.jboss.org/author/display/WFLY8/Infinispan+Subsystem
というか、これないとムリでした。
CacheContainerの定義。
[standalone@localhost:9990 /] /subsystem=infinispan/cache-container=my-cache-container:add() {"outcome" => "success"}
今回定義するCacheContainerの名前は、「my-cache-container」とします。
「add(」の後でタブ保管しようとすると、いろいろ出るのである程度はなんとかなりそう?
[standalone@localhost:9990 /] /subsystem=infinispan/cache-container=my-cache-container:add( aliases= jndi-name= replication-queue-executor= default-cache= listener-executor= start= eviction-executor= module= statistics-enabled=
この時点で、「wildfly-8.1.0.Final/standalone/configuration/standalone.xml」には以下のような記述が入ります。
<cache-container name="my-cache-container"/>
では、Cacheの定義へ。
以下まで入力してタブ保管すると、作成するCacheの種類が表示されます。
[standalone@localhost:9990 /] /subsystem=infinispan/cache-container=my-cache-container/ distributed-cache invalidation-cache local-cache replicated-cache transport
あと、tranportも入ってますか。
今回は「local-cache」を選んで、2つCacheを作成してみます。
[standalone@localhost:9990 /] /subsystem=infinispan/cache-container=my-cache-container/local-cache=my-cache-1:add() {"outcome" => "success"} [standalone@localhost:9990 /] /subsystem=infinispan/cache-container=my-cache-container/local-cache=my-cache-2:add() {"outcome" => "success"}
Cacheの名前は、それぞれ「my-cache-1」と「my-cache-2」とします。
このうち、「my-cache-1」をトランザクション対応しておきましょう。
[standalone@localhost:9990 /] /subsystem=infinispan/cache-container=my-cache-container/local-cache=my-cache-1/transaction=TRANSACTION:add(mode=NON_XA) { "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
リロードを求められるようなので、再起動。
[standalone@localhost:9990 /] reload
はい。
できあがったCacheContainer/Cacheの定義は、このようになっています。
<cache-container name="my-cache-container"> <local-cache name="my-cache-1"> <transaction mode="NON_XA"/> </local-cache> <local-cache name="my-cache-2"/> </cache-container>
それにしても、こういう書き方なんですね…。
[standalone@localhost:9990 /] /subsystem=infinispan/cache-container=my-cache-container/local-cache=my-cache-1/transaction=TRANSACTION:add(mode=NON_XA)
補完は「transaction=」までしかされないので、その後ドキュメントを見ないとわかりませんでしたよ…。
使ってみる
では、定義しただけでは面白くないので、リソースとしてルックアップして使ってみましょう。@Resourceアノテーションでインジェクションして使うところまでを、目標にします。
依存関係の定義。
build.sbt
name := "infinispan-configured-cache" version := "0.0.1-SNAPSHOT" scalaVersion := "2.11.2" organization := "org.littlewings" scalacOptions ++= Seq("-Xlint", "-deprecation", "-unchecked", "-feature") incOptions := incOptions.value.withNameHashing(true) jetty() artifactName := { (version: ScalaVersion, module: ModuleID, artifact: Artifact) => //artifact.name + "." + artifact.extension "javaee7-web." + artifact.extension } val jettyVersion = "9.2.2.v20140723" libraryDependencies ++= Seq( "org.eclipse.jetty" % "jetty-webapp" % jettyVersion % "container", "org.eclipse.jetty" % "jetty-plus" % jettyVersion % "container", "javax" % "javaee-web-api" % "7.0" % "provided", "org.infinispan" % "infinispan-core" % "6.0.2.Final" % "provided" excludeAll( ExclusionRule(organization = "org.jgroups", name = "jgroups"), ExclusionRule(organization = "org.jboss.marshalling", name = "jboss-marshalling-river"), ExclusionRule(organization = "org.jboss.marshalling", name = "jboss-marshalling"), ExclusionRule(organization = "org.jboss.logging", name = "jboss-logging"), ExclusionRule(organization = "org.jboss.spec.javax.transaction", name = "jboss-transaction-api_1.1_spec") ), "org.jgroups" % "jgroups" % "3.4.1.Final" % "provided", "org.jboss.spec.javax.transaction" % "jboss-transaction-api_1.1_spec" % "1.0.1.Final" % "provided", "org.jboss.marshalling" % "jboss-marshalling-river" % "1.4.4.Final" % "provided", "org.jboss.marshalling" % "jboss-marshalling" % "1.4.4.Final" % "provided", "org.jboss.logging" % "jboss-logging" % "3.1.2.GA" % "provided", "net.jcip" % "jcip-annotations" % "1.0" % "provided", "org.scala-lang.modules" %% "scala-xml" % "1.0.2" )
Infinispanの依存関係のスコープは、すべて「provided」にしています。
xsbt-web-pluginが1.0.0-M4になってみたので使ってみたのですが、若干設定方法変わりました?
project/plugins.sbt
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "1.0.0-M4")
このあたり。
jetty()
で、@Resourceを使う対象として、Servletを用意しました。
src/main/scala/org/littlewings/infinispan/configuredcache/InfinispanServelt.scala
package org.litltewings.infinispan.configuredcache import java.io.IOException import javax.annotation.Resource import javax.servlet.annotation.WebServlet import javax.servlet.ServletException import javax.servlet.http.{HttpServlet, HttpServletRequest, HttpServletResponse} import org.infinispan.Cache import org.infinispan.manager.{CacheContainer, EmbeddedCacheManager} @WebServlet(Array("/cache/access")) class InfinispanServlet extends HttpServlet { @Resource(lookup = "java:jboss/infinispan/container/my-cache-container") private var cacheContainer: CacheContainer = _ // CacheContainerで受けても可 // private var cacheContainer: EmbeddedCacheManager = _ // EmbeddedCacheManagerで受けても可 @Resource(lookup = "java:jboss/infinispan/cache/my-cache-container/my-cache-1") private var cache: Cache[String, Integer] = _ @throws(classOf[IOException]) @throws(classOf[ServletException]) override protected def doGet(req: HttpServletRequest, res: HttpServletResponse): Unit = { res.setContentType("text/html; charset=UTF-8") val counter = cache.get("counter") match { case null => 1 case n => n + 1 } cache.put("counter", counter) val fromManagerCache = cacheContainer.getCache[String, String]("my-cache-2") res.getWriter.write { <html> <body> <p>{s"container = ${cacheContainer}"}</p> <p>{s"container class name = ${cacheContainer.getClass.getName}"}</p> <p>{s"container have cache names = ${cacheContainer.asInstanceOf[EmbeddedCacheManager].getCacheNames}"}</p> <p>{s"injected cache name = ${cache.getName}"}</p> <p>{s"injected cache transactionMode = ${cache.getCacheConfiguration.transaction.transactionMode}"}</p> <p>{s"get cache name = ${fromManagerCache.getName}"}</p> <p>{s"get cache transactionMode = ${fromManagerCache.getCacheConfiguration.transaction.transactionMode}"}</p> <p>{s"counter = ${counter}"}</p> </body> </html>.toString + System.lineSeparator } } }
CacheContainerをインジェクションする時は、こんな感じ。
@Resource(lookup = "java:jboss/infinispan/container/my-cache-container") private var cacheContainer: CacheContainer = _ // CacheContainerで受けても可 // private var cacheContainer: EmbeddedCacheManager = _ // EmbeddedCacheManagerで受けても可
JNDI名は、「java:jboss/infinispan/container/[CacheContainer名]」みたいですね。
型は、CacheContainerまたはEmbeddedCacheManagerでインジェクションすることができます。Infinispanのドキュメントでは、EmbeddedCacheManagerを使用しています。
Cacheをインジェクションする時は、こんな感じ。
@Resource(lookup = "java:jboss/infinispan/cache/my-cache-container/my-cache-1") private var cache: Cache[String, Integer] = _
JNDI名は、「java:jboss/infinispan/cache/[CacheContainer名]/[Cache名]」のようです。
結果表示は、簡単なカウンタとCacheContainerおよびCacheの情報表示。
res.getWriter.write { <html> <body> <p>{s"container = ${cacheContainer}"}</p> <p>{s"container class name = ${cacheContainer.getClass.getName}"}</p> <p>{s"container have cache names = ${cacheContainer.asInstanceOf[EmbeddedCacheManager].getCacheNames}"}</p> <p>{s"injected cache name = ${cache.getName}"}</p> <p>{s"injected cache transactionMode = ${cache.getCacheConfiguration.transaction.transactionMode}"}</p> <p>{s"get cache name = ${fromManagerCache.getName}"}</p> <p>{s"get cache transactionMode = ${fromManagerCache.getCacheConfiguration.transaction.transactionMode}"}</p> <p>{s"counter = ${counter}"}</p> </body> </html>.toString + System.lineSeparator }
トランザクションへの対応状態も出すようにしています。
あと、jboss-deployment-structure.xmlの作成。
src/main/webapp/WEB-INF/jboss-deployment-structure.xml
<?xml version="1.0" encoding="UTF-8"?> <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2"> <deployment> <dependencies> <module name="org.infinispan" export="true" /> </dependencies> </deployment> </jboss-deployment-structure>
参考)
Class Loading in WildFly
https://docs.jboss.org/author/display/WFLY8/Class+Loading+in+WildFly
第3章 クラスローディングとモジュール
https://access.redhat.com/documentation/ja-JP/JBoss_Enterprise_Application_Platform/6/html/Development_Guide/chap-Class_Loading_and_Modules.html
3.2. デプロイメントへの明示的なモジュール依存関係の追加
https://access.redhat.com/documentation/ja-JP/JBoss_Enterprise_Application_Platform/6/html/Development_Guide/Add_an_Explicit_Module_Dependency_to_a_deployment.html
これをWARにパッケージングして
> package [info] Packaging /xxxxx/infinispan-configured-cache/target/scala-2.11/javaee7-web.war ... [info] Done packaging. [success] Total time: 8 s, completed 2014/08/09 22:16:17
WildFlyにデプロイします。
$ cp target/scala-2.11/javaee7-web.war /path/to/wildfly-8.1.0.Final/standalone/deployments/
ちなみに、デプロイするとこんな風に警告されます。
22:17:11,768 WARN [org.jboss.as.dependency.private] (MSC service thread 1-4) JBAS018567: Deployment "deployment.javaee7-web.war" is using a private module ("org.infinispan:main") which may be changed or removed in future versions without notice. 22:17:11,769 WARN [org.jboss.as.dependency.private] (MSC service thread 1-4) JBAS018567: Deployment "deployment.javaee7-web.war" is using a private module ("org.infinispan:main") which may be changed or removed in future versions without notice.
これ、前も見たことあるんですけどWildFly的にはInfinispanを直接使って欲しくないのかなぁ?確かにモジュール定義上はprivateになってますしね…。
参考)
Class Loading in WildFly
https://docs.jboss.org/author/display/WFLY8/Class+Loading+in+WildFly
Module descriptors
https://docs.jboss.org/author/display/MODULES/Module+descriptors
まあ、それはさておき…ちょっとアクセスしてみましょう。
$ curl http://localhost:8080/javaee7-web/cache/access
結果。
<html> <body> <p>container = my-cache-container</p> <p>container class name = org.jboss.as.clustering.infinispan.DefaultCacheContainer</p> <p>container have cache names = [my-cache-1, my-cache-2]</p> <p>injected cache name = my-cache-1</p> <p>injected cache transactionMode = TRANSACTIONAL</p> <p>get cache name = my-cache-2</p> <p>get cache transactionMode = NON_TRANSACTIONAL</p> <p>counter = 1</p> </body> </html>
CacheContainerの実体は、DefaultCacheManagerじゃないんですねー。また、CacheContainerに定義したCacheが2つであることと、「my-cache-1」がトランザクションに対応していることがわかります。
なお、繰り返しアクセスするとカウンタが上がっていきます。
<html> <body> <p>container = my-cache-container</p> <p>container class name = org.jboss.as.clustering.infinispan.DefaultCacheContainer</p> <p>container have cache names = [my-cache-1, my-cache-2]</p> <p>injected cache name = my-cache-1</p> <p>injected cache transactionMode = TRANSACTIONAL</p> <p>get cache name = my-cache-2</p> <p>get cache transactionMode = NON_TRANSACTIONAL</p> <p>counter = 2</p> </body> </html>
とりあえず、基本的なところは大丈夫かな?
今回作成したコードは、こちらに置いています。
https://github.com/kazuhira-r/infinispan-examples/tree/master/infinispan-configured-cache