この章の内容は次のとおりです。
通常、コンポジットの起動には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);