Compartir a través de


Recibir notificaciones de cambio de base de datos de Oracle E-Business Suite mediante el modelo de servicio WCF

En este tema se muestra cómo configurar el adaptador de Oracle E-Business para recibir mensajes de notificación de consulta de una base de datos de Oracle. Para demostrar las notificaciones, considere una tabla, ACCOUNTACTIVITY, con una columna "Procesada". Cuando se inserta un nuevo registro en esta tabla, el valor de la columna Estado se establece en "n". Puede configurar el adaptador para recibir notificaciones registrando notificaciones mediante una instrucción SQL que recupera todos los registros que tienen la columna "Procesado" como "n". Para ello, especifique la instrucción SQL para la propiedad de enlace NotificationStatement . Una vez que el cliente del adaptador recibe la notificación, puede contener la lógica para realizar cualquier tarea posterior en la base de datos de Oracle. En este ejemplo, por motivos de simplicidad, el cliente del adaptador muestra todos los registros de la tabla que tienen la columna "Procesado" como "n".

Configuración de notificaciones con las propiedades de enlace del adaptador de E-Business de Oracle

En la tabla siguiente se resumen las propiedades de enlace del adaptador de Oracle E-Business que se usan para configurar la recepción de notificaciones de Oracle E-Business Suite. Debe especificar estas propiedades de enlace mientras ejecuta la aplicación .NET para recibir notificaciones.

Binding (propiedad) Descripción
InboundOperationType Especifica la operación de entrada que desea realizar. Para recibir mensajes de notificación, establezca esta opción en Notificación.
NotificationPort Especifica el número de puerto que ODP.NET debe abrir para escuchar la notificación de cambio de base de datos de oracle.
NotificationStatement Especifica la instrucción Select usada para registrarse para las notificaciones de consulta. El adaptador recibe un mensaje de notificación solo cuando cambia el conjunto de resultados de la instrucción Select especificada.
NotifyOnListenerStart Especifica si el adaptador envía una notificación a los clientes del adaptador cuando se inicia el agente de escucha.

Para obtener una descripción más completa de estas propiedades, vea Leer sobre las propiedades de enlace del adaptador de BizTalk para Oracle E-Business Suite. Para obtener una descripción completa de cómo usar el adaptador de Oracle E-Business para recibir notificaciones de Oracle E-Business Suite, lea el resto de este tema.

Configuración de notificaciones mediante el modelo de servicio WCF

Para recibir las notificaciones mediante el modelo de servicio WCF, debe hacer lo siguiente:

  • Genere un contrato de servicio WCF (interfaz) para la operación de notificación a partir de los metadatos expuestos por el adaptador. Para ello, puede usar el complemento Agregar referencia del servicio adaptador.

  • Genere un cliente WCF para la operación Select en la tabla ACCOUNTACTIVITY. Para ello, puede usar el complemento Agregar referencia del servicio adaptador.

  • Implemente un servicio WCF desde esta interfaz.

  • Hospede este servicio WCF mediante un host de servicio (System.ServiceModel.ServiceHost).

Acerca de los ejemplos usados en este tema

Los ejemplos de este tema reciben una notificación para la tabla ACCOUNTACTIVITY. Se proporciona un script para generar la tabla con los ejemplos. Para obtener más información sobre los ejemplos, consulte Ejemplos para el adaptador de Oracle EBS. También se proporciona un ejemplo, Notification_ServiceModel, que se basa en este tema, con los ejemplos de adaptadores de Oracle E-Business.

Contrato y clase de servicio WCF

Puede usar el complemento Agregar referencia de servicio de adaptador para crear un contrato de servicio WCF (interfaz) y clases auxiliares para la operación de notificación . Para obtener más información sobre cómo generar un contrato de servicio WCF, consulte Generación de un cliente WCF o un contrato de servicio WCF para artefactos de soluciones de Oracle E-Business Suite.

El contrato de servicio WCF (interfaz)

En el código siguiente se muestra el contrato de servicio WCF (interfaz) generado para la operación de notificación .

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

Contratos de mensaje

A continuación se muestra el contrato de mensaje para la operación notificación.

[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;
    }
}

Clase de servicio WCF

El complemento Add Adapter Service Reference también genera un archivo que tiene un código auxiliar para la clase de servicio WCF implementada a partir del contrato de servicio (interfaz). El nombre del archivo es OracleEBSBindingService.cs. Puede insertar la lógica para procesar la operación notificación directamente en esta clase. En el código siguiente se muestra la clase de servicio WCF generada por el complemento Agregar referencia del servicio adaptador.

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

