この章の内容は次のとおりです。
通常、コンポジットの起動にはSOAP over HTTPを使用します。このためには、Webサービス・バインディングを使用してコンポジットのSOAPサービスを作成する必要があります。これに対して、直接バインディングを使用すると、より緊密な統合を作成できます。Javaクライアントは、直接バインディングを使用してコンポジット・サービスを直接起動できるため、Webサービス・バインディングで必要なXMLへの中間変換が不要になります。
直接バインディングでは、次の2種類の起動スタイルがあります。
インバウンド直接バインディング
直接サービス・バインディング・コンポーネントを使用すると、外部クライアントは直接バインディング起動APIを使用してメッセージを送信できます。この場合、直接バインディング起動APIでは、JNDI接続パラメータを使用し、クライアントにかわって接続オブジェクトが作成されます。
アウトバウンド直接バインディング(直接参照バインディング)
直接参照バインディング・コンポーネントでは、Remote Method Invocation (RMI)を介した外部サービスへのSOAメッセージの直接送信がサポートされています。直接インバウンド起動APIと同様に、外部サービスではSOA起動APIを実装する必要があります。
直接アウトバウンド・バインディングの場合、接続オブジェクトは、バインディングに対して構成された外部サービスBeanのJNDI名を使用して作成されます。
直接バインディングは、interface句、およびcallbackInterface
句(オプション)を提供するinterface.wsdl
に関連付けられている必要があります。また、コンポジットには、関連するWSDLがインポートされている必要があります。
サービス・バインディング・コンポーネントは、直接バインディングを通知するWSDLの変更済バージョンも公開します。
次の例は、直接サービス・バインディング・コンポーネントを使用するサンプル構成を示しています。
<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
を定義する一連のプロパティ(oracle.soa.management.facade.Locator
を参照)。
ConnectionFactory
クラス名(oracle.soa.management.facade.Locator
を参照)。
ConnectionFactory
クラスはoracle.soa.api.invocation.DirectConnectFactory
インタフェースを実装する必要があります。
ConnectionFactory
クラス名を指定しない場合は、デフォルトのoracle.soa.api.JNDIDirectConnectionFactory
が使用されます。デフォルトのコネクション・ファクトリを使用するには、EJBのルックアップ名を指定する必要があります。
外部サービスで使用されるアドレス
このアドレス値は、バインディング・コンポーネントでは処理されませんが、起動時にサービスBeanに渡されます。
addressingVersion
(オプション):
デフォルトで使用されるアドレッシング・バージョンは2005/08.
です。
useSSLForCallback
コールバックJNDI接続にSecure Socket Layer (SSL)を使用します。このフラグをtrue
に設定すると、WS-AddressingのreplyTo
ヘッダーは、サービスにSSL JNDIポートでのコールバックを指示します。
次の例にサンプルの構成を示します。
<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>
直接バインディング・コンポーネントでは、同期および非同期の両方の起動パターンがサポートされています。図38-1で同期起動パターンのサンプルを、図38-2で非同期起動パターンのサンプルを説明します。
次に、直接バインディング起動APIで使用する各種パッケージを示します。
oracle.soa.management.facade.Locator
oracle.soa.management.facade.Locator
インタフェースは、直接接続を返すcreateConnection
メソッドを公開します。次の例に示すように、Locator
はDirectConnection
を返すためのメソッドを公開します。
import java.util.Map; public interface DirectConnectionFactory { DirectConnection createDirectConnection(CompositeDN compositeDN, String serviceName) throws Exception;
次の例に示すように、LocatorFactory
実装を使用してDirectConnection
を取得できます。
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
インタフェースは、直接バインディングを使用してコンポジット・サービスを起動します。詳細は、次を参照してください。
oracle.soa.api.message.Message
Message
インタフェースは、交換されたデータをカプセル化します。詳細は、次を参照してください。
直接バインディングでは、次の例に示すメソッドを使用した同期直接起動もサポートされています。
<T> Message<T> request(String operationName, Message<T> message)
throws InvocationException, FaultException
非同期起動は、メッセージ・インスタンスに設定されているWS-Addressingヘッダーに依存します。すべてのヘッダーはWS-Addressing仕様に準拠している必要があります。
直接バインディング起動APIを使用すると、クライアントはWS-AddressingのReplyTo
SOAPヘッダーを指定し、宛先と通信してレスポンスを受信できます。
注意:
サポートされているアドレッシング・バージョンは次のとおりです。
下に、非同期起動に使用される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コンポーネントに対して次のプロパティが使用可能になります。
replyToAddress
= sb://testserver:9001/callback
replyToReferenceParameter
: WSAの要素: ReferenceParameters
直接バインディングJavaクライアント・コードのコンパイルには、次のJARファイルが必要です。
$FMWHOME/soa/soa/modules/oracle.soa.mgmt_11.1.1/soa-infra-mgmt.jar
直接バインディングJavaクライアント・コードの実行には、次のJARファイルが必要です。
$FMWHOME/wlserver/server/lib/wlthint3client.jar
$FMWHOME/soa/soa/modules/oracle.soa.fabric_11.1.1/oracle-soa-client-api.jar
直接バインディング起動APIで使用するサービス・パスは、SOA直接アドレス・パターンに従います。
soadirect:/CompositeDN/serviceName
(CompositeDN
はコンポジット識別名)
SOA直接アドレスでは、CompositeDN
の形式は次のとおりです(label
はオプションです)。
domainName/compositeName[!compositeVersion[*label]]
直接バインディングでは、SOAトランザクション伝播機能がサポートされています。この機能は、次の2つの方法でクライアントから起動できます。
クライアントからJavaトランザクションを開始し、すべてのデータベース操作を実行した後にコミットします。データベース操作は、クライアント側からの正常なコミットの後にコミットする必要があります。
クライアント側からJavaトランザクションを開始します。SOAコンポジットで操作中にフォルトがスローされた場合は、クライアント側からトランザクションをロールバックします。これで、すべてのデータベース操作がロールバックされます。
<wsdl:portType name="MyServicePortType"> <wsdl:operation name="Execute"> <wsdl:input message="exp:ExecuteRequestMsg"/> <wsdl:output message="exp:ExecuteResponseMsg"/> <wsdl:fault name="executeFault" message="exp:ExecuteFaultMsg"/> <wsdl:fault name="genericFault" message="exp:GenericFaultMsg"/> </wsdl:operation> </wsdl:portType>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <soapenv:Fault xmlns:ns0="http://www.example.org/MyService"> <faultcode>ns0:genericFault</faultcode> <faultstring/> <faultactor/> <detail> <GenericFault xmlns="http://www.example.org/FaultInfo"> <FaultInfo> <ErrorDescription>Error - soap1.1</ErrorDescription> </FaultInfo> </GenericFault> </detail> </soapenv:Fault> </soapenv:Body> </soapenv:Envelope>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Header xmlns:exem="http://www.example.org/MyService"/> <soap:Body xmlns:exem="http://www.example.org/MyService"> <soap:Fault> <soap:Fault> <soap:Value>soap:Receiver</soap:Value> <soap:Subcode> <soap:Value xmlns:ns1=" soap:value>"="" target="_blank">http://www.example.org/MyService">ns1:genericFault</soap:Value> </soap:Subcode> </soap:Code> <soap:Reason> <soap:Text xml:lang="pt">Failure calling partner.</soap:Text> </soap:Reason> <soap:Node>...</soap:Node> <soap:Detail> <err:GenericFault xmlns:err="http://www.example.org/FaultInfo"> <err:FaultInfo> <err:ErrorDescription>Error Desc</err:ErrorDescription> </err:FaultInfo> </err:GenericFault> </soap:Detail> </soap:Fault> </soap:Body> </soap:Envelope>
Oracle JDeveloperの「コンポーネント」ウィンドウの「直接」アイコン(図38-3を参照)では、RMIでのSOAとのSOAメッセージ交換がサポートされています。
Oracle JDeveloperでは、Oracle Service Busまたは別のSOAコンポジットのいずれかを起動する直接サービス・バインディングと直接参照バインディングの作成がサポートされています。
注意:
クライアントが直接バインディングを使用してコンポジット・サービスを起動するには、そのクラスパスにsoa-infra-mgmt.jar
、wlthint3client.jar
およびoracle-soa-client-api.jar
が含まれている必要があります。
直接バインディング起動APIの詳細は、「直接バインディング起動APIの概要」を参照してください。
Oracle JDeveloperの「コンポーネント」ウィンドウの「直接」アイコンを使用して、SOAコンポジット・アプリケーションを起動できます。
インバウンド直接バインディング・サービスを作成する手順は、次のとおりです。
SOAコンポジット・アプリケーションまたはOracle Service Busのいずれかを起動するために、Oracle JDeveloperの「コンポーネント」ウィンドウの「直接」アイコンを使用して、アウトバウンド直接バインディング参照を作成できます。
注意:
Oracle SOA SuiteとOracle Service Busが異なるドメインにある場合、それらのドメイン間の信頼を有効化する必要があります。
アウトバウンド直接バインディング参照を作成する手順は、次のとおりです。
次の例に示すように、JNDIルックアップのプロセス中にサーバーに対してJNDIセキュリティ資格証明を渡すことによる認証時に、ユーザー・アイデンティティを確立できます。
public static void main(String[] args) throws Exception { String operation = "process"; // This is the request message XML String ns = "http://xmlns.oracle.com/DirectBinding_jws/EchoBPEL/BPELProcess1"; String payloadXML = "<ns1:process xmlns:ns1=\"" + ns + "\">\n" + " <ns1:input>wew</ns1:input>\n" + "</ns1:process>"; String serviceAddress = "soadirect:/default/EchoBPEL!1.0/DService1"; // Specify the direct binding connection properties 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,username); props.put(Context.SECURITY_CREDENTIALS, password); // Create the direct binding connection, using those context properties DirectConnectionFactory factory = JNDIDirectConnectionFactory.newInstance(); try { DirectConnection dc = factory.createConnection(serviceAddress, props); // Parse the XML request message DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); Document doc = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(payloadXML))); // Prepare the payload for inclusion in the Message object Map<String, Element> payload = new HashMap<String, Element>(); payload.put("payload", doc.getDocumentElement()); Message<Element> request = XMLMessageFactory.getInstance().createMessage(payload); Message<Element> response = dc.request(operation, request); } finally { dc.close(); } }
あるSOAコンポジット・アプリケーションが、異なるホスト上の別のSOAコンポジット・アプリケーションを直接バインディングを介して呼び出し、両コンポジットが同一のサーバー名/ドメイン名を持つホスト上にある場合、呼出しが失敗します。
これは、Oracle WebLogic Serverトランザクション・サブシステムでは、トランザクション管理が正常に機能するためにドメイン名およびサーバー名が異なっている必要があるためです。トランザクション・サブシステムは、これらの名前を使用してトランザクションに関連するサーバーの場所をトラッキングします。呼出し時に2つのサーバーが同一の名前を持つ場合、トランザクション・サブシステムは間違って2つのサーバーを混同してしまいます。
別個のサーバー名およびドメイン名を持つホストを使用するようにしてください。
この項では、APIの使用方法について説明します。接続パラメータを設定し、直接バインディングによってSOAコンポジット・アプリケーションを起動する方法、および直接バインディング起動を起動するようにメッセージ・オブジェクトを変更する方法を示します。
// 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, jndi.WLInitialContextFactory"); properties.put(Context.PROVIDER_URL, "t3://HOST:PORT"); properties.put(Context.SECURITY_PRINCIPAL, USERNAME); properties.put(Context.SECURITY_CREDENTIALS, PASSWORD); DirectConnection conn = dcFactory.createConnection("soadirect:/default/MyComposite!1.0/MyService", properties);
// Messages are created using the MessageFactory // Message objects are subsequently modified to be used for an invocation. Message<Element> request = XMLMessageFactory.getInstance().createMessage(); // Define a Map of WSDL part names to matching XML Element objects Map<String, Element> partData; 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);
Hashtable jndiProps = new Hashtable(); jndiProps.put(Context.PROVIDER_URL, "t3://" + HOST + ':' + PORT); jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); jndiProps.put(Context.SECURITY_PRINCIPAL,USERNAME); jndiProps.put(Context.SECURITY_CREDENTIALS, PASSWORD); Locator locator = LocatorFactory.createLocator(jndiProps); CompositeDN compositedn = new CompositeDN(domainName, compositename, version); String serviceName = "HelloEntry"; DirectConnection conn = locator.createDirectConnection(compositedn, serviceName);