共用方式為


使用 WCF 服務模型接收 Oracle E-Business Suite 資料庫變更通知

本主題示範如何設定 Oracle E-Business 配接器,以接收來自 Oracle 資料庫的查詢通知訊息。 若要示範通知,請考慮具有 「Processed」 資料行的資料表 ACCOUNTACTIVITY。 當新記錄插入此資料表時,Status 資料行的值會設定為 「n」。 您可以使用 SQL 語句來擷取具有 「Processed」 資料行的所有記錄,以設定配接器以接收通知。 您可以指定 NotificationStatement 系結屬性的 SQL 語句來執行此動作。 配接器用戶端收到通知之後,它可以包含邏輯,以在 Oracle 資料庫上執行任何後續工作。 在此範例中,為了簡單起見,配接器用戶端會將資料表中的所有記錄列出為 「n」。

使用 Oracle E-Business 配接器系結屬性設定通知

下表摘要說明您用來設定從 Oracle E-Business Suite 接收通知的 Oracle E-Business 配接器系結屬性。 在執行 .NET 應用程式以接收通知時,您必須指定這些系結屬性。

Binding 屬性 Description
InboundOperationType 指定您想要執行的輸入作業。 若要接收通知訊息,請將此設定為 [通知]。
NotificationPort 指定 ODP.NET 必須開啟的埠號碼,以接聽 Oracle 資料庫中的資料庫變更通知。
NotificationStatement 指定用來註冊查詢通知的 Select 語句。 只有在指定 Select 語句的結果集變更時,配接器才會取得通知訊息。
NotifyOnListenerStart 指定當接聽程式啟動時,配接器是否會將通知傳送給配接器用戶端。

如需這些屬性的更完整描述,請參閱 閱讀 BizTalk Adapter for Oracle E-Business Suite 系結屬性。 如需如何使用 Oracle E-Business 配接器從 Oracle E-Business Suite 接收通知的完整描述,請閱讀本主題的其餘部分。

使用 WCF 服務模型設定通知

若要使用 WCF 服務模型接收通知,您必須:

  • 從配接器所公開的中繼資料產生 WCF 服務合約 (介面) 。 若要這樣做,您可以使用 [新增配接器服務參考外掛程式]。

  • 在 ACCOUNTACTIVITY 資料表上產生 Select 作業的 WCF 用戶端。 若要這樣做,您可以使用 [新增配接器服務參考外掛程式]。

  • 從這個介面實作 WCF 服務。

  • 使用服務主機裝載此 WCF 服務, (System.ServiceModel.ServiceHost) 。

關於本主題中使用的範例

本主題中的範例會收到 ACCOUNTACTIVITY 資料表的通知。 產生資料表的腳本會提供範例。 如需範例的詳細資訊,請參閱 Oracle EBS 配接器的範例。 本主題所依據的範例 Notification_ServiceModel也隨附 Oracle E-Business 配接器範例。

WCF 服務合約和類別

您可以使用 [新增配接器服務參考外掛程式] 來建立 WCF 服務合約 (介面) 和支援 通知 作業的類別。 如需產生 WCF 服務合約的詳細資訊,請參閱 產生 WCF 用戶端或 Oracle E-Business Suite 解決方案成品的 WCF 服務合約

WCF 服務合約 (介面)

下列程式碼顯示針對 通知 作業產生的 WCF 服務合約 (介面) 。

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://schemas.microsoft.com/OracleEBS/", ConfigurationName="Notification_")]
public interface Notification_ {

    // CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/OracleEBS/2008/05/Notification/) of message Notification
    // does not match the default value (https://schemas.microsoft.com/OracleEBS/)
    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="Notification")]
    void Notification(Notification request);
}

訊息合約

以下是通知作業的訊息合約。

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="Notification", WrapperNamespace="http://schemas.microsoft.com/OracleEBS/2008/05/Notification/", IsWrapped=true)]
public partial class Notification {

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/OracleEBS/2008/05/Notification/", Order=0)]
    public schemas.microsoft.com.OracleEBS._2008._05.Notification.NotificationDetails[] Details;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/OracleEBS/2008/05/Notification/", Order=1)]
    public string Info;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/OracleEBS/2008/05/Notification/", Order=2)]
    public string[] ResourceNames;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/OracleEBS/2008/05/Notification/", Order=3)]
    public string Source;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/OracleEBS/2008/05/Notification/", Order=4)]
    public string Type;

    public Notification() {
    }

    public Notification(schemas.microsoft.com.OracleEBS._2008._05.Notification.NotificationDetails[] Details, string Info, string[] ResourceNames, string Source, string Type) {
        this.Details = Details;
        this.Info = Info;
        this.ResourceNames = ResourceNames;
        this.Source = Source;
        this.Type = Type;
    }
}

WCF 服務類別

