次の方法で共有


WCF サービス モデルでストアド プロシージャを使用して Oracle E-Business Suite をポーリングする

ストアド プロシージャを使用して Oracle データベースを定期的にポーリングすることで、定期的なデータ変更メッセージを受信するように Oracle E-Business アダプターを構成できます。 Oracle データベースをポーリングするためにアダプターが定期的に実行するポーリング ステートメントとしてストアド プロシージャを指定できます。

ポーリングを有効にするには、このトピックで説明するように特定のバインド プロパティを指定する必要があります。 アダプターがポーリングをサポートする方法の詳細については、「 ポーリングを使用した受信呼び出しのサポート」を参照してください。

Oracle E-Business Adapter のバインド プロパティを使用したポーリング操作の構成

次の表は、データ変更メッセージを受信するようにアダプターを構成するために使用する Oracle E-Business アダプター バインド プロパティをまとめたものです。 ポーリング アプリケーションの実行中に、これらのバインド プロパティを指定する必要があります。

Binding プロパティ 説明
InboundOperationType ポーリングまたは通知の受信操作を実行するかどうかを指定します。 既定値は ポーリングです。
PolledDataAvailableStatement ポーリングに使用できるデータがあるかどうかを判断するためにアダプターが実行する SQL ステートメントを指定します。 レコードが使用可能な場合にのみ、 PollingInput バインド プロパティに指定したストアド プロシージャが実行されます。
PollingInterval Oracle E-Business アダプターが PolledDataAvailableStatement バインディング プロパティに指定されたステートメントを実行する間隔を秒単位で指定します。 既定値は 30 秒です。 ポーリング間隔は、連続するポーリング間の時間間隔を決定します。 ステートメントが指定された期間内に実行された場合、アダプターはその間隔の残りの時間スリープ状態になります。
PollingInput ポーリング ステートメントを指定します。 ストアド プロシージャを使用してポーリングするには、このバインド プロパティの要求メッセージ全体を指定する必要があります。 要求メッセージは、ストアド プロシージャを送信操作として呼び出すためにアダプターに送信するメッセージと同じである必要があります。 既定値は null です。

ポーリングを有効にするには、 PollingInput バインド プロパティの値を指定する必要があります。 ポーリング ステートメントは、ポーリングに使用できるデータがある場合にのみ実行されます。これは、 PolledDataAvailableStatement バインディング プロパティによって決定されます。
PollingAction ポーリング操作のアクションを指定します。 操作用に生成されたサービス インターフェイスからポーリング アクションを決定するには、アダプター サービス参照の追加 Visual Studio プラグインを使用します。
PostPollStatement 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 スクリプトを実行して、これらのオブジェクトをデータベースに作成できます。

Note

このトピックの例では、サンプルで提供されるスクリプトを実行して作成されたベース データベース テーブルである 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 サービス コントラクトとクラス

アダプター サービス参照の追加プラグインを使用して、 GET_ACTIVITYS受信操作 の WCF サービス コントラクト (インターフェイス) とサポート クラスを作成できます。 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 アプリケーションを作成する方法について説明します。

ストアド プロシージャを使用してポーリング メッセージを受信するには

  1. アダプター サービス参照の追加プラグインを使用して、 GET_ACTIVITYS 受信操作の WCF サービス コントラクト (インターフェイス) とヘルパー クラスを生成します。 詳細については、「 Oracle E-Business Suite ソリューション成果物の WCF クライアントまたは WCF サービス コントラクトを生成する」を参照してください。 必要に応じて、サービス コントラクトとヘルパー クラスの生成中にバインド プロパティを指定できます。 これにより、生成された構成ファイルに正しく設定されます。

  2. 手順 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");
        }
    }
    
  3. 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;
        }
    }
    
  4. OracleEBSBinding を作成し、バインド プロパティを指定してポーリング操作を構成します。 これは、コードで明示的に行うか、構成で宣言によって行うことができます。 少なくとも、 InboundOperationTypePolledDataAvailableStatementPollingInput、および 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;";
    

    Note

    PollingInput バインド プロパティの値には、GET_ACTIVITYS ストアド プロシージャを送信操作として呼び出すための要求メッセージが含まれていることに注意してください。

    重要

    この例では、データベース テーブルをポーリングするため、アプリケーション コンテキストを設定する必要はありません。 ただし、インターフェイス テーブルをポーリングする場合は、 OracleUserNameOraclePasswordOracleEBSResponsibilityName バインディング プロパティを指定して、アプリケーション コンテキストを設定する必要があります。 アプリケーション コンテキストの詳細については、「アプリケーション コンテキストの設定」を参照してください。

  5. 手順 3 で作成 した PollingCredentials クラスをインスタンス化して、Oracle E-Business Suite の資格情報を指定します。

    PollingCredentials credentials = new PollingCredentials();
    credentials.UserName.UserName = "<Enter user name here>";
    credentials.UserName.Password = "<Enter password here>";
    
  6. 手順 2 で作成した WCF サービスのインスタンスを作成します。

    // create service instance
    PollingService service = new PollingService();
    
  7. 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);
    
    
  8. サービス エンドポイントをサービス ホストに追加します。 これを行うには、次の手順を実行します。

    • 手順 4 で作成したバインディングを使用します。

    • 資格情報と必要に応じて受信 ID を含む接続 URI を指定します。

    • コントラクトを "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);
    
  9. ポーリング データを受信するには、サービス ホストを開きます。 アダプターは、クエリが結果セットを返すたびにデータを返します。

    // Open the service host to begin polling
    serviceHost.Open();
    
  10. ポーリングを終了するには、サービス ホストを閉じます。

    重要

    アダプターは、サービス ホストが閉じられるまでポーリングを続行します。

    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();
            }
        }
    }
}

参照

WCF サービス モデルを使用して Oracle E-Business Suite をポーリングする