Recepción de notificaciones de consulta mediante el modelo de servicio WCF

En esta sección se proporcionan instrucciones sobre cómo escribir una aplicación .NET para recibir notificaciones de consulta mediante el adaptador de Oracle E-Business.

Para recibir notificaciones de consulta

  1. Use el complemento Agregar referencia de servicio de adaptador para generar un cliente WCF para la operación Select en la tabla ACCOUNTACTIVITY . Usará este cliente para realizar operaciones Select después de recibir un mensaje de notificación. Agregue una nueva clase, TableOperation.cs, al proyecto y agregue el siguiente fragmento de código para realizar una operación 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. Use el complemento Agregar referencia del servicio adaptador para generar un contrato de servicio WCF (interfaz) y clases auxiliares para la operación de notificación .

    Para más información, consulte Generación de un cliente WCF o un contrato de servicio WCF para artefactos de soluciones de Oracle E-Business Suite. Opcionalmente, puede especificar las propiedades de enlace al generar el contrato de servicio y las clases auxiliares. Esto garantiza que se establecen correctamente en el archivo de configuración generado.

  3. Implemente un servicio WCF desde la interfaz y las clases auxiliares generadas en el paso 2. El método Notification de esta clase puede producir una excepción para anular la operación, si se produce un error al procesar los datos recibidos de la operación notificación ; de lo contrario, el método no devuelve nada. Debe atribuir la clase de servicio WCF de la siguiente manera:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    

    Dentro del método Notification , puede implementar la lógica de la aplicación directamente. Esta clase se puede encontrar en OracleEBSBindingService.cs. Este código de este ejemplo subclase la clase OracleEBSBindingService . En este código, el mensaje de notificación recibido se escribe en la consola. Además, se invoca el método TableOp dentro de la clase TableOperation para realizar la operación 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. Debe implementar la siguiente clase para pasar las credenciales de Oracle E-Business Suite. En la última parte de la aplicación, creará una instancia de esta clase para pasar las credenciales.

    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. Cree un OracleEBSBinding y configure el adaptador para recibir notificaciones de consulta especificando las propiedades de enlace. Puede hacerlo explícitamente en el código o mediante declaración en la configuración. Como mínimo, debe especificar las propiedades de enlace InboundOperationType y NotificationStatement .

    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;
    

    Importante

    El valor de la propiedad de enlace NotificationPort debe establecerse en el mismo número de puerto que debe haber agregado a la lista de excepciones del Firewall de Windows. Para obtener instrucciones sobre cómo agregar puertos a la lista de excepciones del Firewall de Windows, consulte https://go.microsoft.com/fwlink/?LinkID=196959.

    Importante

    Si no establece la propiedad de enlace NotificationPort , el adaptador asume el valor predeterminado de -1 para esta propiedad de enlace. En tal caso, tendrás que deshabilitar completamente firewall de Windows para recibir mensajes de notificación.

  6. Especifique las credenciales de Oracle E-Business Suite creando instancias de la clase NotificationCredentials que creó en el paso 4.

    NotificationCredentials credentials = new NotificationCredentials();
    credentials.UserName.UserName = "<Enter user name here>";
    credentials.UserName.Password = "<Enter password here>";
    
  7. Cree una instancia del servicio WCF creado en el paso 3.

    // create service instance
    NotificationService service = new NotificationService();
    
  8. Cree una instancia de System.ServiceModel.ServiceHost mediante el servicio WCF y un URI de conexión base. También debe especificar las credenciales aquí.

    // 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. Agregue un punto de conexión de servicio al host de servicio. Para ello, siga estos pasos:

    • Use el enlace creado en el paso 5.

    • Especifique un URI de conexión que contenga credenciales y, si es necesario, un identificador de entrada.

    • Especifique el contrato como "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. Para recibir el mensaje de notificación, abra el host de servicio.

    // Open the service host to begin receiving notifications
    serviceHost.Open();
    
  11. Para dejar de recibir notificaciones, cierre el host del servicio.

    serviceHost.Close();
    

Ejemplo

En el ejemplo siguiente se muestra una aplicación .NET para recibir mensajes de notificación para la tabla ACCOUNTACTIVITY.

Nota

El siguiente fragmento de código crea una instancia de una clase TableOperation.cs e invoca el método TableOp . La clase y el método se describen en el paso 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();
            }

        }
    }
}

Consulte también

Desarrollo de aplicaciones de Oracle E-Business Suite mediante el modelo de servicio WCF