[新增配接器服務參考外掛程式] 也會產生檔案,該檔案會從服務合約 (介面) 實作 WCF 服務類別的存根。 檔案名為 OracleEBSBindingService.cs。 您可以將邏輯直接插入此類別來處理 通知 作業。 下列程式碼顯示新增配接器服務參考外掛程式所產生的 WCF 服務類別。

namespace OracleEBSBindingNamespace {

    public class OracleEBSBindingService : Notification_ {

        // CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/OracleEBS/2008/05/Notification/) of message Notification
        // does not match the default value (https://schemas.microsoft.com/OracleEBS/)
        public virtual void Notification(Notification request) {
            throw new System.NotImplementedException("The method or operation is not implemented.");
        }
    }
}

使用 WCF 服務模型接收查詢通知

本節提供如何撰寫 .NET 應用程式以使用 Oracle E-Business 配接器接收查詢通知的指示。

接收查詢通知

  1. 使用 [新增配接器服務參考外掛程式],在ACCOUNTACTIVITY資料表上產生[選取] 作業的 WCF 用戶端。 您將使用此用戶端在收到通知訊息之後執行 Select 作業。 將新的類別 TableOperation.cs 新增至您的專案,並新增下列程式碼片段來執行 Select 作業。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Notification_ServiceModel
    {
        class TableOperation
        {
            public void TableOp()
            {
                //////////////////////////////////////////////////////////////////////
                // CREATING THE CLIENT AND SETTING CLIENT CREDENTIALS
                //////////////////////////////////////////////////////////////////////
    
                Tables_APPS_ACCOUNTACTIVITYClient client = new Tables_APPS_ACCOUNTACTIVITYClient();
                client.ClientCredentials.UserName.UserName = "<Enter user name here>";
                client.ClientCredentials.UserName.Password = "<Enter password here>";
    
                ////////////////////////////////////////////////////////////////////
                // OPENING THE CLIENT
                //////////////////////////////////////////////////////////////////////
                try
                {
                    Console.WriteLine("Opening the client ...");
                    client.Open();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception: " + ex.Message);
                    throw;
                }
    
                ////////////////////////////////////////////////////////////////////////////////////////
                // SELECTING THE LAST INSERTED VALUES
                ////////////////////////////////////////////////////////////////////////////////////////
                Console.WriteLine("The application will now select the last inserted record");
    
                schemas.microsoft.com.OracleEBS._2008._05.TableViewRecord.APPS.ACCOUNTACTIVITY.SelectRecord[] selectRecords;
    
                try
                {
                    selectRecords = client.Select("*", "WHERE PROCESSED = 'n'");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception: " + ex.Message);
                    throw;
                }
    
                Console.WriteLine("The details of the newly added records are:");
                Console.WriteLine("********************************************");
                for (int i = 0; i < selectRecords.Length; i++)
                {
                    Console.WriteLine("Transaction ID   : " + selectRecords[i].TID);
                    Console.WriteLine("Account ID       : " + selectRecords[i].ACCOUNT);
                    Console.WriteLine("Processed Status : " + selectRecords[i].PROCESSED);
                    Console.WriteLine();
                }
                Console.WriteLine("********************************************");
            }
        }
    }
    
    
  2. 使用 [新增配接器服務參考外掛程式] 來產生 WCF 服務合約 (介面) 和 通知 作業的協助程式類別。

    如需詳細資訊,請參閱 產生 Oracle E-Business Suite 解決方案成品的 WCF 用戶端或 WCF 服務合約。 您可以在產生服務合約和協助程式類別時,選擇性地指定系結屬性。 這可確保它們已正確設定在產生的組態檔中。

  3. 從步驟 2 中產生的介面和協助程式類別實作 WCF 服務。 如果遇到錯誤處理從通知作業收到的資料,這個類別的Notification方法可能會擲回例外狀況來中止作業;否則,方法不會傳回任何專案。 您必須屬性 WCF 服務類別,如下所示:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    

    Notification 方法中,您可以直接實作應用程式邏輯。 您可以在 OracleEBSBindingService.cs 中找到這個類別。 此範例中的這個程式碼會子類別 OracleEBSBindingService 類別。 在此程式碼中,收到的通知訊息會寫入主控台。 此外,會叫用TableOperation類別內的TableOp方法來執行 Select 作業。

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    
    public class NotificationService : OracleEBSBindingNamespace.OracleEBSBindingService
    {
        public override void Notification(Notification request)
        {
            Console.WriteLine("\nNew Notification Received");
            Console.WriteLine("*************************************************");
            Console.WriteLine(request.Info);
            Console.WriteLine(request.Source);
            Console.WriteLine(request.Type);
            Console.WriteLine("*************************************************");
    
            TableOperation Ops = new TableOperation();
            Ops.TableOp();
    
        }
    }
    
  4. 您必須實作下列類別,才能傳遞 Oracle E-Business Suite 的認證。 在應用程式的後者部分中,您將具現化此類別來傳遞認證。

    class NotificationCredentials : 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 NotificationCredentials();
            clone.UserName.UserName = this.UserName.UserName;
            clone.UserName.Password = this.UserName.Password;
            return clone;
        }
    }
    
  5. 建立 OracleEBSBinding ,並藉由指定系結屬性來設定配接器以接收查詢通知。 您可以在程式碼中明確執行此動作,或在組態中以宣告方式執行此動作。 您至少必須指定 InboundOperationTypeNotificationStatement 系結屬性。

    OracleEBSBinding binding = new OracleEBSBinding();
    binding.InboundOperationType = InboundOperation.Notification;
    binding.NotificationStatement = "SELECT TID,ACCOUNT,PROCESSED FROM APPS.ACCOUNTACTIVITY WHERE PROCESSED = 'n'";
    binding.NotifyOnListenerStart = true;
    binding.NotificationPort = 10;
    

    重要

    NotificationPort系結屬性的值必須設定為您必須新增至 Windows 防火牆例外狀況清單的相同埠號碼。 如需如何將埠新增至 Windows 防火牆例外狀況清單的指示,請參閱 https://go.microsoft.com/fwlink/?LinkID=196959

    重要

    如果您未設定 NotificationPort 系結屬性,配接器會假設此系結屬性的預設值為 -1。 在這種情況下,您必須完全停用 Windows 防火牆,才能接收通知訊息。

  6. 藉由具現化您在步驟 4 中建立的 NotificationCredentials 類別來指定 Oracle E-Business Suite 認證。

    NotificationCredentials credentials = new NotificationCredentials();
    credentials.UserName.UserName = "<Enter user name here>";
    credentials.UserName.Password = "<Enter password here>";
    
  7. 建立在步驟 3 中建立之 WCF 服務的實例。

    // create service instance
    NotificationService service = new NotificationService();
    
  8. 使用 WCF 服務和基底連線 URI,建立 System.ServiceModel.ServiceHost 的實例。 您也必須在這裡指定認證。

    // Enable service host
    Uri[] baseUri = new Uri[] { new Uri("oracleebs://ebs_instance_name") };
    ServiceHost serviceHost = new ServiceHost(service, baseUri);
    serviceHost.Description.Behaviors.Add(credentials);
    
    
  9. 將服務端點新增至服務主機。 作法如下:

    • 使用在步驟 5 中建立的系結。

    • 指定包含認證的連線 URI,並視需要指定輸入識別碼。

    • 將合約指定為 「Notification_」。

      // Add service endpoint: be sure to specify Notification_ as the contract
      Uri ConnectionUri = new Uri("oracleebs://ebs_instance_name?");
      serviceHost.AddServiceEndpoint("Notification_", binding, ConnectionUri);
      
  10. 若要接收通知訊息,請開啟服務主機。

    // Open the service host to begin receiving notifications
    serviceHost.Open();
    
  11. 若要停止接收通知,請關閉服務主機。

    serviceHost.Close();
    

