第75章 CXF
CXF コンポーネント
cxf: コンポーネントは、CXF でホストされる JAX-WS サービスに接続するための Apache CXF との統合を提供します。
Maven ユーザーは、このコンポーネントの pom.xml
に以下の依存関係を追加する必要があります。
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-cxf</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>
CXF の依存関係については、WHICH-JARS
テキストファイルを参照してください。
ストリーミングモードで CXF を使用する場合(DataFormat オプションを参照)、Stream caching も読み取ります。
Camel on EAP デプロイメント
このコンポーネントは、Red Hat JBoss Enterprise Application Platform (JBoss EAP) コンテナー上で簡素化されたデプロイメントモデルを提供する Camel on EAP (Wildfly Camel) フレームワークによってサポートされます。
CXF コンポーネントは、Apache CXF も使用する JBoss EAP webservices
の susbsystem と統合します。詳細は「 JAX-WS 」を参照してください。
現在、Camel on EAP サブシステムでは CXF または Restlet コンシューマー はサポートさ れません。ただし、CamelProxy
を使用すると、CXF コンシューマーの動作を模倣することができます。
URI 形式
cxf:bean:cxfEndpoint[?options]
cxfEndpoint は Spring Bean レジストリーの Bean を参照する Bean ID を表します。この URI 形式では、ほとんどのエンドポイント詳細が Bean 定義で指定されます。
cxf://someAddress[?options]
someAddress は、CXF エンドポイントのアドレスを指定します。この URI 形式では、ほとんどのエンドポイント詳細がオプションを使用して指定されます。
上記のいずれかのスタイルで、以下のように URI にオプションを追加できます。
cxf:bean:cxfEndpoint?wsdlURL=wsdl/hello_world.wsdl&dataFormat=PAYLOAD
オプション
Name | 必須 | 説明 |
| 非対応 | WSDL の場所。WSDL はデフォルトでエンドポイントアドレスから取得されます。以下に例を示します。
|
| 対応 | SEI(Service Endpoint Interface)クラスの名前。このクラスは JSR181 アノテーションを持つことができますが、必須ではありません。 2.0 以降、このオプションは POJO モードでのみ必要です。wsdlURL オプションを指定する場合、serviceClass は PAYLOAD モードおよび MESSAGE モードでは必要ありません。serviceClass なしで wsdlURL オプションを使用すると、serviceName オプションおよび portName オプション(Spring 設定の endpointName)オプションを指定する 必要 があります。
2.0 以降、
参照されるオブジェクトは、Spring AOP 以外のプロキシーの 2.8 以降、 PAYLOAD モードおよび MESSAGE モード の wsdlURL および serviceClass オプションの両方を省略することができます。省略すると、CXF の Dispatch Mode を容易にするために、任意の XML 要素を PAYLOAD モードの CxfPayload ボディーに配置できます。
例: |
|
WSDL に複数の |
このサービスは実装されているサービス名で、
|
|
|
このサービスが実装しているポート名。
|
| 非対応 |
CXF エンドポイントがサポートするメッセージデータフォーマット。使用できる値は |
| 非対応 |
このオプション の |
| 非対応 |
CXF エンドポイントプロデューサーが呼び出す操作の種類。使用できる値は |
| 非対応 |
2.5.0 以降、SOAP ボディーでパラメーターを表す方法を記述する WSDL スタイル。値が |
| 非対応 |
deprecated: このエンドポイントにデフォルトの CXF バスを使用するかどうかを指定します。使用できる値は |
| 非対応 |
deprecated: このエンドポイントにデフォルトの CXF バスを使用するかどうかを指定します。使用できる値は |
| 非対応 |
デフォルトでは、CXF Bus Factory によって作成されたデフォルトのバスを使用します。 |
| 非対応 |
|
| 非対応 |
|
| 非対応 |
2.3 の新機能。このオプションは、インバウンドおよびアウトバウンド SOAP メッセージをログに書き込む CXF ロギング機能を有効にします。使用できる値は |
| 非対応 |
2.4 の新機能として、このオプションはリモートサービスを呼び出す
|
| 非対応 | 2.4 の新機能として、このオプションはリモートサービスを呼び出す CxfProducer によって使用されるデフォルトの operationNamespace を設定します。以下に例を示します。
|
| 非対応 |
2.5 の新機能、このオプションを使用すると、CXF エンドポイントが sync または async API を使用して基礎となる作業を行うことを決定できるようになりました。デフォルト値は |
| 非対応 |
2.5 の新機能として、このオプションはサービスアドレス URL と
|
| 非対応 |
Camel 2.8: エンドポイント URI にカスタム CXF プロパティーを設定できます。たとえば、 |
| 非対応 | 2.8.2 の新機能このオプションは、PAYLOAD モードで実行されている場合に CXF コンポーネントを制御します(以下を参照)、受信メッセージを DOM 要素に解析するか、ペイロードを一部のケースでストリーミングできる javax.xml.transform.Source オブジェクトとして解析するかを制御します。 |
| 非対応 | 2.11 の新機能。このオプションは、PhaseInterceptorChain がキャッチするフォールトのロギングをスキップするかどうかを制御します。 |
| 非対応 |
Camel 2.11 の新機能。このオプションは、プログラムによる CXF エンドポイントの設定をサポートする |
|
| 非対応 |
Camel 2.12.3 の新機能。このオプションは、CXF クライアントのユーザー名の基本認証情報を設定するために使用されます。 |
| 非対応 |
Camel 2.12.3 の新機能。このオプションは、CXF クライアントのパスワードの基本認証情報を設定するために使用されます。 |
| 非対応 |
serviceName
および portName
は QNames であるため、上記の例に示すように、それらを指定する際に {namespace}
のプレフィックスが付けられるようにしてください。
データフォーマットの説明
DataFormat | 説明 |
| POJO(古い Java オブジェクト)は、ターゲットサーバーで呼び出されるメソッドに対する Java パラメーターです。プロトコルおよび論理 JAX-WS ハンドラーの両方がサポートされます。 |
|
|
|
|
|
Camel 2.8.2 の新機能。 |
エクスチェンジプロパティー CamelCXFDataFormat
を取得すると、エクスチェンジのデータ形式モードを判別できます。交換キー定数は org.apache.camel.component.cxf.CxfConstants.DATA_FORMAT_PROPERTY
で定義されます。
Apache Aries Blueprint を使用した CXF エンドポイントの設定
Camel 2.8 以降、CXF エンドポイントの Aries Blueprint 依存関係インジェクションの使用はサポートされません。スキーマは Spring スキーマと非常に似ているため、移行はかなり透過的です。
以下に例を示します。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf" xmlns:cxfcore="http://cxf.apache.org/blueprint/core" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <camel-cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:9001/router" serviceClass="org.apache.servicemix.examples.cxf.HelloWorld"> <camel-cxf:properties> <entry key="dataFormat" value="MESSAGE"/> </camel-cxf:properties> </camel-cxf:cxfEndpoint> <camel-cxf:cxfEndpoint id="serviceEndpoint" address="http://localhost:9000/SoapContext/SoapPort" serviceClass="org.apache.servicemix.examples.cxf.HelloWorld"> </camel-cxf:cxfEndpoint> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="routerEndpoint"/> <to uri="log:request"/> </route> </camelContext> </blueprint>
現在、endpoint 要素は最初にサポートされている CXF namespacehandler です。
Spring と同様に Bean 参照を使用することもできます。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws" xmlns:cxf="http://cxf.apache.org/blueprint/core" xmlns:camel="http://camel.apache.org/schema/blueprint" xmlns:camelcxf="http://camel.apache.org/schema/blueprint/cxf" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd "> <camelcxf:cxfEndpoint id="reportIncident" address="/camel-example-cxf-blueprint/webservices/incident" wsdlURL="META-INF/wsdl/report_incident.wsdl" serviceClass="org.apache.camel.example.reportincident.ReportIncidentEndpoint"> </camelcxf:cxfEndpoint> <bean id="reportIncidentRoutes" class="org.apache.camel.example.reportincident.ReportIncidentRoutes" /> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <routeBuilder ref="reportIncidentRoutes"/> </camelContext> </blueprint>
MESSAGE モードで CXF の LoggingOutInterceptor を有効にする方法
CXF の LoggingOutInterceptor
は、回線上にあるアウトバウンドメッセージをロギングシステム(java.util.logging
)に出力します。LoggingOutInterceptor
は PRE_STREAM
フェーズであるため( PRE_STREAM
フェーズは MESSAGE
モードで削除されています)、LoggingOutInterceptor
が WRITE
フェーズ中に実行されるように設定する必要があります。以下に例を示します。
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"> <!-- it really should have been user-prestream but CXF does have such phase! --> <constructor-arg value="target/write"/> </bean> <cxf:cxfEndpoint id="serviceEndpoint" address="http://localhost:9002/helloworld" serviceClass="org.apache.camel.component.cxf.HelloService"> <cxf:outInterceptors> <ref bean="loggingOutInterceptor"/> </cxf:outInterceptors> <cxf:properties> <entry key="dataFormat" value="MESSAGE"/> </cxf:properties> </cxf:cxfEndpoint>
relayHeaders オプションの説明
JAXWS WSDL -first 開発者 の観点からは、帯域外 および帯域外ヘッダーがあります。
アウト バウンド ヘッダーは、SOAP ヘッダーなどのエンドポイントの WSDL バインディングコントラクトの一部として明示的に定義されるヘッダーです。
アウトバウンド ヘッダーは、ネットワークを介してシリアライズされるヘッダーですが、WSDL バインディングコントラクトの一部ではありません。
ヘッダーのリレー/フィルタリングは双方向です。
ルートに CXF エンドポイントがあり、開発者が SOAP ヘッダーなどの有線ヘッダーを持つ必要がある場合、別の JAXWS エンドポイントによって消費されるルートと一緒にリレーされる必要がある場合は、relayHeaders
がデフォルト値の true
に設定する必要があります。
POJO モードでのみ利用可能
relayHeaders=true
設定は、ヘッダーをリレーする意図を表します。特定のヘッダーがリレーされるかどうかの実際の決定は、MessageHeadersRelay
インターフェースを実装するプラグ可能なインスタンスに委譲されます。MessageHeadersRelay
の具体的な実装を参照し、ヘッダーをリレーする必要があるかどうかを判断します。すでに SoapMessageHeadersRelay
の実装があり、これはそれ自体をよく知られた SOAP ネームスペースにバインドします。現在、out ofband ヘッダーのみがフィルターされ、relayHeaders=true
の場合、Oband ヘッダーは常にリレーされます。ネットワーク上にヘッダーがあり、その名前空間がランタイムに不明な場合は、フォールバックする DefaultMessageHeadersRelay
が使用され、すべてのヘッダーをリレーできます。
relayHeaders=false
設定は、すべてのヘッダー、帯域外および帯域外(out ofband)がドロップされることをアサートします。
独自の MessageHeadersRelay
実装をオーバーライドしたり、リレーのリストに追加したりできます。事前に読み込んだリレーインスタンスをオーバーライドするには、MessageHeadersRelay
実装サービスが上書きするものと同じ名前空間になるようにしてください。また、オーバーライドされるリレーは上書きする名前と同じスペースをすべて処理する必要があります。そうでない場合には、ルートの起動時にランタイム例外がスローされます。これは、インスタンスマッピングをリレーする名前空間に曖昧さが発生するためです。
<cxf:cxfEndpoint ...> <cxf:properties> <entry key="org.apache.camel.cxf.message.headers.relays"> <list> <ref bean="customHeadersRelay"/> </list> </entry> </cxf:properties> </cxf:cxfEndpoint> <bean id="customHeadersRelay" class="org.apache.camel.component.cxf.soap.headers.CustomHeadersRelay"/>
ヘッダーをリレー/ドロップする方法を示すテストをご覧ください。
リリース 2.0 以降の変更
-
POJO
およびPAYLOAD
モードがサポートされます。POJO
モードでは、帯域外ヘッダーのみが処理され、CXF のヘッダーリストから削除されたため、フィルタリングにだけ利用できます。アウトバウンドヘッダーは、POJO
モードのMessageContentList
に組み込まれています。camel-cxf
コンポーネントは、MessageContentList
から In-band ヘッダーのフィルターが必要な場合に、PAYLOAD
モードまたはプラグインを CXF インターセプター/JAXWS Handler で使用してみてください。 Message Header Relay メカニズムは
CxfHeaderFilterStrategy
に統合されました。relayHeaders
オプション、そのセマンティクス、およびデフォルト値は同じですが、CxfHeaderFilterStrategy
のプロパティーになります。以下は、設定例です。<bean id="dropAllMessageHeadersStrategy" class="org.apache.camel.component.cxf.common.header.CxfHeaderFilterStrategy"> <!-- Set relayHeaders to false to drop all SOAP headers --> <property name="relayHeaders" value="false"/> </bean>
次に、エンドポイントは
CxfHeaderFilterStrategy
を参照できます。<route> <from uri="cxf:bean:routerNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/> <to uri="cxf:bean:serviceNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/> </route>
MessageHeadersRelay
インターフェースが若干変更され、MessageHeaderFilter
に変更されました。これはCxfHeaderFilterStrategy
のプロパティーです。以下は、ユーザー定義の Message Header フィルターを設定する例です。<bean id="customMessageFilterStrategy" class="org.apache.camel.component.cxf.common.header.CxfHeaderFilterStrategy"> <property name="messageHeaderFilters"> <list> <!-- SoapMessageHeaderFilter is the built in filter. It can be removed by omitting it. --> <bean class="org.apache.camel.component.cxf.common.header.SoapMessageHeaderFilter"/> <!-- Add custom filter here --> <bean class="org.apache.camel.component.cxf.soap.headers.CustomHeaderFilter"/> </list> </property> </bean>
-
relayHeaders
以外の新しいプロパティーは、CxfHeaderFilterStrategy
で設定できます。
Name | 説明 | type | 必須? | デフォルト値 |
| すべてのメッセージヘッダーは、メッセージヘッダーフィルターによって処理されます。 |
| 非対応 |
|
| すべてのメッセージヘッダーが伝播されます(メッセージヘッダーフィルターによる処理なし)。 |
| 非対応 |
|
|
2 つのフィルターがアクティベーション namespace で重複している場合、プロパティーによって処理される方法が制御されます。値が |
| 非対応 |
|
Spring での CXF エンドポイントの設定
以下に示した Spring 設定ファイルを使用して CXF エンドポイントを設定できます。また、エンドポイントを camelContext
タグに埋め込むこともできます。サービスエンドポイントを呼び出す場合は、operationName
および operationNamespace
ヘッダーを、呼び出す操作を明示的に設定できます。
Camel 2.x で、CXF エンドポイントのターゲット名前空間として http://camel.apache.org/schema/cxf
を使用するように変更しました。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://camel.apache.org/schema/cxf" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd "> ...
Apache Camel 2.x では、http://activemq.apache.org/camel/schema/cxfEndpoint
名前空間が http://camel.apache.org/schema/cxf
に変更されました。
ルート beans 要素に指定された JAX-WS schemaLocation
属性が含まれるようにしてください。これにより、CXF はファイルを検証でき、必須です。また、< cxf:cxfEndpoint/
> タグの最後にある namespace 宣言にも注意してください。組み合わせた {namespace}localName
構文が存在すると、このタグの属性値に対してはサポートされないためです。
cxf:cxfEndpoint
要素は、多くの追加属性をサポートします。
Name | 値 |
|
このサービスが実装しているエンドポイント名。 |
|
このサービスは実装されているサービス名で、 |
| WSDL の場所。クラスパス、ファイルシステム、またはリモートでホストできます。 |
|
使用するサービスモデルの |
| サービスの公開アドレス。 |
| JAX-WS エンドポイントで使用されるバス名。 |
| JSR181 アノテーションが含まれる SEI(Service Endpoint Interface)クラスのクラス名。 |
また、多くの子要素もサポートします。
Name | 値 |
|
このエンドポイントの受信インターセプター。< |
|
このエンドポイントの受信障害インターセプター。< |
|
このエンドポイントの送信インターセプター。< |
|
このエンドポイントの送信障害インターセプター。< |
| JAX-WS エンドポイントに提供する必要があるプロパティーマップ。以下を参照してください。 |
| JAX-WS エンドポイントに提供する JAX-WS ハンドラーリスト。以下を参照してください。 |
|
エンドポイントで使用する |
|
使用するエンドポイントの |
|
このエンドポイントのインターセプターを保持する機能。< |
|
使用するエンドポイントのスキーマの場所。< |
|
使用するこのエンドポイントのサービスファクトリー。これは、Spring < |
インターセプター、プロパティー、およびハンドラーを提供する方法を示すより高度な例は、http://cwiki.apache.org/CXF20DOC/jax-ws-configuration.htmlを参照してください。
CXF:properties を使用して CXF エンドポイントの dataFormat
、および Spring 設定ファイルから setDefaultBus
プロパティーを以下のように設定できます。
<cxf:cxfEndpoint id="testEndpoint" address="http://localhost:9000/router" serviceClass="org.apache.camel.component.cxf.HelloService" endpointName="s:PortName" serviceName="s:ServiceName" xmlns:s="http://www.example.com/test"> <cxf:properties> <entry key="dataFormat" value="MESSAGE"/> <entry key="setDefaultBus" value="true"/> </cxf:properties> </cxf:cxfEndpoint>
camel-cxf コンポーネントを java.util.logging ではなく log4j を使用する方法
CXF のデフォルトのロガーは java.util.logging
です。これを log4j
に変更する場合は、以下の手順を実行します。META-INF/cxf/org.apache.cxf.logger
という名前のクラスパスにファイルを作成します。このファイルには、1 行にコメントがない org.apache.cxf.common.logging.Log4jLogger
クラスの完全修飾名を含める必要があります。
How to allow camel-cxf response message with xml start document
PHP などの一部の SOAP クライアントを使用している場合、CXF は XML 開始ドキュメント < ?xml version="1.0" encoding="utf-8"?> を追加しないため、この種のエラーが発生します
。
Error:sendSms: SoapFault exception: [Client] looks like we got no XML document in [...]
この問題を解決するには、XML 開始ドキュメントを書くように StaxOutInterceptor に指示する必要があります。
public class WriteXmlDeclarationInterceptor extends AbstractPhaseInterceptor<SoapMessage> { public WriteXmlDeclarationInterceptor() { super(Phase.PRE_STREAM); addBefore(StaxOutInterceptor.class.getName()); } public void handleMessage(SoapMessage message) throws Fault { message.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE); } }
このようなカスタマーインターセプターを追加し、camel-cxf
終了ポンジーに設定することができます。
<cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:${CXFTestSupport.port2}/CXFGreeterRouterTest/CamelContext/RouterPort" serviceClass="org.apache.hello_world_soap_http.GreeterImpl" skipFaultLogging="true"> <cxf:outInterceptors> <!-- This interceptor will force the CXF server send the XML start document to client --> <bean class="org.apache.camel.component.cxf.WriteXmlDeclarationInterceptor"/> </cxf:outInterceptors> <cxf:properties> <!-- Set the publishedEndpointUrl which could override the service address from generated WSDL as you want --> <entry key="publishedEndpointUrl" value="http://www.simple.com/services/test" /> </cxf:properties> </cxf:cxfEndpoint>
または、Camel 2.4 を使用している場合は、このメッセージヘッダーを追加します。
// set up the response context which force start document Map<String, Object> map = new HashMap<String, Object>(); map.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE); exchange.getOut().setHeader(Client.RESPONSE_CONTEXT, map);
POJO データフォーマットで camel-cxf エンドポイントからメッセージを消費する方法
camel-cxf
エンドポイントコンシューマー POJO
データ形式は cxf invoker をベースとしているため、メッセージヘッダーには CxfConstants.OPERATION_NAME
という名前のプロパティーがあり、メッセージボディーは SEI メソッドパラメーターのリストです。
public class PersonProcessor implements Processor { private static final transient Logger LOG = LoggerFactory.getLogger(PersonProcessor.class); @SuppressWarnings("unchecked") public void process(Exchange exchange) throws Exception { LOG.info("processing exchange in camel"); BindingOperationInfo boi = (BindingOperationInfo)exchange.getProperty(BindingOperationInfo.class.toString()); if (boi != null) { LOG.info("boi.isUnwrapped" + boi.isUnwrapped()); } // Get the parameters list which element is the holder. MessageContentsList msgList = (MessageContentsList)exchange.getIn().getBody(); Holder<String> personId = (Holder<String>)msgList.get(0); Holder<String> ssn = (Holder<String>)msgList.get(1); Holder<String> name = (Holder<String>)msgList.get(2); if (personId.value == null || personId.value.length() == 0) { LOG.info("person id 123, so throwing exception"); // Try to throw out the soap fault message org.apache.camel.wsdl_first.types.UnknownPersonFault personFault = new org.apache.camel.wsdl_first.types.UnknownPersonFault(); personFault.setPersonId(""); org.apache.camel.wsdl_first.UnknownPersonFault fault = new org.apache.camel.wsdl_first.UnknownPersonFault("Get the null value of person name", personFault); // Since camel has its own exception handler framework, we can't throw the exception to trigger it // We just set the fault message in the exchange for camel-cxf component handling and return exchange.getOut().setFault(true); exchange.getOut().setBody(fault); return; } name.value = "Bonjour"; ssn.value = "123"; LOG.info("setting Bonjour as the response"); // Set the response message, first element is the return value of the operation, // the others are the holders of method parameters exchange.getOut().setBody(new Object[] {null, personId, ssn, name}); } }
POJO データフォーマットの camel-cxf エンドポイントのメッセージを準備する方法
camel-cxf
エンドポイントプロデューサーは cxf クライアント API をベースにしています。最初にメッセージヘッダーで操作名を指定し、続いてメソッドパラメーターを一覧に追加し、このパラメーター一覧でメッセージを初期化する必要があります。応答メッセージのボディーは messageContentsList
で、そのリストから結果を取得できます。
メッセージヘッダーで操作名を指定しない場合、CxfProducer
は CxfEndpoint
から defaultOperationName
の使用を試行します。CxfEndpoint
に defaultOperationName
が設定されていない場合、これは操作一覧から最初の操作名を選択します。
メッセージボディーからオブジェクトアレイを取得する場合は、以下のように message.getbody(Object[].class)
を使用してボディーを取得できます。
Exchange senderExchange = new DefaultExchange(context, ExchangePattern.InOut); final List<String> params = new ArrayList<String>(); // Prepare the request message for the camel-cxf procedure params.add(TEST_MESSAGE); senderExchange.getIn().setBody(params); senderExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, ECHO_OPERATION); Exchange exchange = template.send("direct:EndpointA", senderExchange); org.apache.camel.Message out = exchange.getOut(); // The response message's body is an MessageContentsList which first element is the return value of the operation, // If there are some holder parameters, the holder parameter will be filled in the reset of List. // The result will be extract from the MessageContentsList with the String class type MessageContentsList result = (MessageContentsList)out.getBody(); LOG.info("Received output text: " + result.get(0)); Map<String, Object> responseContext = CastUtils.cast((Map<?, ?>)out.getHeader(Client.RESPONSE_CONTEXT)); assertNotNull(responseContext); assertEquals("We should get the response context here", "UTF-8", responseContext.get(org.apache.cxf.message.Message.ENCODING)); assertEquals("Reply body on Camel is wrong", "echo " + TEST_MESSAGE, result.get(0));
PAYLOAD データフォーマットの camel-cxf エンドポイントのメッセージの処理方法
Apache Camel 2.0: CxfMessage.getBody()
は、SOAP メッセージヘッダーおよびボディー要素の getter がある org.apache.camel.component.cxf.CxfPayload
オブジェクトを返します。この変更により、Apache Camel メッセージからネイティブ CXF メッセージを分離できます。
protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { from(SIMPLE_ENDPOINT_URI + "&dataFormat=PAYLOAD").to("log:info").process(new Processor() { @SuppressWarnings("unchecked") public void process(final Exchange exchange) throws Exception { CxfPayload<SoapHeader> requestPayload = exchange.getIn().getBody(CxfPayload.class); List<Source> inElements = requestPayload.getBodySources(); List<Source> outElements = new ArrayList<Source>(); // You can use a customer toStringConverter to turn a CxfPayLoad message into String as you want String request = exchange.getIn().getBody(String.class); XmlConverter converter = new XmlConverter(); String documentString = ECHO_RESPONSE; Element in = new XmlConverter().toDOMElement(inElements.get(0)); // Just check the element namespace if (!in.getNamespaceURI().equals(ELEMENT_NAMESPACE)) { throw new IllegalArgumentException("Wrong element namespace"); } if (in.getLocalName().equals("echoBoolean")) { documentString = ECHO_BOOLEAN_RESPONSE; checkRequest("ECHO_BOOLEAN_REQUEST", request); } else { documentString = ECHO_RESPONSE; checkRequest("ECHO_REQUEST", request); } Document outDocument = converter.toDOMDocument(documentString); outElements.add(new DOMSource(outDocument.getDocumentElement())); // set the payload header with null CxfPayload<SoapHeader> responsePayload = new CxfPayload<SoapHeader>(null, outElements, null); exchange.getOut().setBody(responsePayload); } }); } }; }
POJO モードでの SOAP ヘッダーの取得および設定方法
POJO
は、CXF エンドポイントが Camel エクスチェンジを生成または消費するときにデータ形式が Java オブジェクトのリスト であることを意味します。Apache Camel はメッセージボディーをこのモードで POJO として公開しますが、CXF コンポーネントは引き続き SOAP ヘッダーの読み書きへのアクセスを提供します。ただし、CXF インターセプターは処理後にヘッダーリストから In-band SOAP ヘッダーを削除するため、POJO モードで使用できるのは帯域外な SOAP ヘッダーのみです。
以下の例は、SOAP ヘッダーの取得/設定方法を示しています。CXF エンドポイントから別のエンドポイントに転送するルートがあるとします。つまり、SOAP Client
<route> <from uri="cxf:bean:routerRelayEndpointWithInsertion"/> <process ref="InsertRequestOutHeaderProcessor" /> <to uri="cxf:bean:serviceRelayEndpointWithInsertion"/> <process ref="InsertResponseOutHeaderProcessor" /> </route>
2.x SOAP ヘッダーは、 Apache Camel Message ヘッダーとの間で伝播されます。Apache Camel メッセージヘッダー名は org.apache.cxf.headers.Header.list
で、CXF で定義された定数(org.apache.cxf.headers.Header.HEADER_LIST
)です。ヘッダーの値は、CXF SoapHeader
オブジェクト(org.apache.cxf.binding.soap.SoapHeader
)の List
<> です。以下のスニペットは InsertResponseOutHeaderProcessor
です(レスポンスメッセージに新しい SOAP ヘッダーを挿入します)。InsertResponseOutHeaderProcessor
と InsertRequestOutHeaderProcessor
の両方で SOAP ヘッダーにアクセスする方法は実際に同じです。2 つのプロセッサーの唯一の違いは、挿入された SOAP ヘッダーの方向の設定です。
public static class InsertResponseOutHeaderProcessor implements Processor { @SuppressWarnings("unchecked") public void process(Exchange exchange) throws Exception { // You should be able to get the header if exchange is routed from camel-cxf endpoint List<SoapHeader> soapHeaders = CastUtils.cast((List<?>)exchange.getIn().getHeader(Header.HEADER_LIST)); if (soapHeaders == null) { // we just create a new soap headers in case the header is null soapHeaders = new ArrayList<SoapHeader>(); } // Insert a new header String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><outofbandHeader " + "xmlns=\"http://cxf.apache.org/outofband/Header\" hdrAttribute=\"testHdrAttribute\" " + "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" soap:mustUnderstand=\"1\">" + "<name>New_testOobHeader</name><value>New_testOobHeaderValue</value></outofbandHeader>"; SoapHeader newHeader = new SoapHeader(soapHeaders.get(0).getName(), DOMUtils.readXml(new StringReader(xml)).getDocumentElement()); // make sure direction is OUT since it is a response message. newHeader.setDirection(Direction.DIRECTION_OUT); //newHeader.setMustUnderstand(false); soapHeaders.add(newHeader); } }
PAYLOAD モードで SOAP ヘッダーを取得して設定する方法
PAYLOAD
モードで SOAP メッセージにアクセスする方法を
すでに紹介しています( 「PAYLOAD データフォーマットの camel-cxf エンドポイントのメッセージの処理方法」を参照)。
CxfPayload
オブジェクトを取得したら、DOM 要素(SOAP ヘッダー)の List
を返す CxfPayload.getHeaders()
メソッドを呼び出すことができます。
from(getRouterEndpointURI()).process(new Processor() { @SuppressWarnings("unchecked") public void process(Exchange exchange) throws Exception { CxfPayload<SoapHeader> payload = exchange.getIn().getBody(CxfPayload.class); List<Source> elements = payload.getBodySources(); assertNotNull("We should get the elements here", elements); assertEquals("Get the wrong elements size", 1, elements.size()); Element el = new XmlConverter().toDOMElement(elements.get(0)); elements.set(0, new DOMSource(el)); assertEquals("Get the wrong namespace URI", "http://camel.apache.org/pizza/types", el.getNamespaceURI()); List<SoapHeader> headers = payload.getHeaders(); assertNotNull("We should get the headers here", headers); assertEquals("Get the wrong headers size", headers.size(), 1); assertEquals("Get the wrong namespace URI", ((Element)(headers.get(0).getObject())).getNamespaceURI(), "http://camel.apache.org/pizza/types"); } }) .to(getServiceEndpointURI());
Camel 2.16.0 以降、「POJO モードでの SOAP ヘッダーの取得および設定方法」 で説明されている手法を使用して SOAP ヘッダーを設定または取得することができます。org.apache.cxf.headers.Header.list
ヘッダーを使用して SOAP ヘッダーの一覧を取得および設定できるようになりました。つまり、Camel CXF エンドポイントから別のエンドポイントに転送するルートがある場合(SOAP Client org.apache.cxf.headers.Header.list
Camel ヘッダーから削除します。
SOAP ヘッダーが MESSAGE モードで利用できない
SOAP 処理はスキップされるため、SOAP ヘッダーは MESSAGE
モードでは使用できません。
Apache Camel から SOAP Fault をスローする方法
CXF エンドポイントを使用して SOAP リクエストを消費する場合は、Camel コンテキストから SOAP Fault
をスローする必要がある場合があります。基本的に、throwFault
DSL を使用してこれを行うことができます。POJO
、PAYLOAD
、および MESSAGE
データフォーマットで機能します。以下のような soap 障害を定義できます。
SOAP_FAULT = new SoapFault(EXCEPTION_MESSAGE, SoapFault.FAULT_CODE_CLIENT); Element detail = SOAP_FAULT.getOrCreateDetail(); Document doc = detail.getOwnerDocument(); Text tn = doc.createTextNode(DETAIL_TEXT); detail.appendChild(tn);
次に、以下のようにスローします。
from(routerEndpointURI).setFaultBody(constant(SOAP_FAULT));
CXF エンドポイントが MESSAGE
データ形式で動作している場合、メッセージボディーに SOAP Fault メッセージを設定し、メッセージヘッダーにレスポンスコードを設定できます。
from(routerEndpointURI).process(new Processor() { public void process(Exchange exchange) throws Exception { Message out = exchange.getOut(); // Set the message body with the out.setBody(this.getClass().getResourceAsStream("SoapFaultMessage.xml")); // Set the response code here out.setHeader(org.apache.cxf.message.Message.RESPONSE_CODE, new Integer(500)); } });
POJO データフォーマットでも同じです。Out ボディーに SOAP Fault を設定し、以下のように Message.setFault(true)
を呼び出すことで障害を示すこともできます。
from("direct:start").onException(SoapFault.class).maximumRedeliveries(0).handled(true) .process(new Processor() { public void process(Exchange exchange) throws Exception { SoapFault fault = exchange .getProperty(Exchange.EXCEPTION_CAUGHT, SoapFault.class); exchange.getOut().setFault(true); exchange.getOut().setBody(fault); } }).end().to(serviceURI);
CXF エンドポイントのリクエストおよび応答コンテキストを伝播する方法
CXF クライアント API は、リクエストおよび応答コンテキストで操作を呼び出す方法を提供します。CXF エンドポイントプロデューサーを使用して外部 Web サービスを呼び出す場合は、リクエストコンテキストを設定し、以下のコードで応答コンテキストを取得できます。
CxfExchange exchange = (CxfExchange)template.send(getJaxwsEndpointUri(), new Processor() { public void process(final Exchange exchange) { final List<String> params = new ArrayList<String>(); params.add(TEST_MESSAGE); // Set the request context to the inMessage Map<String, Object> requestContext = new HashMap<String, Object>(); requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, JAXWS_SERVER_ADDRESS); exchange.getIn().setBody(params); exchange.getIn().setHeader(Client.REQUEST_CONTEXT , requestContext); exchange.getIn().setHeader(CxfConstants.OPERATION_NAME, GREET_ME_OPERATION); } }); org.apache.camel.Message out = exchange.getOut(); // The output is an object array, the first element of the array is the return value Object\[\] output = out.getBody(Object\[\].class); LOG.info("Received output text: " + output\[0\]); // Get the response context form outMessage Map<String, Object> responseContext = CastUtils.cast((Map)out.getHeader(Client.RESPONSE_CONTEXT)); assertNotNull(responseContext); assertEquals("Get the wrong wsdl opertion name", "{http://apache.org/hello_world_soap_http}greetMe", responseContext.get("javax.xml.ws.wsdl.operation").toString());
添付サポート
POJO モード: SOAP with Attachment and MTOM の両方がサポートされます(MTOM を有効にするための Payload Mode の例を参照してください)。 ただし、SOAP with Attachment はテストされていません。 アタッチメントはマーシャリングされ、POJO にアンマーシャリングされるため、ユーザーは通常添付ファイルを扱う必要はありません。 アタッチメントは 2.1 以降、Camel メッセージの添付ファイルに伝播されます。 そのため、Camel Message API による再試行添付が可能です。
DataHandler Message.getAttachment(String id)
.
ペイロードモード: MTOM は 2.1 以降サポートされます。アタッチメントは、上記の Camel Message API によって取得できます。このモードでは SOAP 処理がないため、SOAP with Attachment はサポートされません。
MTOM を有効にするには、CXF エンドポイントプロパティー「mtom_enabled」を true に設定します。(Spring でのみ実行できると考えられます。)
<cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:${CXFTestSupport.port1}/CxfMtomRouterPayloadModeTest/jaxws-mtom/hello" wsdlURL="mtom.wsdl" serviceName="ns:HelloService" endpointName="ns:HelloPort" xmlns:ns="http://apache.org/camel/cxf/mtom_feature"> <cxf:properties> <!-- enable mtom by setting this property to true --> <entry key="mtom-enabled" value="true"/> <!-- set the camel-cxf endpoint data fromat to PAYLOAD mode --> <entry key="dataFormat" value="PAYLOAD"/> </cxf:properties>
Payload モードの CXF エンドポイントに送信する attachment のある Camel メッセージを生成できます。
Exchange exchange = context.createProducerTemplate().send("direct:testEndpoint", new Processor() { public void process(Exchange exchange) throws Exception { exchange.setPattern(ExchangePattern.InOut); List<Source> elements = new ArrayList<Source>(); elements.add(new DOMSource(DOMUtils.readXml(new StringReader(MtomTestHelper.REQ_MESSAGE)).getDocumentElement())); CxfPayload<SoapHeader> body = new CxfPayload<SoapHeader>(new ArrayList<SoapHeader>(), elements, null); exchange.getIn().setBody(body); exchange.getIn().addAttachment(MtomTestHelper.REQ_PHOTO_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.REQ_PHOTO_DATA, "application/octet-stream"))); exchange.getIn().addAttachment(MtomTestHelper.REQ_IMAGE_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.requestJpeg, "image/jpeg"))); } }); // process response CxfPayload<SoapHeader> out = exchange.getOut().getBody(CxfPayload.class); Assert.assertEquals(1, out.getBody().size()); Map<String, String> ns = new HashMap<String, String>(); ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS); ns.put("xop", MtomTestHelper.XOP_NS); XPathUtils xu = new XPathUtils(ns); Element oute = new XmlConverter().toDOMElement(out.getBody().get(0)); Element ele = (Element)xu.getValue("//ns:DetailResponse/ns:photo/xop:Include", oute, XPathConstants.NODE); String photoId = ele.getAttribute("href").substring(4); // skip "cid:" ele = (Element)xu.getValue("//ns:DetailResponse/ns:image/xop:Include", oute, XPathConstants.NODE); String imageId = ele.getAttribute("href").substring(4); // skip "cid:" DataHandler dr = exchange.getOut().getAttachment(photoId); Assert.assertEquals("application/octet-stream", dr.getContentType()); MtomTestHelper.assertEquals(MtomTestHelper.RESP_PHOTO_DATA, IOUtils.readBytesFromStream(dr.getInputStream())); dr = exchange.getOut().getAttachment(imageId); Assert.assertEquals("image/jpeg", dr.getContentType()); BufferedImage image = ImageIO.read(dr.getInputStream()); Assert.assertEquals(560, image.getWidth()); Assert.assertEquals(300, image.getHeight());
Payload モードの CXF エンドポイントから受信した Camel メッセージを消費することもできます。
public static class MyProcessor implements Processor { @SuppressWarnings("unchecked") public void process(Exchange exchange) throws Exception { CxfPayload<SoapHeader> in = exchange.getIn().getBody(CxfPayload.class); // verify request assertEquals(1, in.getBody().size()); Map<String, String> ns = new HashMap<String, String>(); ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS); ns.put("xop", MtomTestHelper.XOP_NS); XPathUtils xu = new XPathUtils(ns); Element body = new XmlConverter().toDOMElement(in.getBody().get(0)); Element ele = (Element)xu.getValue("//ns:Detail/ns:photo/xop:Include", body, XPathConstants.NODE); String photoId = ele.getAttribute("href").substring(4); // skip "cid:" assertEquals(MtomTestHelper.REQ_PHOTO_CID, photoId); ele = (Element)xu.getValue("//ns:Detail/ns:image/xop:Include", body, XPathConstants.NODE); String imageId = ele.getAttribute("href").substring(4); // skip "cid:" assertEquals(MtomTestHelper.REQ_IMAGE_CID, imageId); DataHandler dr = exchange.getIn().getAttachment(photoId); assertEquals("application/octet-stream", dr.getContentType()); MtomTestHelper.assertEquals(MtomTestHelper.REQ_PHOTO_DATA, IOUtils.readBytesFromStream(dr.getInputStream())); dr = exchange.getIn().getAttachment(imageId); assertEquals("image/jpeg", dr.getContentType()); MtomTestHelper.assertEquals(MtomTestHelper.requestJpeg, IOUtils.readBytesFromStream(dr.getInputStream())); // create response List<Source> elements = new ArrayList<Source>(); elements.add(new DOMSource(DOMUtils.readXml(new StringReader(MtomTestHelper.RESP_MESSAGE)).getDocumentElement())); CxfPayload<SoapHeader> sbody = new CxfPayload<SoapHeader>(new ArrayList<SoapHeader>(), elements, null); exchange.getOut().setBody(sbody); exchange.getOut().addAttachment(MtomTestHelper.RESP_PHOTO_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.RESP_PHOTO_DATA, "application/octet-stream"))); exchange.getOut().addAttachment(MtomTestHelper.RESP_IMAGE_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.responseJpeg, "image/jpeg"))); } }
Message Mode: 接続は、メッセージをまったく処理しないため、サポートされていません。
CXF_MESSAGE Mode: MTOM はサポートされ、上記の Camel Message API によって接続を取得できます。マルチパート(MTOM)メッセージを受信すると、デフォルトの SOAPMessage
to String
コンバーターはボディーに完全なマルチパートペイロードを提供することに注意してください。SOAP XML を String
としてのみ必要な場合は、メッセージボディーを message.getSOAPPart()
で設定でき、Camel convert は残りの作業を行うことができます。
スタックトレース情報を伝播させる方法
Java の例外がサーバー側で発生したときに、例外のスタックトレースがフォールトメッセージにマーシャリングされてクライアントに返されるように、CXF エンドポイントを設定することができます。この機能を有効にするには、以下のように cxfEndpoint
要素で、dataFormat
を PAYLOAD
に設定し、faultStackTraceEnabled
プロパティーを true
に設定します。
<cxf:cxfEndpoint id="router" address="http://localhost:9002/TestMessage"
wsdlURL="ship.wsdl"
endpointName="s:TestSoapEndpoint"
serviceName="s:TestService"
xmlns:s="http://test">
<cxf:properties>
<!-- enable sending the stack trace back to client; the default value is false-->
<entry key="faultStackTraceEnabled" value="true" /> <entry key="dataFormat" value="PAYLOAD" />
</cxf:properties>
</cxf:cxfEndpoint>
セキュリティー上の理由から、スタックトレースには原因となる例外 (つまりスタックトレースの Caused by
以降の部分) は含まれません。スタックトレースに原因となる例外を含めたい場合は、以下のように cxfEndpoint
要素の exceptionMessageCauseEnabled
プロパティーを true
に設定します。
<cxf:cxfEndpoint id="router" address="http://localhost:9002/TestMessage"
wsdlURL="ship.wsdl"
endpointName="s:TestSoapEndpoint"
serviceName="s:TestService"
xmlns:s="http://test">
<cxf:properties>
<!-- enable to show the cause exception message and the default value is false -->
<entry key="exceptionMessageCauseEnabled" value="true" />
<!-- enable to send the stack trace back to client, the default value is false-->
<entry key="faultStackTraceEnabled" value="true" />
<entry key="dataFormat" value="PAYLOAD" />
</cxf:properties>
</cxf:cxfEndpoint>
exceptionMessageCauseEnabled
フラグは、テストおよび診断目的でのみ有効にしてください。サーバにおいて例外の元の原因を隠すことで、敵対的なユーザーがサーバーを調査しにくくするのが、通常の実践的なやり方です。
PAYLOAD モードでのサポートのストリーミング
2.8.2 では、camel-cxf コンポーネントは PAYLOAD モードを使用する場合に受信メッセージのストリーミングをサポートするようになりました。以前のバージョンでは、受信メッセージは完全に DOM 解析されました。メッセージが大きい場合は、時間がかかるため、大量のメモリーが使用されます。2.8.2 以降では、受信メッセージはルーティング中に javax.xml.transform.Source として残ることができます。ペイロードが変更されていない場合は、ターゲットの宛先に直接ストリーミングすることができます。一般的な「simple proxy」のユースケース(例: from("cxf:…").to("cxf:…")については、パフォーマンスが大幅に向上し、メモリーの要件が大幅に低下する可能性があります。
ただし、ストリーミングが適切でない場合もあります。ストリーミングの性質上、無効な受信 XML が処理チェーンの後半までキャッチされないことがあります。また、特定のアクションでは、メッセージを DOM に解析(WS-Security やメッセージトレースなど)する必要があります。この場合、ストリーミングの利点は制限されます。この時点で、ストリーミングを制御する 2 つの方法があります。
- エンドポイントプロパティー: "allowStreaming=false" をエンドポイントプロパティーとして追加し、ストリーミングのオン/オフをオン/オフにできます。
- コンポーネントプロパティー: CxfComponent オブジェクトには、コンポーネントから作成されるエンドポイントのデフォルトを設定できる allowStreaming プロパティーもあります。
- グローバルシステムプロパティー: オフの場合は、"org.apache.camel.component.cxf.streaming" のシステムプロパティーを "false" に追加して有効にすることができます。これはグローバルデフォルトを設定しますが、上記のエンドポイントプロパティーを設定すると、そのエンドポイントのこの値が上書きされます。
汎用 CXF Dispatch モードの使用
2.8.0 以降、camel-cxf コンポーネントは、任意の構造のメッセージを転送できる汎用 CXF ディスパッチモード をサポートします(つまり、特定の XML スキーマにバインドされません)。このモードを使用するには、CXF エンドポイントの wsdlURL および serviceClass 属性を指定するだけです。
<cxf:cxfEndpoint id="testEndpoint" address="http://localhost:9000/SoapContext/SoapAnyPort"> <cxf:properties> <entry key="dataFormat" value="PAYLOAD"/> </cxf:properties> </cxf:cxfEndpoint>
デフォルトの CXF ディスパッチクライアントは特定の SOAPAction ヘッダーを送信しないことに注意してください。したがって、ターゲットサービスに特定の SOAPAction 値が必要な場合は、SOAPAction(case-insensitive)キーを使用して Camel ヘッダーに提供されます。
75.1. JBoss Enterprise Application Platform での CXF コンシューマー
JBoss Enterprise Application Platform での camel-cxf コンシューマーの設定は、スタンドアロン Camel とは異なります。プロデューサーエンドポイントは通常どおり機能します。
JBoss Enterprise Application Platform では、camel-cxf コンシューマーはコンテナーによって提供されるデフォルトの Undertow HTTP サーバーを使用します。サーバーは undertow サブシステム設定内に定義されます。以下は、standalone.xml のデフォルト設定の抜粋です。
<subsystem xmlns="urn:jboss:domain:undertow:4.0"> <buffer-cache name="default" /> <server name="default-server"> <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" /> <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true" /> <host name="default-host" alias="localhost"> <location name="/" handler="welcome-content" /> <filter-ref name="server-header" /> <filter-ref name="x-powered-by-header" /> <http-invoker security-realm="ApplicationRealm" /> </host> </server> </subsystem>
この場合、Undertow は http および https socket-binding によって指定されたインターフェース/ポートをリッスンするように設定されます。デフォルトでは、これは http のポート 8080、https の場合は 8443 です。
たとえば、異なるホストまたはポートの組み合わせを使用してエンドポイントコンシューマーを設定すると、警告がサーバーログファイルに表示されます。たとえば、以下のホストおよびポート設定は無視されます。
<cxf:rsServer id="cxfRsConsumer" address="http://somehost:1234/path/to/resource" serviceClass="org.example.ServiceClass" />
<cxf:cxfEndpoint id="cxfWsConsumer" address="http://somehost:1234/path/to/resource" serviceClass="org.example.ServiceClass" />
[org.wildfly.extension.camel] (pool-2-thread-1) Ignoring configured host: http://somehost:1234/path/to/resource
ただし、コンシューマーはデフォルトのホストおよびポート localhost:8080 または localhost:8443 で引き続き利用できます。
camel-cxf コンシューマーを使用するアプリケーションは WAR としてパッケージ化する 必要があり ます。以前の Fuse on JBoss EAP リリースでは、JAR などの他のタイプのアーカイブの使用は許可されますが、サポート対象外になりました。
75.1.1. 代替ポートの設定
代替ポートが許可される場合は、JBoss Enterprise Application Platform サブシステム設定を使用して設定する必要があります。詳細は、サーバーのドキュメントで説明されています。
75.1.2. SSL の設定
SSL を設定するには、JBoss Enterprise Application Platform の『SSL 設定ガイド』を参照してください。
75.1.3. Elytron を使用したセキュリティー設定
Fuse on JBoss EAP は、Elytron セキュリティーフレームワークでの camel-cxf コンシューマーエンドポイントのセキュア化をサポートします。
75.1.3.1. セキュリティードメインの設定
Elytron で Fuse on JBoss EAP アプリケーションをセキュアにするには、WAR デプロイメントの WEB-INF/jboss-web.xml
内でアプリケーションセキュリティードメインを参照する必要があります。
<jboss-web> <security-domain>my-application-security-domain</security-domain> </jboss-web>
< ;security-domain>
設定は、Undertow サブシステムによって定義される < application-security-domain&
gt; の名前を参照します。たとえば、Undertow サブシステム < application-security-domain
> は、以下のように JBoss Enterprise Application Platform サーバーの standalone.xml
設定ファイル内に設定されます。
<subsystem xmlns="urn:jboss:domain:undertow:6.0"> ... <application-security-domains> <application-security-domain name="my-application-security-domain" http-authentication-factory="application-http-authentication"/> </application-security-domains> </subsystem>
< ;http-authentication-factory>
application-http-authentication
は Elytron サブシステム内に定義されます。application-http-authentication
は、standalone.xml
および standalone-full.xml
サーバー設定ファイルの両方でデフォルトで利用できます。以下に例を示します。
<subsystem xmlns="urn:wildfly:elytron:1.2"> ... <http> ... <http-authentication-factory name="application-http-authentication" http-server-mechanism-factory="global" security-domain="ApplicationDomain"> <mechanism-configuration> <mechanism mechanism-name="BASIC"> <mechanism-realm realm-name="Application Realm" /> </mechanism> <mechanism mechanism-name="FORM" /> </mechanism-configuration> </http-authentication-factory> <provider-http-server-mechanism-factory name="global" /> </http> ... </subsystem>
application
> は、-http-authentication
という名前の <http-authentication-factoryApplicationDomain
という Elytron セキュリティードメインへの参照を保持します。
Elytron サブシステムの設定方法の詳細は、Elytron の ドキュメントを参照してください。
75.1.3.2. セキュリティー制約、認証方法、およびセキュリティーロールの設定
camel-cxf コンシューマーエンドポイントのセキュリティー制約、認証方法、およびセキュリティーロールは、WAR デプロイメント WEB-INF/web.xml
内で設定できます。たとえば、BASIC 認証を設定するには、次のコマンドを実行します。
<web-app> <security-constraint> <web-resource-collection> <web-resource-name>secure</web-resource-name> <url-pattern>/webservices/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>my-role</role-name> </auth-constraint> </security-constraint> <security-role> <description>The role that is required to log in to /webservices/*</description> <role-name>my-role</role-name> </security-role> <login-config> <auth-method>BASIC</auth-method> <realm-name>my-realm</realm-name> </login-config> </web-app>
Servlet Specification で定義された < url-pattern
> は Web アプリケーションのコンテキストパスに相対することに注意してください。アプリケーションが my-app.war
としてパッケージされている場合、JBoss Enterprise Application Platform はコンテキストパス /my-app
でアクセスできるようになり、< url-patternpattern
> /webservices/*
は /my-app
への相対パスに適用されます。
たとえば、http://my-server/my-app/webservices/my-endpoint
に対するリクエストは /webservices/*
パターンと一致しますが、http://my-server/webservices/my-endpoint
は一致しません。
これは、Fuse on JBoss EAP ではベースパスがホスト Web アプリケーションコンテキストパス外にある camel-cxf エンドポイントコンシューマーを作成することができるため重要です。たとえば、my-app.war
内に http://my-server/webservices/my-endpoint
の camel-cxf コンシューマーを作成できます。
このようなコンテキストエンドポイントのセキュリティー制約を定義するために、Fuse on JBoss EAP はカスタム 標準以外 の <url-pattern
&
gt; 規則をサポートします。たとえば、my-app.war
内で http://my-server/webservices/my-endpoint
をセキュアにするには、以下の設定を web.xml
に追加します。
<web-app> <security-constraint> <web-resource-collection> <web-resource-name>secure</web-resource-name> <url-pattern>///webservices/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>my-role</role-name> </auth-constraint> </security-constraint> <security-role> <description>The role that is required to log in to /webservices/*</description> <role-name>my-role</role-name> </security-role> <login-config> <auth-method>BASIC</auth-method> <realm-name>my-realm</realm-name> </login-config> </web-app>