JBossESBをひも解く(その2)

5月は業務に追われて大忙しだった。
最近になってようやく余裕が出てきたので、またタイミングを見つけてブログを更新していこうと思う。
ということで今回はorg.jboss.soa.esb.actions.soap.proxy.SOAPProxyについて。

org.jboss.soa.esb.actions.soap.proxy.SOAPProxy

SOAPProxyについてはProgrammers Guideで語られている。
ここでは
 「疎結合を実現するために、Webサービスクライアント⇔Webサービスの間を仲介するもの」
といった感じで言及されている。
ちょっと周りくどいので、もっと単純に(SOAPProxyの機能にフォーカスして)
 「SOAP通信をプロキシする」
ととらえた方が簡単で理解しやすいと思う。
(ちなみに、SOAPだけでなくMTOMにも対応している。)

SOAPProxy周りのクラス構成はこんな感じ。

クラス構成からも分かるけど、現在対応しているトランスポートはhttpだけ。
Programmers Guideには

It is understood that SOAP is not tied to http. The wsdl is read, 
and if an http transport is defined, that will be used. 
Other transports (jms) will need future consideration.

とあるので、ゆくゆくはJMSとかその他のトランスポートにも対応するんだろうと思う。


さて、ここからが本題、SOAPProxyの使い方について。
まずは定義ファイルの設定から。

jboss-esb.xml

<service category="SOAPService" description="" invmScope="GLOBAL" name="SOAPProxy">
	<listeners>
		<http-gateway name="soap-gw" />
	</listeners>
	<actions mep="RequestResponse">
		<action class="org.jboss.soa.esb.actions.soap.proxy.SOAPProxy"
			name="proxy">
			<property name="wsdl" value="http://localhost:8888/webapp/ws/Service?wsdl" />
		</action>
	</actions>
</service>

指定するのはWSDLのURLだけと単純。

次に「soap-proxy.esb」を作成して、${JBOSS_HOME}/server//deployにデプロイする。
あとは

http://localhost:8080/soap-proxy/http/SOAPService/SOAPProxy?wsdl

にアクセスすればlocation情報が変換されたWSDL(※)が返却される。
(※location情報は  から  に変換される。)



で、実はこの部分にSOAPProxyはバグがある。
SOAP1.1であれば正しくlocation情報が書きかわるんだが、SOAP1.2ではlocation情報が書き変わらない。
これは
https://issues.jboss.org/browse/JBESB-3783
にも上げられている。
ここよりもう少し詳しく書くと、

「http://・・・?wsdl」でアクセスされると、org.jboss.soa.esb.actions.soap.proxy.SOAPProxyWsdlContractPublisherが
元のWSDL(<property name="wsdl" value="xxx"/>で指定されたもの)を読み込み、
Smooksを利用して変換したものを結果として返却する。
しかし、Smooks用の定義ファイル(org.jboss.soa.esb.actions.soap.wsdltrans.xml)が
そもそもSOAP1.2に対応していない。

ということ。

◆Smooks用の定義ファイル(org.jboss.soa.esb.actions.soap.wsdltrans.xml

<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">

    <resource-config selector="import">
        <resource>org.jboss.soa.esb.actions.soap.WsdlEndpointTransformer</resource>
    </resource-config>

    <resource-config selector="port address" selector-namespace="http://schemas.xmlsoap.org/wsdl/soap/">
        <resource>org.jboss.soa.esb.actions.soap.WsdlEndpointTransformer</resource>
    </resource-config>

    <resource-config selector="binding" selector-namespace="http://schemas.xmlsoap.org/wsdl/soap/">
        <resource>org.jboss.soa.esb.actions.soap.WsdlEndpointTransformer</resource>
    </resource-config>

    <resource-config selector="*">
        <resource>org.jboss.soa.esb.actions.soap.DenormalizedAttributeValueSerializer</resource>
        <param name="closeEmptyElements">true</param>
    </resource-config>

</smooks-resource-list>


対応策としては、にSOAP1.2の定義を追加すれば良い。

◆wsdltrans12.xml

<?xml version="1.0" encoding="UTF-8"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
	<resource-config selector="port address" selector-namespace="http://schemas.xmlsoap.org/wsdl/soap12/">
		<resource>org.jboss.soa.esb.actions.soap.WsdlEndpointTransformer</resource>
	</resource-config>
</smooks-resource-list>

jboss-esb.xml

<service category="SOAPService" description="" invmScope="GLOBAL" name="SOAPProxy">
	<listeners>
		<http-gateway name="soap-gw" />
	</listeners>
	<actions mep="RequestResponse">
		<action class="org.jboss.soa.esb.actions.soap.proxy.SOAPProxy"
			name="proxy">
			<property name="wsdl" value="http://localhost:8888/webapp/ws/Service?wsdl" />
			<property name="wsdlTransform" value="/wsdltrans12.xml" />
		</action>
	</actions>
</service>

これでSOAP1.2のときもlocation情報が正しく書き変わるようになった。