範例

下列範例顯示 .NET 應用程式,以接收 ACCOUNTACTIVITY 資料表的通知訊息。

注意

下列程式碼片段會具現化 TableOperation.cs 類別,並叫用 TableOp 方法。 類別和 方法會在步驟 1 中說明。

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 Notification_ServiceModel
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

    public class NotificationService : OracleEBSBindingNamespace.OracleEBSBindingService
    {
        public override void Notification(Notification request)
        {
            Console.WriteLine("\nNew Notification Received");
            Console.WriteLine("*************************************************");
            Console.WriteLine(request.Info);
            Console.WriteLine(request.Source);
            Console.WriteLine(request.Type);
            Console.WriteLine("*************************************************");

            TableOperation Ops = new TableOperation();
            Ops.TableOp();

        }
    }

    class NotificationCredentials : 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 NotificationCredentials();
            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 receiving notifications...");
                Console.ReadLine();

                OracleEBSBinding binding = new OracleEBSBinding();
                binding.InboundOperationType = InboundOperation.Notification;
                binding.NotificationStatement = "SELECT TID,ACCOUNT,PROCESSED FROM APPS.ACCOUNTACTIVITY WHERE PROCESSED = 'n'";
                binding.NotifyOnListenerStart = true;
                binding.NotificationPort = 10;

                // 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") };

                NotificationCredentials credentials = new NotificationCredentials();
                credentials.UserName.UserName = "<Enter user name here>";
                credentials.UserName.Password = "<Enter password here>";

                Console.WriteLine("Opening service host...");
                NotificationService service = new NotificationService();
                serviceHost = new ServiceHost(service, baseUri);
                serviceHost.Description.Behaviors.Add(credentials);
                serviceHost.AddServiceEndpoint("Notification_", binding, ConnectionUri);
                serviceHost.Open();
                Console.WriteLine("Service host opened...");
                Console.WriteLine("Waiting for notification...");

                Console.WriteLine("\nHit <RETURN> to stop receiving notification");
                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 應用程式