ストアド プロシージャを使用して Oracle データベースを定期的にポーリングすることで、定期的なデータ変更メッセージを受信するように Oracle E-Business アダプターを構成できます。 Oracle データベースをポーリングするためにアダプターが定期的に実行するポーリング ステートメントとしてストアド プロシージャを指定できます。
ポーリングを有効にするには、このトピックの説明に従って特定のバインド プロパティを指定する必要があります。 アダプターがポーリングをサポートする方法の詳細については、「 ポーリングを使用した受信呼び出しのサポート」を参照してください。
Oracle E-Business Adapter のバインド プロパティを使用したポーリング操作の構成
次の表は、データ変更メッセージを受信するようにアダプターを構成するために使用する Oracle E-Business アダプター バインド プロパティをまとめたものです。 ポーリング アプリケーションの実行中に、これらのバインド プロパティを指定する必要があります。
バインディングプロパティ | 説明 |
---|---|
InboundOperationType | ポーリングまたは通知の受信操作を実行するかどうかを指定します。 既定値は ポーリングです。 |
ポーリングデータの利用可能声明 | ポーリングに使用できるデータがあるかどうかを判断するためにアダプターが実行する SQL ステートメントを指定します。 レコードが使用可能な場合にのみ、 PollingInput バインディング プロパティに指定したストアド プロシージャが実行されます。 |
PollingInterval | Oracle E-Business アダプターが PolledDataAvailableStatement バインディング プロパティに指定されたステートメントを実行する間隔を秒単位で指定します。 既定値は 30 秒です。 ポーリング間隔は、連続するポーリング間の時間間隔を決定します。 ステートメントが指定された期間内に実行された場合、アダプターはその間隔の残りの時間スリープ状態になります。 |
PollingInput | ポーリング ステートメントを指定します。 ストアド プロシージャを使用してポーリングするには、このバインド プロパティの要求メッセージ全体を指定する必要があります。 要求メッセージは、ストアド プロシージャを送信操作として呼び出すためにアダプターに送信するメッセージと同じである必要があります。 既定値は null です。 ポーリングを有効にするには、 PollingInput バインド プロパティの値を指定する必要があります。 ポーリング ステートメントは、 PolledDataAvailableStatement バインディング プロパティによって決定されるポーリングに使用できるデータがある場合にのみ実行されます。 |
PollingAction | ポーリング操作のアクションを指定します。 操作用に生成されたサービス インターフェイスからポーリングアクションを決定するには、「アダプター サービス参照の追加」Visual Studioプラグインを使用します。 |
投票後声明 | PollingInput バインディング プロパティで指定されたステートメントが実行された後に実行されるステートメント ブロックを指定します。 |
PollWhileDataFound | ポーリング対象のテーブルでデータが使用可能な場合に、Oracle E-Business アダプターがポーリング間隔を無視し、ポーリング ステートメントを継続的に実行するかどうかを指定します。 テーブルにデータが存在しない場合、アダプターは、指定されたポーリング間隔でポーリング ステートメントを実行するように戻ります。 既定値は false です。 |
これらのプロパティの詳細については、「 BizTalk Adapter for Oracle E-Business Suite バインディング プロパティの読み取り」を参照してください。 Oracle E-Business アダプターを使用してポーリングする方法の詳細については、次のセクションを参照してください。
このトピックがポーリングを説明する方法
このトピックでは、Oracle E-Business アダプターがストアド プロシージャを使用したデータ変更メッセージの受信をサポートする方法を示すために、GET_ACTIVITYS ストアド プロシージャを使用して Oracle データベースの ACCOUNTACTIVITY テーブルをポーリングします。 このストアド プロシージャは、ACCOUNT_PKG パッケージで使用できます。 サンプルに付属の SQL スクリプトを実行して、これらのオブジェクトをデータベースに作成できます。
注
このトピックの例では、ACCOUNTACTIVITY テーブルをポーリングします。これは、サンプルで提供されるスクリプトを実行して作成されたベース データベース テーブルです。 インターフェイス テーブルを含む他のテーブルをポーリングするには、このトピックの説明と同様の手順を実行する必要があります。
ポーリング操作を示すために、次の操作を行います。
PolledDataAvailableStatement バインディング プロパティの SELECT ステートメントを指定して、ポーリング対象のテーブル (ACCOUNTACTIVITY) にデータが含まれている場所を決定します。 この例では、このバインド プロパティを次のように設定できます。
SELECT COUNT (*) FROM ACCOUNTACTIVITY
これにより、ACCOUNTACTIVITY テーブルに一部のレコードがある場合にのみ、アダプターでポーリング ステートメントが実行されます。
PollingInput バインディング プロパティの一部として要求メッセージを指定して、GET_ACTIVITYSストアド プロシージャを実行します。 このストアド プロシージャは ACCOUNTACTIVITY テーブル内のすべての行を取得し、アダプターから応答メッセージを取得します。
PostPollStatement バインディング プロパティの一部として PL/SQL ブロックを実行します。 このステートメントは、ACCOUNTACTIVITY テーブルからデータベース内の別のテーブルにすべてのデータを移動します。 この処理が行われると、次に PollingInput が実行されるときにデータはフェッチされないため、GET_ACTIVITYS ストアド プロシージャは空の応答メッセージを返します。
ACCOUNTACTIVITY テーブルに追加されたデータが増えるまで、空の応答メッセージが表示され続けます。そのため、ACCOUNTACTIVITY テーブルに新しいレコードを再入力する必要があります。 これを行うには、サンプルで提供されているmore_activity_data.sql スクリプトを実行します。 このスクリプトを実行すると、次のポーリング操作によって、テーブルに挿入された新しいレコードが取得されます。
WCF サービス モデルでのポーリングの構成
WCF サービス モデルを使用して Oracle E-Business アダプターでストアド プロシージャを使用してポーリングするには、次の操作を行う必要があります。
ポーリングに使用するストアド プロシージャのために、WCF サービス コントラクト (インターフェイス) を生成します。 この例では、GET_ACTIVITYS ストアド プロシージャの WCF サービス コントラクトを受信 操作として生成する必要があります。 これを行うには、アダプター サービス参照の追加プラグインを使用できます。
このインターフェイスから WCF サービスを実装します。
サービス ホスト (System.ServiceModel.ServiceHost) を使用して、この WCF サービスをホストします。
このトピックで使用する例について
このトピックの例では、GET_ACTIVITYS ストアド プロシージャを使用して ACCOUNTACTIVITY データベース テーブルをポーリングします。 テーブルとストアド プロシージャを生成するスクリプトがサンプルと共に提供されます。 サンプルの詳細については、 Oracle EBS アダプターのサンプルを参照してください。 このトピックに基づく サンプル StoredProcPolling_ServiceModelは、Oracle E-Business アダプターのサンプルでも提供されています。
WCF サービス コントラクトとクラス
アダプター サービス参照の追加プラグインを使用して、WCF サービス コントラクト (インターフェイス) と GET_ACTIVITYS 受信操作のサポート クラスを作成できます。 WCF サービス コントラクトの生成の詳細については、「 Oracle E-Business Suite ソリューション成果物の WCF クライアントまたは WCF サービス コントラクトを生成する」を参照してください。
WCF サービス コントラクト (インターフェイス)
次のコードは、 GET_ACTIVITYS 受信操作用に生成された WCF サービス コントラクト (インターフェイス) を示しています。
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://schemas.microsoft.com/OracleEBS/", ConfigurationName="PollingPackageApis_APPS_ACCOUNT_PKG")]
public interface PollingPackageApis_APPS_ACCOUNT_PKG {
// CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/OracleEBS/2008/05/PollingPackageApis/APPS/ACCOUNT_PKG) of message GET_ACTIVITYS
// does not match the default value (https://schemas.microsoft.com/OracleEBS/)
[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="PollingPackageApis/APPS/ACCOUNT_PKG/GET_ACTIVITYS")]
void GET_ACTIVITYS(GET_ACTIVITYS request);
}
メッセージ コントラクト
以下にGET_ACTIVITYS受信操作のメッセージコントラクトを示します。
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="GET_ACTIVITYS", WrapperNamespace="http://schemas.microsoft.com/OracleEBS/2008/05/PollingPackageApis/APPS/ACCOUNT_PK" +
"G", IsWrapped=true)]
public partial class GET_ACTIVITYS {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/OracleEBS/2008/05/PollingPackageApis/APPS/ACCOUNT_PK" +
"G", Order=0)]
public schemas.microsoft.com.OracleEBS._2008._05.RecordTypes.APPS.ACCOUNT_PKG.GET_ACTIVITYS.OUTRECSRecord[] OUTRECS;
public GET_ACTIVITYS() {
}
public GET_ACTIVITYS(schemas.microsoft.com.OracleEBS._2008._05.RecordTypes.APPS.ACCOUNT_PKG.GET_ACTIVITYS.OUTRECSRecord[] OUTRECS) {
this.OUTRECS = OUTRECS;
}
}
WCF サービス クラス
アダプター サービス参照の追加プラグインは、サービス コントラクト (インターフェイス) から実装された WCF サービス クラスのスタブを持つファイルも生成します。 ファイルの名前はOracleEBSBindingService.cs。 GET_ACTIVITYS操作をこのクラスに直接処理するロジックを挿入できます。 次のコードは、アダプター サービス参照プラグインの追加によって生成される WCF サービス クラスを示しています。
namespace OracleEBSBindingNamespace {
public class OracleEBSBindingService : PollingPackageApis_APPS_ACCOUNT_PKG {
// CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/OracleEBS/2008/05/PollingPackageApis/APPS/ACCOUNT_PKG) of message GET_ACTIVITYS
// does not match the default value (https://schemas.microsoft.com/OracleEBS/)
public virtual void GET_ACTIVITYS(GET_ACTIVITYS request) {
throw new System.NotImplementedException("The method or operation is not implemented.");
}
}
}
ポーリング用の受信メッセージをストアド プロシージャで処理する
このセクションでは、Oracle E-Business アダプターを使用して受信ポーリング メッセージを受信する .NET アプリケーションを記述する方法について説明します。
ストアド プロシージャを使用してポーリング メッセージを受信するには
アダプター サービス参照の追加プラグインを使用して、GET_ACTIVITYS 受信操作のWCFサービスコントラクト (インターフェイス) とヘルパークラスを生成します。 詳細については、「 Oracle E-Business Suite ソリューション成果物の WCF クライアントまたは WCF サービス コントラクトを生成する」を参照してください。 必要に応じて、サービス コントラクトとヘルパー クラスの生成中にバインディング プロパティを指定できます。 これにより、生成された構成ファイルに正しく設定されます。
手順 1 で生成されたインターフェイスとヘルパー クラスから WCF サービスを実装します。 このクラスの GET_ACTIVITYS メソッドは、 GET_ACTIVITYS操作から 受信したデータの処理でエラーが発生した場合に、ポーリング トランザクションを中止する例外をスローできます。それ以外の場合、メソッドは何も返しません。 WCF サービス クラスの属性を次に示す必要があります。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
GET_ACTIVITYS メソッド内では、アプリケーション ロジックを直接実装できます。 このクラスは、OracleEBSBindingService.csにあります。 この例のこのコードは、 OracleEBSBindingService クラスを サブクラス化します。 このコードでは、ポーリング メッセージが受信され、コンソールに書き込まれます。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class PollingService : OracleEBSBindingNamespace.OracleEBSBindingService { public override void GET_ACTIVITYS(GET_ACTIVITYS request) { Console.WriteLine("\nNew Polling Records Received"); Console.WriteLine("*************************************************"); Console.WriteLine("Tx Id\tAccount\tAmount\tProcessed"); for (int i = 0; i < request.OUTRECS.Length; i++) { Console.WriteLine("{0}\t{1}\t{2}\t{3}", request.OUTRECS[i].TID, request.OUTRECS[i].ACCOUNT, request.OUTRECS[i].AMOUNT, request.OUTRECS[i].PROCESSED); } Console.WriteLine("*************************************************"); Console.WriteLine("\nHit <RETURN> to stop polling"); } }
URI の一部として資格情報を渡さないようにするには、次のクラスを実装する必要があります。 アプリケーションの後半では、このクラスをインスタンス化して資格情報を渡します。
class PollingCredentials : ClientCredentials, IServiceBehavior { public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { bindingParameters.Add(this); } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } protected override ClientCredentials CloneCore() { ClientCredentials clone = new PollingCredentials(); clone.UserName.UserName = this.UserName.UserName; clone.UserName.Password = this.UserName.Password; return clone; } }
OracleEBSBinding を作成し、バインド プロパティを指定してポーリング操作を構成します。 これは、コードで明示的に行うか、構成で宣言によって行うことができます。 少なくとも、 InboundOperationType、 PolledDataAvailableStatement、 PollingInput、および PollingAction バインディング プロパティを指定する必要があります。
OracleEBSBinding binding = new OracleEBSBinding(); binding.InboundOperationType = InboundOperation.Polling; binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM ACCOUNTACTIVITY"; binding.PollingInput = "<GET_ACTIVITYS xmlns='http://schemas.microsoft.com/OracleEBS/2008/05/PackageApis/APPS/ACCOUNT_PKG'><INRECS>OPEN ? FOR SELECT * FROM ACCOUNTACTIVITY</INRECS></GET_ACTIVITYS>"; binding.PollingAction = "PollingPackageApis/APPS/ACCOUNT_PKG/GET_ACTIVITYS"; binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";
注
PollingInput バインド プロパティの値には、GET_ACTIVITYS ストアド プロシージャを送信操作として呼び出すための要求メッセージが含まれていることに注意してください。
Von Bedeutung
この例では、データベース テーブルをポーリングするため、アプリケーション コンテキストを設定する必要はありません。 ただし、インターフェイス テーブルをポーリングする場合は、 OracleUserName、 OraclePassword、 OracleEBSResponsibilityName のバインド プロパティを指定して、アプリケーション コンテキストを設定する必要があります。 アプリケーション コンテキストの詳細については、「アプリケーション コンテキストの 設定」を参照してください。
手順 3 で作成 した PollingCredentials クラスをインスタンス化して、Oracle E-Business Suite の資格情報を指定します。
PollingCredentials credentials = new PollingCredentials(); credentials.UserName.UserName = "<Enter user name here>"; credentials.UserName.Password = "<Enter password here>";
手順 2 で作成した WCF サービスのインスタンスを作成します。
// create service instance PollingService service = new PollingService();
WCF サービスとベース接続 URI を使用して 、System.ServiceModel.ServiceHost のインスタンスを作成します。 基本接続 URI に受信 ID を含めることはできません (指定されている場合)。 ここでも資格情報を渡す必要があります。
// Enable service host Uri[] baseUri = new Uri[] { new Uri("oracleebs://ebs_instance_name") }; ServiceHost serviceHost = new ServiceHost(service, baseUri); serviceHost.Description.Behaviors.Add(credentials);
サービス ホストにサービス エンドポイントを追加します。 これを行うには:
手順 4 で作成したバインディングを使用します。
資格情報を含む接続 URI と、必要に応じて受信 ID を指定します。
コントラクトを "PollingPackageApis_APPS_ACCOUNT_PKG" として指定して、MS_SAMPLE_EMPLOYEE インターフェイス テーブルをポーリングします。
// Add service endpoint: be sure to specify PollingPackageApis_APPS_ACCOUNT_PKG as the contract Uri ConnectionUri = new Uri("oracleebs://ebs_instance_name"); serviceHost.AddServiceEndpoint("PollingPackageApis_APPS_ACCOUNT_PKG", binding, ConnectionUri);
ポーリング データを受信するには、サービス ホストを開きます。 アダプターは、クエリが結果セットを返すたびにデータを返します。
// Open the service host to begin polling serviceHost.Open();
ポーリングを終了するには、サービス ホストを閉じます。
Von Bedeutung
アダプターは、サービス ホストが閉じられるまでポーリングを続行します。
serviceHost.Close();
例
次の例は、GET_ACTIVITYS ストアド プロシージャを使用して ACCOUNTACTIVITY データベース テーブルをポーリングするポーリング アプリケーションを示しています。 PollingInput バインディング プロパティには、ACCOUNTACTIVITY テーブルからすべてのデータを読み取るGET_ACTIVITYS ストアド プロシージャを呼び出す要求メッセージが含まれており、ポーリング後のステートメントは ACCOUNTACTIVITY から ACTIVITYHISTORY テーブルにすべてのデータを移動します。
最初のポーリング メッセージは、ACCOUNTACTIVITY テーブルのすべてのレコードを示します。 後続のポーリング メッセージにはレコードは含まれません。これは、post poll ステートメントによってレコードが削除されるためです。 ACCOUNTACTIVITY テーブルにさらにデータが追加されるまで、ポーリング メッセージは取得されないため、ACCOUNTACTIVITY テーブルに新しいレコードを再入力する必要があります。 これを行うには、サンプルで提供されているmore_activity_data.sql スクリプトを実行します。
このスクリプトを実行すると、次のポーリング操作によって、テーブルに挿入された新しいレコードが取得されます。 アダプターは、 <RETURN>
を押してサービス ホストを閉じるまでポーリングを続行します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Adapters.OracleEBS;
using Microsoft.ServiceModel.Channels;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Collections.ObjectModel;
namespace StoredProcPolling_ServiceModel
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class PollingService : OracleEBSBindingNamespace.OracleEBSBindingService
{
public override void GET_ACTIVITYS(GET_ACTIVITYS request)
{
Console.WriteLine("\nNew Polling Records Received");
Console.WriteLine("*************************************************");
Console.WriteLine("Tx Id\tAccount\tAmount\tProcessed");
for (int i = 0; i < request.OUTRECS.Length; i++)
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}",
request.OUTRECS[i].TID,
request.OUTRECS[i].ACCOUNT,
request.OUTRECS[i].AMOUNT,
request.OUTRECS[i].PROCESSED);
}
Console.WriteLine("*************************************************");
Console.WriteLine("\nHit <RETURN> to stop polling");
}
}
class PollingCredentials : ClientCredentials, IServiceBehavior
{
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
bindingParameters.Add(this);
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{ }
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{ }
protected override ClientCredentials CloneCore()
{
ClientCredentials clone = new PollingCredentials();
clone.UserName.UserName = this.UserName.UserName;
clone.UserName.Password = this.UserName.Password;
return clone;
}
}
class Program
{
static void Main(string[] args)
{
ServiceHost serviceHost = null;
try
{
Console.WriteLine("Sample started...");
Console.WriteLine("Press any key to start polling...");
Console.ReadLine();
OracleEBSBinding binding = new OracleEBSBinding();
binding.InboundOperationType = InboundOperation.Polling;
binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM ACCOUNTACTIVITY";
binding.PollingInput = "<GET_ACTIVITYS xmlns='http://schemas.microsoft.com/OracleEBS/2008/05/PackageApis/APPS/ACCOUNT_PKG'><INRECS>OPEN ? FOR SELECT * FROM ACCOUNTACTIVITY</INRECS></GET_ACTIVITYS>";
binding.PollingAction = "PollingPackageApis/APPS/ACCOUNT_PKG/GET_ACTIVITYS";
binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";
// This URI is used to specify the address for the ServiceEndpoint
// It must contain the InboundId that was used to generate
// the WCF service callback interface
Uri ConnectionUri = new Uri("oracleebs://ebs_instance_name");
// This URI is used to initialize the ServiceHost. It cannot contain
// an InboundID; otherwise,an exception is thrown when
// the ServiceHost is initialized.
Uri[] baseUri = new Uri[] { new Uri("oracleebs://ebs_instance_name") };
PollingCredentials credentials = new PollingCredentials();
credentials.UserName.UserName = "<Enter user name here>";
credentials.UserName.Password = "<Enter password here>";
Console.WriteLine("Opening service host...");
PollingService service = new PollingService();
serviceHost = new ServiceHost(service, baseUri);
serviceHost.Description.Behaviors.Add(credentials);
serviceHost.AddServiceEndpoint("PollingPackageApis_APPS_ACCOUNT_PKG", binding, ConnectionUri);
serviceHost.Open();
Console.WriteLine("Service host opened...");
Console.WriteLine("Polling started...");
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("Exception :" + e.Message);
Console.ReadLine();
/* If there is an error it will be specified in the inner exception */
if (e.InnerException != null)
{
Console.WriteLine("InnerException: " + e.InnerException.Message);
Console.ReadLine();
}
}
finally
{
// IMPORTANT: you must close the ServiceHost to stop polling
if (serviceHost.State == CommunicationState.Opened)
serviceHost.Close();
else
serviceHost.Abort();
}
}
}
}