Order Management拡張でのWebサービスのコールに関するガイドライン
拡張機能がwebサービスを呼び出す場合は、次のガイドラインを適用してください。
Webサービスへのコールの処理
コードでinvokeSoapServiceメソッドを複数回使用する場合は、2回目のコールを行う前に、最初のコールからのレスポンスの処理を終了してください。正しいコード
明細 | コード |
---|---|
1 |
def serviceInvoker = context.getServiceInvoker();
|
2 |
def response1 = serviceInvoker.invokeSoapService("connector1",payload).getSoapBody();
|
3 |
String tagStorageLimitDays = response1.getElementsByTagNameNS("*", "tagStorageLimitDays").item(0)?.getTextContent()?: 0;
|
4 |
def response2 = serviceInvoker.invokeSoapService("webservice2", payload).getSoapBody();
|
5 |
String status = response2.getElementsByTagNameNS("*", "status").item(0)?.getTextContent()?: "failure";
|
このコードは、webservice2をコールする前にwebservice1からのレスポンスを処理します。 これは、コードを記述する方法です。
- 行2はwebサービスwebservice1をコールし、行3はwebservice1からのレスポンスを処理します。
- 行4はwebサービスwebservice2をコールし、行5はWebサービスwebservice2からのレスポンスを処理します。
無効なコード
明細 | コード |
---|---|
1 |
def serviceInvoker = context.getServiceInvoker();
|
2 |
def response1 = serviceInvoker.invokeSoapService("webservice1", payload).getSoapBody();
|
3 |
def response2 = serviceInvoker.invokeSoapService("webservice2", payload).getSoapBody();
|
4 |
String tagStorageLimitDays = response1.getElementsByTagNameNS("*", "tagStorageLimitDays").item(0)?.getTextContent()?: 0;
|
5 |
String status = response2.getElementsByTagNameNS("*", "status").item(0)?.getTextContent()?: "failure";
|
このコードは、行3が行4の前にwebservice2をコールするため、webservice1からのレスポンスを処理する機会があるため失敗します。 これは、webservice1からのレスポンスが使用できなくなったために発生します。
この問題を回避するには、最初のコールからのレスポンスを処理してから、2番目のコールを実行します。
かわりに、extractContentAsDocumentメソッドを追加して、最初のコールからのレスポンスの抽出が拡張で終了するようにできます。 たとえば:
明細 | コード |
---|---|
1 |
def serviceInvoker = context.getServiceInvoker();
|
2 |
def response1 = serviceInvoker.invokeSoapService("webservice1", payload).getSoapBody().extractContentAsDocument();
|
3 |
def response2 = serviceInvoker.invokeSoapService("webservice2", payload).getSoapBody();
|
4 |
String tagStorageLimitDays = response1.getElementsByTagNameNS("*", "tagStorageLimitDays").item(0)?.getTextContent()?: 0;
|
5 |
String status = response2.getElementsByTagNameNS("*", "status").item(0)?.getTextContent()?: "failure";
|
2行目は、SOAPBodyオブジェクトのextractContentAsDocumentメソッドをコールして、webservice2をコールする前に、webservice1からのレスポンスの抽出が終了していることを確認します。
メソッドの使用およびコネクタの作成
ノート
-
拡張機能のinvokeSoapServiceメソッドを使用して、webサービスをコールします。
Oracle Application webサービスまたはOracle Applicationsの外部にあるその他のサービスをコールできます。 コールできるのはSOAPサービスのみです。 REST APIをコールできません。 詳細と例については、「Oracle Supply Chain Management CloudのREST API」に移動し、Order Managementを展開して、「オーダー・ハブの販売オーダー」をクリックします。
-
コネクタを設定します。
ノート: 拡張で参照するwebサービスのコネクタを設定するには、「コネクタ詳細の管理」ページを使用する必要があります。これらの値を設定します。
属性
値
コネクタ名
拡張子で使用する名前とまったく同じ名前を使用します。 たとえば:
invokeSoapService("FundsCapturePaymentMethod")
この例では、コネクタ名を
FundsCapturePaymentMethod
に設定します。コネクタURL
オーダー管理の外部にあるシステムにデプロイするwebサービス・アドレスを特定するURLを入力します。
ユーザー名
webサービスへのサインインに使用するユーザー名を入力します。
パスワード
webサービスへのサインインに使用するパスワードを入力します。
起動モード
同期サービスを使用する必要があります。
詳細は、「オーダー管理と履行システム間のコネクタ詳細の管理」を参照してください。
ペイロードの作成
ノート
-
ペイロードを作成します。 この例では、
String payLoad
を使用して、ペイロードを文字列としてhard code
します。 ペイロードでの変数の定義など、他の手法を使用して要件を満たすこともできます。 -
invokeSoapServiceメソッドのパラメータでペイロード定義を参照します。 この例では、文字列
payLoad
を参照します。 -
getSoapBodyメソッドを使用して、webサービスがリクエストに応答して送信するレスポンスを処理します。 拡張はレスポンスを受信し、解析してから、レスポンスから必要な詳細を抽出できます。
-
メイン・コンテンツのみが含まれるようにペイロードを作成します。 エンベロープまたは本文の詳細を含めないでください。invokeSoapServiceには、メイン・コンテンツのみが必要です。 エンベロープと本文の詳細が追加されます。
Webサービス・レスポンスからの詳細の抽出
webサービス・レスポンスのレスポンス・オブジェクトに対するgetSoapBody()コールは、SOAP本文(Simple Object Access Protocol)のJavaクラスのインスタンスです。 詳細は、「インタフェースSOAPBody」を参照してください。 これらのインタフェースで使用可能なメソッドを使用して、webサービス・レスポンスから詳細を抽出します。
次のオーダー管理拡張の例では、これらのインタフェースのメソッドを使用して、レスポンスからデータを抽出します。
import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
def poNumber = header.getAttribute("CustomerPONumber");
if( poNumber != "CreditCheck" ) return;
// get attribute to populate in the payload
String customer = header.getAttribute("BillToCustomerName");
Long accountId = header.getAttribute("BillToCustomerIdentifier");
BigDecimal amount = new BigDecimal(1000);
// prepare the payload
String payLoad = "<ns1:creditChecking xmlns:ns1=\"http://xmlns.oracle.com/apps/financials/receivables/creditManagement/creditChecking/creditCheckingService/types/\">" +
"<ns1:request xmlns:ns2=\"http://xmlns.oracle.com/apps/financials/receivables/creditManagement/creditChecking/creditCheckingService/\">" +
"<ns2:CustomerName>" + customer + "</ns2:CustomerName>" +
"<ns2:CustomerAccountNumber>" + accountId + "</ns2:CustomerAccountNumber>" +
"<ns2:RequestType>Authorization</ns2:RequestType>" +
"<ns2:PriceType>ONE_TIME</ns2:PriceType>" +
"<ns2:RecurrencePeriod></ns2:RecurrencePeriod>" +
"<ns2:RequestAuthorizationAmount currencyCode=\"USD\">" + amount + "</ns2:RequestAuthorizationAmount>" +
"<ns2:RequestAuthorizationCurrency>USD</ns2:RequestAuthorizationCurrency>" +
"<ns2:ExistingAuthorizationNumber></ns2:ExistingAuthorizationNumber>" +
"<ns2:Requestor>ar_super_user</ns2:Requestor>" +
"</ns1:request>" +
"</ns1:creditChecking>";
// Use the CreditCheckService web service connector to the Check Check service. You use the Manage External Interface Web Service Details task to set up the connector. Since this is a service that is secured
// using message protection policy, we have registered the the https URL of the service
def response = context.invokeSoapService("CreditCheckService", payLoad);
// print a debug message. This appends the entire response to the shipping instuctions attribute.
// To avoid performance problems, you must comment out all debug statements in your production environment.
debug(response.getSoapBody().getTextContent());
// The response XML sent by the Credit Check service contains an element named 'Response'. A YES value indicates that credit check passed. Let us extract the contents of Response tag. The following XML API will return all nodes (tags)
// with name 'Response' in a NodeList element. We are expecting only one such element in our XML response
def nodeList = response.getSoapBody().getElementsByTagNameNS("*", "Response");
// print out the lenght of the node list
debug(nodeList.getLength());
// Get the first element with name 'Response' (we are expecting only one), and gets its text content
String ccResponse = nodeList.item(0).getTextContent();
debug(ccResponse);
// Check if credit check passed
if( ccResponse != 'YES' ) {
// Credit check failed. Raise a warning validation exception here
throw new ValidationException( new Message(Message.MessageType.WARNING, "Credit check failed.") );
}
else {
// Credit check passed
// Write the credit check response in an EFF attribute.
def psiContext = header.getOrCreateContextRow("ComplianceDetails");
psiContext.setAttribute("_ComplianceInfo", ccResponse);
}
/**
* Appends passed in msg to the Shipping Instructions attribute. This method has been implemented only for debugging purposes.
*/
void debug(def msg) {
String si = header.getAttribute("ShippingInstructions");
header.setAttribute("ShippingInstructions", si + ", " + msg.toString());
}
Webサービスまたはパブリック・ビュー・オブジェクトを使用する場合のペイロードの検査
webサービスからのレスポンス、またはパブリック・ビュー・オブジェクトのビュー基準からのレスポンスを調べるのは難しい場合があります。 開発時にsetAttributeメソッドを使用して、コードが参照する属性の値を取得し、それらをオーダー管理作業領域に表示してから、これらの値を調べ、コードが予期した値を返していることを確認します。
たとえば、内線番号が出荷指示を参照しているとします。 このコードを使用すると、webサービスからのレスポンスにShippingInstructionsの内容を記述できます。
header.setAttribute("ShippingInstructions", response.getSoapBody().getTextContext());
パブリック・ビュー・オブジェクトからレスポンスに同じデータを書き込むことができます。
本番にデプロイする前に、テスト・コードをログ・ファイルに変換するか、コメント(//)してください。
同様の結果を得るためにメッセージを作成することもできます。 ただし、メッセージは処理を停止または一時停止します。 ペイロードを使用すると、処理を中断せずに続行できるため、オーダー明細の出荷指示属性など、オーダー管理作業領域での属性値の表示方法のコンテキストで属性値を表示できます。