この章では、直接バインディング起動APIについて説明し、この起動APIを使用してSOAコンポジット・アプリケーションを起動する方法について説明します。
項目は次のとおりです。
通常、コンポジットの起動にはSOAP over HTTPを使用します。このためには、Webサービス・バインディングを使用してコンポジットのSOAPサービスを作成する必要があります。これに対して、直接バインディングを使用すると、より緊密な統合を作成できます。Javaクライアントは、直接バインディングを使用してコンポジット・サービスを直接起動できるため、Webサービス・バインディングで必要なXMLへの中間変換が不要になります。
直接バインディングでは、次の2種類の起動スタイルがあります。
インバウンド直接バインディング
直接サービス・バインディング・コンポーネントを使用すると、外部クライアントは直接バインディング起動APIを使用してメッセージを送信できます。この場合、直接バインディング起動APIでは、JNDI接続パラメータを使用し、クライアントにかわって接続オブジェクトが作成されます。
アウトバウンド直接バインディング(直接参照バインディング)
直接参照バインディング・コンポーネントでは、RMIを介した外部サービスへのSOAメッセージの直接送信がサポートされています。直接インバウンド起動APIと同様に、外部サービスではSOA起動APIを実装する必要があります。
直接アウトバウンド・バインディングの場合、接続オブジェクトは、バインディングに対して構成された外部サービスBeanのJNDI名を使用して作成されます。
直接バインディングは、interface句、およびcallbackInterface
句(オプション)を提供するinterface.wsdl
に関連付けられている必要があります。また、コンポジットには、関連するWSDLがインポートされている必要があります。
サービス・バインディング・コンポーネントは、直接バインディングを通知するWSDLの変更済バージョンも公開します。
直接サービス・バインディング・コンポーネント
例37-1に、直接サービス・バインディング・コンポーネントを使用するサンプル構成を示します。
例37-1 直接サービス・バインディング・コンポーネント
<service name="direct2"> <interface.wsdl interface="http://xmlns.oracle.com/asyncNonConvDocLit#wsdl.interface(asyncNonConvD ocLit)" callbackInterface="http://xmlns.oracle.com/asyncNonConvDocLit#wsdl.interface(async NonConvDocLitCallback)" xmlns:ns="http://xmlns.oracle.com/sca/1.0"/> <binding.direct/> </service>
直接参照バインディング・コンポーネント
直接参照バインディング・コンポーネントでは、ユーザー指定のSOAインボーカに接続するために次の情報が必要です。
プロパティ
エンド・サービスのDirectConnection
を定義する一連のプロパティ。
ConnectionFactory
クラス名
ConnectionFactory
クラスはoracle.soa.api.invocation.DirectConnectFactory
インタフェースを実装する必要があります。
外部サービスで使用されるアドレス
このアドレス値は、バインディング・コンポーネントでは処理されませんが、起動時にサービスBeanに渡されます。
AddressingVersion
(オプション)
デフォルトで使用されるアドレッシング・バージョンは2005/08
です。
useSSLForCallback
コールバックJNDI接続のSSLを使用します。このフラグをtrue
に設定すると、WSA replyTo
ヘッダーは、サービスにSSL JNDIポートでのコールバックを指示します。
例37-2に、サンプル構成を示します。
例37-2 サンプル構成
<reference name="HelloReference" ui:wsdlLocation="HelloService.wsdl"> <interface.wsdl interface="http://hello.demo.oracle/#wsdl.interface(HelloInterface)"/> <binding.direct connection-factory="oracle.soa.api.JNDIDirectConnectionFactory" addressingVersion="http://www.w3.org/2005/08/addressing" address="soadirect://syncOut" useSSLForCallback="false"> <property name="oracle.soa.api.invocation.direct.bean">MyDirectTestServiceBean#directEjb.Tes tInvoker</property> <property name="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</property > <property name="java.naming.provider.url">t3://@host:@port</property> </binding.direct> </reference>
直接バインディング・コンポーネントでは、同期および非同期の両方の起動パターンがサポートされています。図37-1で同期起動パターンのサンプルを、図37-2で非同期起動パターンのサンプルを説明します。
次に、直接バインディング起動APIで使用する各種パッケージを示します。
oracle.soa.management.facade.Locator
oracle.soa.management.facade.Locator
インタフェースは、直接接続を返すcreateConnection
メソッドを公開します。例37-3に示すように、Locator
はDirectConnection
を返すためのメソッドを公開します。
例37-3 oracle.soa.management.facade.Locator
import java.util.Map; public interface DirectConnectionFactory { DirectConnection createDirectConnection(CompositeDN compositeDN, String serviceName) throws Exception;
例37-4に示すように、LocatorFactory
実装を使用してDirectConnection
を取得できます。
例37-4 LocatorFactory実装
Hashtable jndiProps = new Hashtable(); jndiProps.put(Context.PROVIDER_URL, "t3://" + hostname + ':' + portname + "/soa-infra"); jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory"); jndiProps.put(Context.SECURITY_PRINCIPAL,"weblogic"); jndiProps.put(Context.SECURITY_CREDENTIALS,"welcome1"); jndiProps.put("dedicated.connection","true"); Locator locator = LocatorFactory.createLocator(jndiProps); CompositeDN compositedn = new CompositeDN(domainName, compositename, version); String serviceName = "HelloEntry"; return locator.createDirectConnection(compositedn, serviceName);
oracle.soa.api.invocation.DirectConnection
DirectConnection
インタフェースは、直接バインディングを使用してコンポジット・サービスを起動します。
例37-5にDirectConnection.java
を示します。
例37-5 DirectConnection.java
import oracle.soa.api.message.Message; public interface DirectConnection { <T> Message<T> request(String operationName, Message<T> message) throws InvocationException, FaultException; <T> void post(String operationName, Message<T> message) throws InvocationException; void close();}
oracle.soa.api.message.Message
Message
インタフェースは、交換されたデータをカプセル化します。
例37-6にMessage
interface.java
を示します。
例37-6 Message interface.java
import java.util.List; import java.util.Map; import org.w3c.dom.Element; public interface Message<T> { // Instance-tracking property names final static String FLOW_ID; final static String CONVERSATION_ID; final static String PARENT_ID; void setPayload(Payload<T> payload); Payload<T> getPayload(); void addAttachment(Attachment attachment); List<Attachment> getAttachments(); void addHeader(Element header); void setHeaders(List<Element> headers); List<Element> getHeaders(); void setProperties(Map<String, Object> properties); void setProperty(String name, Object value); Map<String, Object> getProperties(); Object getProperty(String name); }
Facade APIの詳細は、Oracle Fusion MiddlewareのOracle SOA Suite Infrastructure Management Java API リファレンスを参照してください。
直接バインディングでは、例37-7に示すメソッドを使用した同期直接起動もサポートされています。
非同期起動は、メッセージ・インスタンスに設定されているWS-Addressingヘッダーに依存します。すべてのヘッダーはWS-Addressing仕様に準拠している必要があります。
直接バインディング起動APIを使用すると、クライアントはWS-AddressingのReplyTo
SOAPヘッダーを指定し、宛先と通信してレスポンスを受信できます。
注意: サポートされているアドレッシング・バージョンは次のとおりです。 |
例37-8に、非同期起動に使用されるWS-Addressingヘッダーの例を示します。
例37-8 WS-Addressingヘッダー
<wsa:MessageID>D6202742-D9D9-4023-8167-EF0AB81042EC</wsa:MessageID> <wsa:ReplyTo xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsa:Address>sb://testserver:9001/callback</wsa:Address> <wsa:ReferenceParameters> <soa:callback xmlns:soa="http://xmlns.oracle.com/soa/direct" connection-factory="mytest.MyDirectionConnectionFactory"> <soa:property name="oracle.soa.api.invocation.direct.bean" value="myTest.MyDirectConnectionBean"/> <soa:property name="java.naming.provider.url" value="t3://test:8001"/> <soa:property name="java.naming.factory.initial" value="weblogic.jndi.WLInitialContextFactory"/> </soa:callback> </wsa:ReferenceParameters> </wsa:ReplyTo>
注意: コールバックとそのプロパティ要素は、SOA直接ネームスペースを使用して正しく修飾する必要があります。 |
直接バインディング・コンポーネントは、メッセージ・インスタンスに設定されたAddressingヘッダーの解析を担当します。この例には、wsa:MessageID
およびwsa:ReplyTo
の2つのヘッダーがあります。サービス・バインディング・コンポーネントでは、内部SOAコンポーネントに対して次のプロパティが使用可能になります。
tracking.conversationId
= D6202742-D9D9-4023-8167-EF0AB81042E
replyToAddress
= sb://testserver:9001/callback
replyToReferenceParameter
: WSAの要素: ReferenceParameters
直接バインディング起動APIで使用するサービス・パスは、SOA直接アドレス・パターンに従います。
soadirect:/CompositeDN/serviceName
(CompositeDN
はコンポジット識別名)
SOA直接アドレスでは、CompositeDN
の形式は次のとおりです。
domainName/compositeName[!compositeVersion[*label]]
直接バインディングでは、SOAトランザクション伝播機能がサポートされています。この機能は、次の2つの方法でクライアントから起動できます。
クライアントからJavaトランザクションを開始し、すべてのデータベース操作を実行した後にコミットします。データベース操作は、クライアント側からの正常なコミットの後にコミットする必要があります。
クライアント側からJavaトランザクションを開始します。SOAコンポジットで操作中にフォルトがスローされた場合は、クライアント側からトランザクションをロールバックします。これで、すべてのデータベース操作がロールバックされます。
図37-3に示すように、Oracle JDeveloperの「直接バインディング」コンポーネントでは、RMIでのSOAとのSOAメッセージ交換がサポートされています。
Oracle JDeveloperでは、Oracle Service Busまたは別のSOAコンポジットのいずれかを起動する直接サービス・バインディングと直接参照バインディングの作成がサポートされています。
注意: クライアントが直接バインディングを使用してコンポジット・サービスを起動するには、そのクラスパスにsoa-infra-mgmt.jar とoracle-soa-client-api.jar の両方が含まれている必要があります。 |
直接バインディング起動APIの詳細は、第37.2項「直接バインディング起動APIの概要」を参照してください。
SOAコンポジット・アプリケーションは、Oracle JDeveloperの「直接バインディング」オプションを使用して起動できます。
インバウンド直接バインディング・サービスを作成する手順は、次のとおりです。
Oracle JDeveloperを開きます。
「コンポーネント・パレット」から「SOA」を選択します。
「サービス・アダプタ」リストから、「直接バインディング」コンポーネントを「公開されたサービス」スイムレーンにドラッグします。「直接バインディングの作成」ダイアログが表示されます。
表37-1に記載されている詳細を入力します。
表37-1 「直接バインディング・サービス」ダイアログのフィールドと値
フィールド | 値 |
---|---|
名前 |
名前を入力します。 |
タイプ |
リストから「サービス」を選択します。 |
参照ターゲット |
このサービスを「公開されたサービス」スイムレーンで定義する場合、このフィールドは無効になります。 |
WSDL URL |
WSDLファイルのURLの場所。既存のWSDLがある場合は、「既存のWSDLを検索します。」オプションをクリックします。それ以外の場合は、「スキーマからWSDLを生成します。」をクリックします。 |
ポート・タイプ |
WSDLファイルのポート・タイプ。リストからポート・タイプを選択する必要があります。 |
コールバック・ポート・タイプ |
非同期プロセスのコールバック・ポート・タイプ。 |
「コールバックに対するSSLの使用」 |
コールバックに対してSSLを使用する場合に選択します。 |
アドレス |
WSDLが具体的で少なくとも1つの直接バインディングがある場合、このフィールドは自動的に移入されます。 |
プロバイダURL |
WSDLが具体的で少なくとも1つの直接バインディングがある場合、このフィールドは自動的に移入されます。 |
ローカルJNDIプロバイダの使用 |
ローカルJNDIプロバイダを使用する場合に選択します。 |
WSDLとその依存アーティファクトをプロジェクトにコピー。 |
このチェック・ボックスの選択を解除します。このチェック・ボックスを選択した場合は、WSDLファイルをローカルでコピーすると、リモートWSDLの更新時に同期の問題が発生する可能性があります。 |
完了すると、図37-4に示すように、「直接バインディングの作成」ダイアログが表示されます。
「OK」をクリックします。
図37-5に示すように、直接バインディング・サービスがSOAコンポジット・エディタに表示されます。丸囲みの1本の矢印は、同期する一方向の直接バインディング・コンポーネントであることを示します。
Oracle JDeveloperの「直接バインディング」オプションを使用してアウトバウンド直接バインディング参照を作成し、コンポジット・アプリケーションまたはOracle Service Busを起動できます。
アウトバウンド直接バインディング参照を作成する手順は、次のとおりです。
Oracle JDeveloperを開きます。
「コンポーネント・パレット」から「SOA」を選択します。
「サービス・アダプタ」リストから、「直接バインディング」コンポーネントを「外部参照」スイムレーンにドラッグします。「直接バインディングの作成」ダイアログが表示されます。
表37-2に記載されている詳細を入力します。
表37-2 「直接バインディング・サービス」ダイアログのフィールドと値
フィールド | 値 |
---|---|
名前 |
名前を入力します。 |
タイプ |
リストから「参照」を選択します。 |
参照ターゲット |
直接バインディング・サービスの実行先となる参照ターゲットを選択します。
|
WSDL URL |
WSDLファイルのURLの場所。既存のWSDLがある場合は、「既存のWSDLを検索します。」オプションをクリックします。 |
ポート・タイプ |
WSDLファイルのポート・タイプ。リストからポート・タイプを選択する必要があります。 |
コールバック・ポート・タイプ |
非同期プロセスのコールバック・ポート・タイプ。 |
「コールバックに対するSSLの使用」 |
コールバックに対してSSLを使用する場合に選択します。 |
アドレス |
具体的なWSDL URLとポート・タイプを選択した場合、このフィールドは自動的に移入されます。ただし、具体的でないWSDLが指定されている場合、このフィールドは手動で入力する必要があります。 |
プロバイダURL |
具体的なWSDL URLとポート・タイプを選択した場合、このフィールドは自動的に移入されます。ただし、具体的でないWSDLが指定されている場合、このフィールドは手動で入力する必要があります。 |
ローカルJNDIプロバイダの使用 |
ローカルJNDIプロバイダを使用する場合に選択します。 |
WSDLとその依存アーティファクトをプロジェクトにコピー。 |
このチェック・ボックスの選択を解除します。このチェック・ボックスを選択した場合は、WSDLファイルをローカルでコピーすると、リモートWSDLの更新時に同期の問題が発生する可能性があります。 |
完了すると、図37-6に示すように、「直接バインディングの作成」ダイアログが表示されます。Oracle SOA SuiteのサービスをOracle Service Busで使用する方法の詳細は、『Oracle Fusion Middleware Oracle Service Bus開発者ガイド』のOracle SOA Suiteのトランスポート(SOA-DIRECT)に関する項を参照してください。
「OK」をクリックします。
図37-7に示すように、直接バインディング参照がデザイナに表示されます。丸囲みの1本の矢印は、同期する一方向の直接バインディング参照コンポーネントであることを示します。
例37-9に示すように、直接バインディングの起動中にJ2SEクライアントでアイデンティティを設定できます。
例37-9 直接バインディングを起動するJ2SEクライアントのアイデンティティの設定
public static void main(String[] args) throws Exception { Invoker invoker = new Invoker(); String payloadXML="<ns1:process xmlns:ns1=\"http://xmlns.oracle.com/DirectBinding_jws/EchoBPEL/BPELProcess1\"> " +"\n" + "<ns1:input>wew</ns1:input>" + "\n"+ "</ns1:process>" ; String serviceAddress = "soadirect:/default/EchoBPEL!1.0/DService1"; System.out.println("***** test Sync ****"); DirectConnectionFactory factory = JNDIDirectConnectionFactory.newInstance(); Message<Element> m = getAsyncRequest(payloadXML); Map<String, Object> props = new HashMap<String, Object>(); props.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); props.put(Context.PROVIDER_URL, "t3://" + hostname + ':' + portname); props.put(Context.SECURITY_PRINCIPAL,"xtest-soa1-user"); props.put(Context.SECURITY_CREDENTIALS,"welcome1"); DirectConnection conn = factory.createConnection(serviceAddress, props); DirectConnection conn = getConnection(serviceAddress); Document doc = DirectBindingXMLUtil.getDocumentFromString(payloadXML); Element element = doc.getDocumentElement(); Map<String, Element> payload = new HashMap<String, Element>(); payload.put("payload", element); Message<Element> m = XMLMessageFactory.getInstance().createMessage(payload); List<Element> headers = createWSAHeaders("payload:BPELSyncTest:msgID:1234567"); for( Element e : headers) m.addHeader(e); try { ctx = new InitialContext(props); conn.request("process", m); } finally { if (null != ctx) ctx.close(); } //System.out.println(ret); }
前述の例のキー・ポイントは次のとおりです。
直接接続を起動する前に、セキュリティ・プリンシパル/プリンシパル資格証明を使用してInitialContext
を作成します。これにより、ログインします。
InitialContext
を終了します。これにより、ログアウトします。
try { ctx = new InitialContext(props); conn.request("process", m); } finally { if (null != ctx) ctx.close(); }
あるSOAコンポジット・アプリケーションが、異なるホスト上の別のSOAコンポジット・アプリケーションを直接バインディングを介して呼び出し、両コンポジットが同一のサーバー名/ドメイン名を持つホスト上にある場合、呼出しが失敗します。
これは、Oracle WebLogic Serverトランザクション・サブシステムでは、トランザクション管理が正常に機能するためにドメイン名およびサーバー名が異なっている必要があるためです。トランザクション・サブシステムは、これらの名前を使用してトランザクションに関連するサーバーの場所をトラッキングします。呼出し時に2つのサーバーが同一の名前を持つ場合、トランザクション・サブシステムは間違って2つのサーバーを混同してしまいます。
別個のサーバー名およびドメイン名を持つホストを使用するようにしてください。
例37-10から例37-12に、このAPIの使用例を示します。この項では、接続パラメータを設定し、直接バインディングによってSOAコンポジット・アプリケーションを起動する方法、および直接バインディング起動を起動するようにメッセージ・オブジェクトを変更する方法を示します。
例37-10 接続パラメータの使用例
// The JNDIDirectConnectionFactory can be used to establish SOA instance connections for exchanging messages over the direct binding. DirectConnectionFactory dcFactory = JNDIDirectConnectionFactory.newInstance(); // Connections are created based on the configuration, which is a map of standard // naming properties, which will be used for the underlying connection lookup. Map<String, Object> properties = new HashMap<String, Object>(); properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); properties.put(Context.PROVIDER_URL, "t3://HOST:PORT"); DirectConnection conn = dcFactory.createConnection("soadirect:/default/MyComposite!1.0/MyService", properties);
例37-11 メッセージの使用例
//Messages are created using the MessageFactory Message<Element> request = XMLMessageFactory.getInstance().createMessage(); //Message objects are then modified to be used for an invocation Map<String, Element> partData; // Define a Map of WSDL part names to matching XML Element objects Payload<Element> payload = PayloadFactory.createXMLPayload(partData); request.setPayload(payload); // One-way invocation conn.post("onewayoperation", request); // Request-reply invocation Message<Element> response = conn.request("requestreplyoperation", request);
例37-12 LocatorFactoryの使用例
//A Sample Java Code Hashtable jndiProps = new Hashtable(); jndiProps.put(Context.PROVIDER_URL, "t3://" + hostname + ':' + portname + "/soa-infra"); jndiProps.put(Context.INITIAL_CONTEXT -FACTORY,"weblogic.jndi.WLInitialContextFactory"); jndiProps.put(Context.SECURITY_PRINCIPAL,"weblogic"); jndiProps.put(Context.SECURITY_CREDENTIALS,"welcome1"); jndiProps.put("dedicated.connection","true"); Locator locator = LocatorFactory.createLocator(jndiProps); CompositeDN compositedn = new CompositeDN(domainName, compositename, version); String serviceName = "HelloEntry"; return locator.createDirectConnection(compositedn, serviceName);