Sondear Oracle E-Business Suite mediante procedimientos almacenados con el modelo de servicio WCF
Puede configurar el adaptador de Oracle E-Business para recibir mensajes periódicos de cambio de datos mediante procedimientos almacenados para sondear periódicamente la base de datos de Oracle. Puede especificar un procedimiento almacenado como una instrucción de sondeo que el adaptador ejecuta periódicamente para sondear la base de datos de Oracle.
Para habilitar el sondeo, debe especificar determinadas propiedades de enlace como se describe en este tema. Para obtener más información sobre cómo el adaptador admite el sondeo, consulte Compatibilidad con llamadas entrantes mediante sondeo.
Configuración de una operación de sondeo con propiedades de enlace del adaptador de E-Business de Oracle
En la tabla siguiente se resumen las propiedades de enlace del adaptador de E-Business de Oracle que se usan para configurar el adaptador para recibir mensajes de cambio de datos. Debe especificar estas propiedades de enlace al ejecutar la aplicación de sondeo.
Binding (propiedad) | Descripción |
---|---|
InboundOperationType | Especifica si desea realizar una operación de sondeo o notificación de entrada. El valor predeterminado es Sondeo. |
PolledDataAvailableStatement | Especifica la instrucción SQL que ejecuta el adaptador para determinar si hay datos disponibles para el sondeo. Solo si hay un registro disponible, se ejecutará el procedimiento almacenado especificado para la propiedad de enlace PollingInput . |
PollingInterval | Especifica el intervalo, en segundos, en el que el adaptador de Oracle E-Business ejecuta la instrucción especificada para la propiedad de enlace PolledDataAvailableStatement . El valor predeterminado es 30 segundos. El intervalo de sondeo determina el intervalo de tiempo entre sondeos sucesivos. Si la instrucción se ejecuta dentro del intervalo especificado, el adaptador se suspende durante el tiempo restante del intervalo. |
PollingInput | Especifica la instrucción de sondeo. Para sondear mediante un procedimiento almacenado, debe especificar todo el mensaje de solicitud para esta propiedad de enlace. El mensaje de solicitud debe ser el mismo que se envía al adaptador para invocar el procedimiento almacenado como una operación saliente. El valor predeterminado es null. Debe especificar un valor para la propiedad de enlace PollingInput para habilitar el sondeo. La instrucción de sondeo solo se ejecuta si hay datos disponibles para el sondeo, que viene determinado por la propiedad de enlace PolledDataAvailableStatement . |
PollingAction | Especifica la acción para la operación de sondeo. Puede determinar la acción de sondeo de la interfaz de servicio generada para la operación mediante el complemento Agregar referencia de servicio de adaptador de Visual Studio. |
PostPollStatement | Especifica un bloque de instrucciones que se ejecuta después de que se ejecute la instrucción especificada por la propiedad de enlace PollingInput . |
PollWhileDataFound | Especifica si el adaptador de Oracle E-Business omite el intervalo de sondeo y ejecuta continuamente la instrucción de sondeo, si los datos están disponibles en la tabla que se está sondeando. Si no hay datos disponibles en la tabla, el adaptador revierte para ejecutar la instrucción de sondeo en el intervalo de sondeo especificado. El valor predeterminado es False. |
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 sondear, lea las secciones siguientes.
Cómo muestra este tema el sondeo
En este tema, para demostrar cómo el adaptador de Oracle E-Business admite la recepción de mensajes de cambio de datos mediante procedimientos almacenados, use el procedimiento almacenado GET_ACTIVITYS para sondear la tabla ACCOUNTACTIVITY de la base de datos de Oracle. Este procedimiento almacenado está disponible con el paquete ACCOUNT_PKG. Puede ejecutar los scripts SQL proporcionados con los ejemplos para crear estos objetos en la base de datos.
Nota
En el ejemplo de este tema se sondea la tabla ACCOUNTACTIVITY, que es una tabla de base de datos base creada mediante la ejecución de los scripts proporcionados con los ejemplos. Debe realizar procedimientos similares como se describe en este tema para sondear cualquier otra tabla, incluidas las tablas de interfaz.
Para demostrar una operación de sondeo, hacemos lo siguiente:
Especifique una instrucción SELECT para la propiedad de enlace PolledDataAvailableStatement para determinar dónde se sondea la tabla (ACCOUNTACTIVITY) tiene datos. En este ejemplo, puede establecer esta propiedad de enlace como:
SELECT COUNT (*) FROM ACCOUNTACTIVITY
Esto garantiza que el adaptador ejecute la instrucción de sondeo solo cuando la tabla ACCOUNTACTIVITY tenga algunos registros.
Ejecute un procedimiento almacenado, GET_ACTIVITYS, proporcionando el mensaje de solicitud como parte de la propiedad de enlace PollingInput . Este procedimiento almacenado recuperará todas las filas de la tabla ACCOUNTACTIVITY y obtendrá un mensaje de respuesta del adaptador.
Ejecute un bloque PL/SQL como parte de la propiedad de enlace PostPollStatement . Esta instrucción moverá todos los datos de la tabla ACCOUNTACTIVITY a otra tabla de la base de datos. Después de esto, la próxima vez que se ejecute PollingInput , no capturará ningún dato y, por tanto, el GET_ACTIVITYS procedimiento almacenado devolverá un mensaje de respuesta vacío.
Hasta que se agreguen más datos a la tabla ACCOUNTACTIVITY, seguirá recibiendo mensajes de respuesta vacíos, por lo que debe volver a rellenar la tabla ACCOUNTACTIVITY con nuevos registros. Para ello, ejecute el script more_activity_data.sql proporcionado con los ejemplos. Después de ejecutar este script, la siguiente operación de sondeo capturará los nuevos registros insertados en la tabla.
Configuración del sondeo en el modelo de servicio WCF
Para sondear mediante procedimientos almacenados con el adaptador de Oracle E-Business con el modelo de servicio WCF, debe hacer lo siguiente:
Genere un contrato de servicio WCF (interfaz) para el procedimiento almacenado mediante el que va a sondear. En este ejemplo, debe generar el contrato de servicio WCF para el GET_ACTIVITYS procedimiento almacenado como una operación de entrada. Para ello, puede usar el complemento Agregar referencia de servicio de 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 sondean la tabla de base de datos ACCOUNTACTIVITY mediante el procedimiento almacenado GET_ACTIVITYS. Se proporciona un script para generar la tabla y el procedimiento almacenado 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 de StoredProcPolling_ServiceModel, que se basa en este tema, con los ejemplos de adaptadores de Oracle E-Business.
El contrato de servicio y la clase 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 entrada de GET_ACTIVITYS . 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.
Contrato de servicio WCF (interfaz)
En el código siguiente se muestra el contrato de servicio WCF (interfaz) generado para la operación de entrada GET_ACTIVITYS .
[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);
}
Contratos de mensaje
A continuación se muestra el contrato de mensaje para la operación de entrada de 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;
}
}
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 desde el contrato de servicio (interfaz). El nombre del archivo es OracleEBSBindingService.cs. Puede insertar la lógica para procesar la operación de GET_ACTIVITYS directamente en esta clase. En el código siguiente se muestra la clase de servicio WCF generada por el complemento Add Adapter Service Reference.
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.");
}
}
}
Recepción de mensajes entrantes para el sondeo mediante un procedimiento almacenado
En esta sección se proporcionan instrucciones sobre cómo escribir una aplicación .NET para recibir mensajes de sondeo entrantes mediante el adaptador de Oracle E-Business.
Para recibir mensajes de sondeo mediante un procedimiento almacenado
Use el complemento Agregar referencia de servicio de adaptador para generar un contrato de servicio WCF (interfaz) y clases auxiliares para la operación de entrada GET_ACTIVITYS . Para obtener 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.
Implemente un servicio WCF desde la interfaz y las clases auxiliares generadas en el paso 1. El método GET_ACTIVITYS de esta clase puede producir una excepción para anular la transacción de sondeo, si se encuentra un error al procesar los datos recibidos de la operación de GET_ACTIVITYS ; 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 GET_ACTIVITYS , 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 sondeo recibido y se escribe en la consola.
[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"); } }
Debe implementar la siguiente clase para evitar pasar credenciales como parte del URI. En la última parte de la aplicación, creará una instancia de esta clase para pasar las credenciales.
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; } }
Cree una instancia de OracleEBSBinding y configure la operación de sondeo 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, PolledDataAvailableStatement, PollingInput y 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;";
Nota
Tenga en cuenta que el valor de la propiedad de enlace PollingInput contiene el mensaje de solicitud para invocar el procedimiento almacenado GET_ACTIVITYS como una operación de salida.
Importante
En este ejemplo, dado que está sondeando una tabla de base de datos, no es necesario establecer el contexto de las aplicaciones. Sin embargo, si sondeaba una tabla de interfaz, debe establecer el contexto de las aplicaciones especificando las propiedades de enlace OracleUserName, OraclePassword y OracleEBSResponsibilityName . Para más información sobre el contexto de la aplicación, consulte Establecimiento del contexto de la aplicación.
Especifique las credenciales de Oracle E-Business Suite mediante la creación de instancias de la clase PollingCredentials que creó en el paso 3.
PollingCredentials credentials = new PollingCredentials(); credentials.UserName.UserName = "<Enter user name here>"; credentials.UserName.Password = "<Enter password here>";
Cree una instancia del servicio WCF creado en el paso 2.
// create service instance PollingService service = new PollingService();
Cree una instancia de System.ServiceModel.ServiceHost mediante el servicio WCF y un URI de conexión base. El URI de conexión base no puede contener el identificador de entrada, si se especifica. También debe pasar 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);
Agregue un punto de conexión de servicio al host de servicio. Para ello, siga estos pasos:
Use el enlace creado en el paso 4.
Especifique un URI de conexión que contenga credenciales y, si es necesario, un identificador de entrada.
Especifique el contrato como "PollingPackageApis_APPS_ACCOUNT_PKG" para sondear la tabla de interfaz de 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);
Para recibir datos de sondeo, abra el host de servicio. El adaptador devolverá datos cada vez que la consulta devuelva un conjunto de resultados.
// Open the service host to begin polling serviceHost.Open();
Para finalizar el sondeo, cierre el host de servicio.
Importante
El adaptador seguirá sondeando hasta que se cierre el host de servicio.
serviceHost.Close();
Ejemplo
En el ejemplo siguiente se muestra una aplicación de sondeo que sondea la tabla de base de datos ACCOUNTACTIVITY mediante el procedimiento almacenado GET_ACTIVITYS. La propiedad de enlace PollingInput contiene el mensaje de solicitud para invocar el procedimiento almacenado GET_ACTIVITYS que lee todos los datos de la tabla ACCOUNTACTIVITY y la instrucción post poll mueve todos los datos de ACCOUNTACTIVITY a la tabla ACTIVITYHISTORY.
El primer mensaje de sondeo proporciona todos los registros de la tabla ACCOUNTACTIVITY. Los mensajes de sondeo posteriores no contendrán ningún registro porque la instrucción post poll elimina los registros. Hasta que se agreguen más datos a la tabla ACCOUNTACTIVITY, no obtendrá ningún mensaje de sondeo, por lo que debe volver a rellenar la tabla ACCOUNTACTIVITY con nuevos registros. Para ello, ejecute el script more_activity_data.sql proporcionado con los ejemplos.
Después de ejecutar este script, la siguiente operación de sondeo capturará los nuevos registros insertados en la tabla. El adaptador seguirá sondeando hasta que cierre el host de servicio presionando <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();
}
}
}
}
Consulte también
Sondear Oracle E-Business Suite mediante el modelo de servicio WCF