S2JMS 開発記 Re: こもりさんのコメント
へのレスです.
すごい勢いで進んでますね。
や,作夏辺りからほとんど前進していません (苦笑).
SendMessageInterceptor
を含む S2JMS-Core はすなあそびのころからありましたから.
進歩したのは Velocity 対応を含めて,ぼうずさんが作ってくれた部分のみ...
アプリケーションからの送信メッセージはMessageFactory次第とのことですが、この場合は送信メッセージがある程度固定化されてしまいますよね。VelocityTextFormatterを使っても、プロパティをテキスト化して送信するのが精一杯では。
Velocity って #if
とか #foreach
とか使えるようなので,ある程度複雑なことはテンプレートエンジンの側でできるかなぁ,と思ってます.
実際にはそれで済まない場合ももちろんあって,アプリケーションの処理結果によってメッセージを送信したりしなかったり,全然違う種類のメッセージを送信したり,別の宛先へ送信したり等々,複雑な状況は普通にあると考えています.
が,それを S2JMS として対応することはあまり考えていません.
なぜなら秘策があるからです.それは...
謎です (謎なし).
謎 は文字通りの謎ではなく,少なくとも存在することだけは間違いのないあるものを示しています.その意味で謎なし.
ですが,謎を我々が目にすることができるのか,できるとしたらいつなのかは文字通りの謎です.
ヒントはこのへんとか.
まぁ,謎が謎のままだとしても,昨年のすなあそびで発表のあった Trickle とか,他にも S2JBPM とか,S2Drools とか,S2JESS とか...
そういった飛び道具と組み合わせることができればいいなぁと妄想しています.
わたしのイメージだと、S2JSFでアクションの処理した結果をHTMLに埋め込むように、送信メッセージに埋め込むようなこともできればよいかと思ってます。
これは昨日書いた例でもできているような.
S2JSF だとアクションの処理結果は DTO に設定されますよね.
MessageFactory
がその DTO を参照すればいいのではないかと.
昨日の例だと,
<component name="sendInterceptor" class="org.seasar.jms.core.interceptor.SendMessageInterceptor"> <component class="org.seasar.jms.core.message.impl.TextMessageFactory"/> <component class="org.seasar.jms.core.message.text.VelocityTextFormatter"> <property name="templateText">$employeeDto.empno $employeeDto.ename</property> </component>
例えば employeeDto
の empno
は要求メッセージから設定される情報で,アクションを実行すると DB から該当する従業員名が employeeDto
の ename
に設定されて,それを結果メッセージに設定して送信するとか.
このテンプレート文字列はメッセージ送信の度に評価されるので,その時の employeeDto
の値が反映されます.
S2JSF の HTML テンプレートとあまり変わらないような.
MapMessage
なんかだと,
<component name="sendInterceptor" class="org.seasar.jms.core.interceptor.SendMessageInterceptor"> <component instance="prototype" class="org.seasar.jms.core.message.impl.MapMessageFactory"> <property name="map">fooDto.map</property> </component>
みたいに MapMessageFactory
を instance="prototype"
にして,その map
プロパティにアプリケーションが処理した結果の Map
が設定されるようにしたりとか.
あまりおすすめじゃないけど,
<component instance="prototype" class="org.seasar.jms.core.message.impl.MapMessageFactory"> <property name="map"> #{ "empno" : employeeDto.empno, "ename" : employeeDto.ename } </property> </component>
ということもできちゃったり.(^^;
アノテートされたフィールドからMessageFactoryが勝手にMapMessageを作って投げてくれるような感じです。これだと、あるロジックで処理した結果を別のロジックに投げてさらに処理・・・みたいなことが実現できると思うのですが、どうでしょう? (・・・と、これはS2JMSContainer側で実現すればいいんですかね?)
うーん,結果メッセージを作る時の情報 (アノテーション含む) は情報元の方より引っ張ってくる方にあった方がいいような.
上の例だと,employeeDto
から empno
や ename
を集めてくるわけですが,その情報が employeeDto
の方にあったらちょっといやーん.
でもまぁ,この辺はいろいろアイディアを出して頂いて構いません.というか出してください (笑).
こもりさんも blog 始めません? S2JMS 専用でも構わないので (その場合は是非はてなで).
そこでいろいろ思いついたことを書いて頂けるとうれしいなぁ.
S2JMS 開発記 訂正:ExecutionContext と TransactionManager
01/03 に書いた「ExecutionContext と TransactionManager」は大間違いでした.
リソースマネージャが ExecutionContext
に設定して WorkManager
に渡す Xid
は,「14. Transaction Inflow」で使うものらしい.
Transaction Inflow というのは 外部の TP モニタ (メインフレーム上の CICS とか) がトランザクションのオリジネータで,アプリケーションサーバがその配下で動くような場合の仕様.
このケースでは,アプリケーションサーバは外部のトランザクションマネージャに制御されるリソースのように動作するため,外から Xid
が渡されるということらしい.
S2JMS ではこのケースをサポートする予定はないので,これは忘れてよさげ.
んで,通常のっていうかアプリケーションサーバが管理するトランザクションの基でメッセージを受信する際はというと,結局メッセージを処理するのと同一のスレッド (Work#run()
の中) で処理するみたい.
少なくとも ActiveMQ と Sun の Generic Resource Adapter for JMS はそうなってる.
なーんだ,難しく考えることなかったよ.心より恥じる.
JCA 仕様的には「12.5.6 Transacted Delivery (Using Container-Managed Transaction)」あたりに書いてあるっぽい.
そんなわけで (どんなわけで?),アプリケーションサーバっていうか S2JCA では MessageEndpointFactory#createEndpoint(XAResource)
に渡される XAResource
を MessageEndpoint
実装クラスに憶えておいて,beforeDelivery(Method)
で TransactionManager#begin()
& Transaction#enlistResource(XAResource)
すればいいだけっぽい.
それなら楽勝♪
そんなわけで (どんなわけで?),この週末には MessageEndpoint
および MessageEndpointFactory
を実装しよう.
これが片づけば残りは ActivationSpec
くらいかな.これが面倒なんだよなぁ.
出演予定 TV 番組
この近辺 (どこ?) で話題のモデルが出演するテレビ番組を分かるだけ掲載します.
新規分は赤字で (レギュラー除く).直近分は太字で.
- 香里奈
- 01/07 (土) 09:30〜14:00 TBS 「王様のブランチ」