Recepción de mensajes modificados por datos basados en sondeo en Oracle Database mediante el modelo de servicio WCF
Puede configurar el adaptador de Microsoft BizTalk para oracle Database para recibir mensajes modificados de datos basados en sondeos en una tabla o vista de Oracle. Para recibir mensajes modificados por datos, el adaptador ejecuta periódicamente una consulta SQL en una tabla o vista de Oracle seguida de un bloque de código PL/SQL opcional. A continuación, el adaptador de base de datos de Oracle devuelve los resultados de la consulta SQL a la aplicación como un conjunto de resultados fuertemente tipado en una operación POLLINGSTMT de entrada. Para obtener más información sobre el mecanismo usado para configurar y realizar sondeos en una base de datos de Oracle mediante el adaptador de base de datos de Oracle, consulte Recepción de mensajes modificados por datos basados en sondeos en el adaptador de base de datos de Oracle. Se recomienda encarecidamente leer este tema antes de continuar.
Para recibir la operación POLLINGSTMT al usar el modelo de servicio WCF, debe hacer lo siguiente:
Genere un contrato de servicio WCF (interfaz) para la operación POLLINGSTMT a partir de los metadatos expuestos por el adaptador. Para ello, use el complemento Agregar referencia del servicio adaptador de Visual Studio o la Herramienta de utilidad de metadatos ServiceModel (svcutil.exe).
Implemente un servicio WCF desde esta interfaz.
Hospede este servicio WCF mediante un host de servicio (System.ServiceModel.ServiceHost).
Los temas de esta sección proporcionan información y procedimientos que le ayudarán a realizar sondeos en tablas y vistas de base de datos de Oracle en el modelo de servicio WCF.
Acerca de los ejemplos usados en este tema
Los ejemplos de este tema usan la tabla /SCOTT/ACCOUNTACTIVITY y la función /SCOTT/Package/ACCOUNT_PKG/PROCESS_ACTIVITY. Se proporciona un script para generar estos artefactos con los ejemplos del paquete de adaptadores de BizTalk. Para obtener más información sobre los ejemplos, vea Ejemplos de adaptador.
Configuración del sondeo en el modelo de servicio WCF
Configure el adaptador de Base de datos de Oracle para realizar sondeos en tablas y vistas de base de datos de Oracle estableciendo propiedades de enlace y una propiedad de conexión opcional (parámetro). Algunas de estas propiedades son obligatorias y algunas, para tener un efecto, deben establecerse en tiempo de diseño y en tiempo de ejecución.
En tiempo de diseño, se establecen los parámetros de conexión y las propiedades de enlace al conectarse a la base de datos de Oracle para generar un contrato de servicio WCF.
En tiempo de ejecución, establezca propiedades de enlace en el objeto OracleDBBinding que se usa para crear el host de servicio. El parámetro de conexión se establece al agregar un agente de escucha de servicio al host de servicio.
En la lista siguiente se proporciona una breve introducción a las propiedades de enlace y los parámetros de conexión que se usan para configurar el sondeo:
Propiedad de enlace PollingStatement . Debe establecer esta propiedad de enlace en tiempo de diseño y en tiempo de ejecución.
Propiedades de enlace opcionales. Solo deben establecerse en tiempo de ejecución.
La propiedad de enlace AcceptCredentialsInUri . Debe establecer esta propiedad de enlace en true durante el tiempo de ejecución si desea habilitar las credenciales en el URI de conexión. El nombre de usuario y la contraseña deben estar presentes en el URI de conexión al agregar un punto de conexión de servicio al host de servicio.
Parámetro de cadena de consulta PollingId en el URI de conexión. Si desea cambiar el espacio de nombres de la operación POLLINGSTMT, debe establecer esta propiedad de conexión tanto en tiempo de diseño como en tiempo de ejecución.
Para obtener una descripción completa de las propiedades de enlace y los parámetros de conexión usados para configurar el sondeo, consulte Recepción de mensajes modificados por datos basados en sondeo en el adaptador de base de datos de Oracle.
Contrato y clase de servicio WCF
Use el complemento Agregar referencia de servicio de adaptador de Visual Studio o la Herramienta de utilidad de metadatos serviceModel (svcutil.exe) para crear un contrato de servicio WCF (interfaz) y clases auxiliares para la operación POLLINGSTMT.
Al conectarse a la base de datos de Oracle con cualquiera de estas herramientas para generar un contrato de servicio para la operación POLLINGSTMT:
Debe especificar la propiedad de enlace PollingStatement . El adaptador usa la instrucción SELECT de esta propiedad de enlace para generar los metadatos correctos para el conjunto de resultados fuertemente tipado devuelto por la operación POLLINGSTMT.
Opcionalmente, puede especificar un parámetro PollingId en el URI de conexión. El adaptador usa este parámetro para generar el espacio de nombres para la operación POLLINGSTMT.
En los siguientes ejemplos:
PollingStatement se establece en "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE".
PollingId se establece en "AcctActivity".
El contrato de servicio WCF (interfaz)
En el código siguiente se muestra el contrato de servicio WCF (interfaz) generado para la operación POLLINGSTMT.
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.LobServices.OracleDB/2007/03", ConfigurationName="POLLINGSTMT_OperationGroup")]
public interface POLLINGSTMT_OperationGroup {
// CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity)
// of message POLLINGSTMT does not match the default value (http://Microsoft.LobServices.OracleDB/2007/03)
[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMT")]
void POLLINGSTMT(POLLINGSTMT request);
}
Contratos de mensaje
El parámetro PollingId modifica el espacio de nombres del contrato de mensaje en el URI de conexión. El mensaje de solicitud devuelve un conjunto de registros fuertemente tipados.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="POLLINGSTMT", WrapperNamespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity", IsWrapped=true)]
public partial class POLLINGSTMT {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity", Order=0)]
public microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity.POLLINGSTMTRECORD[] POLLINGSTMTRECORD;
public POLLINGSTMT() {
}
public POLLINGSTMT(microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity.POLLINGSTMTRECORD[] POLLINGSTMTRECORD) {
this.POLLINGSTMTRECORD = POLLINGSTMTRECORD;
}
}
Espacio de nombres del contrato de datos
Un contrato de datos es un acuerdo formal entre un servicio y un cliente que abstractamente describe los datos que se van a intercambiar. Es decir, para comunicarse, el cliente y el servicio no tienen que compartir los mismos tipos, solo los mismos contratos de datos.
En el caso de los mensajes de cambio de datos, el espacio de nombres del contrato de datos también se modifica mediante el parámetro PollingId (si se especifica) en el URI de conexión. El contrato de datos se compone de una clase que representa un registro fuertemente tipado en el conjunto de resultados de la consulta. Los detalles de la definición de clase se omiten en este ejemplo. La clase contiene propiedades que representan las columnas del conjunto de resultados.
En el ejemplo siguiente, se usa pollingId "AcctActivity".
namespace microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity {
using System.Runtime.Serialization;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="POLLINGSTMTRECORD", Namespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity")]
public partial class POLLINGSTMTRECORD : object, System.Runtime.Serialization.IExtensibleDataObject {…}
}
}
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 OracleDBBindingService.cs. Puede insertar la lógica para procesar la operación POLLINGSTMT directamente en esta clase. Si usa svcutil.exe para generar la interfaz del contrato de servicio, debe implementar esta clase usted mismo. En el código siguiente se muestra la clase de servicio WCF generada por el complemento Agregar referencia del servicio adaptador.
namespace OracleDBBindingNamespace {
public class OracleDBBindingService : POLLINGSTMT_OperationGroup {
// CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity)
// of message POLLINGSTMT does not match the default value (http://Microsoft.LobServices.OracleDB/2007/03)
public virtual void POLLINGSTMT(POLLINGSTMT request) {
throw new System.NotImplementedException("The method or operation is not implemented.");
}
}
}
Recepción de la operación POLLINGSTMT
Para recibir datos de sondeo del adaptador de Base de datos de Oracle
Use el complemento Agregar referencia del servicio adaptador o svcutil.exe para generar un contrato de servicio WCF (interfaz) y clases auxiliares para la operación POLLINGSTMT. Para obtener más información, consulte Generación de un cliente WCF o un contrato de servicio WCF para artefactos de la solución oracle Database. Como mínimo, debe establecer la propiedad de enlace PollingStatement al conectarse al adaptador. Opcionalmente, puede especificar un parámetro PollingId en el URI de conexión. Si usa el complemento Agregar referencia del servicio adaptador, debe establecer todos los parámetros de enlace necesarios para la configuración. 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 POLLINGSTMT de esta clase puede producir una excepción para anular la transacción de sondeo, si se produce un error al procesar los datos recibidos de la operación POLLINGSTMT; de lo contrario, el método no devuelve nada. Debe atribuir la clase de servicio WCF de la siguiente manera:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
Si usó el complemento Add Adapter Service Reference para generar la interfaz, puede implementar la lógica directamente en el método POLLINGSTMT en la clase OracleDBBindingService generada. Esta clase se puede encontrar en OracleDBBindingService.cs. Este código de este ejemplo subclase la clase OracleDBBindingService .
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class PollingStmtService : OracleDBBindingService { public override void POLLINGSTMT(POLLINGSTMT request) { Console.WriteLine("\nNew Polling Records Received"); Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription"); for (int i = 0; i < request.POLLINGSTMTRECORD.Length; i++) { Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", request.POLLINGSTMTRECORD[i].TID, request.POLLINGSTMTRECORD[i].ACCOUNT, request.POLLINGSTMTRECORD[i].AMOUNT, request.POLLINGSTMTRECORD[i].TRANSDATE, request.POLLINGSTMTRECORD[i].DESCRIPTION); } } }
Si usó svcutil.exe para generar la interfaz, debe crear un servicio WCF que implemente la interfaz e implemente la lógica en el método POLLINGSTMT de esta clase.
Cree una instancia del servicio WCF creado en el paso 2.
// create service instance PollingStmtService pollingInstance = new PollingStmtService();
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 userinfoparams ni un query_string.
// Enable service host Uri[] baseUri = new Uri[] { new Uri("oracledb://Adapter") }; ServiceHost srvHost = new ServiceHost(pollingInstance, baseUri);
Cree un OracleDBBinding y configure la operación de sondeo estableciendo sus propiedades de enlace. Puede hacerlo explícitamente en el código o mediante declaración en la configuración. Como mínimo, debe especificar la instrucción de sondeo y el intervalo de sondeo. En este ejemplo, se especifican las credenciales como parte del URI, por lo que también debe establecer AcceptCredentialsInUri en true.
// Create and configure a binding for the service endpoint. NOTE: binding // parameters are set here for clarity, but these are already set in the // the generated configuration file OracleDBBinding binding = new OracleDBBinding(); // The credentials are included in the connection URI, so set this property to true binding.AcceptCredentialsInUri = true; // Same as statement specified in Configure Adapter dialog box binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE"; binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;"; // Be sure to set the interval long enough to complete processing before // the next poll binding.PollingInterval = 15; // Polling is transactional; be sure to set an adequate isolation level // for your environment binding.TransactionIsolationLevel = TransactionIsolationLevel.ReadCommitted;
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 PollingId.
Especifique el contrato como "POLLINGSTMT_OperationGroup".
// Add service endpoint: be sure to specify POLLINGSTMT_OperationGroup as the contract Uri serviceUri = new Uri("oracledb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivity"); srvHost.AddServiceEndpoint("POLLINGSTMT_OperationGroup", binding, serviceUri);
Para recibir datos de sondeo, abra el host del servicio. El adaptador devolverá datos cada vez que la consulta devuelva un conjunto de resultados.
// Open the service host to begin polling srvHost.Open();
Para finalizar el sondeo, cierre el host del servicio.
Importante
El adaptador seguirá sondeando hasta que se cierre el host de servicio.
srvHost.Close();
Ejemplo
En el ejemplo siguiente se muestra una consulta de sondeo que se ejecuta en la tabla /SCOTT/ACCOUNTACTIVITY. La instrucción post-poll invoca una función de Oracle que mueve los registros procesados a otra tabla /SCOTT/ACCOUNTHISTORY. El espacio de nombres de la operación POLLINGSTMT se modifica estableciendo el parámetro PollingId en "AccountActivity" en el URI de conexión. En este ejemplo, el servicio WCF para la operación POLLINGSTMT se crea mediante la subclase de la clase OracleDBBindingService generada; sin embargo, puede implementar la lógica directamente en la clase generada.
using System;
using System.Collections.Generic;
using System.Text;
// Add these three references to use the Oracle adapter
using System.ServiceModel;
using Microsoft.ServiceModel.Channels;
using Microsoft.Adapters.OracleDB;
using microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity;
using OracleDBBindingNamespace;
namespace OraclePollingSM
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class PollingStmtService : OracleDBBindingService
{
public override void POLLINGSTMT(POLLINGSTMT request)
{
Console.WriteLine("\nNew Polling Records Received");
Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription");
for (int i = 0; i < request.POLLINGSTMTRECORD.Length; i++)
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", request.POLLINGSTMTRECORD[i].TID,
request.POLLINGSTMTRECORD[i].ACCOUNT,
request.POLLINGSTMTRECORD[i].AMOUNT,
request.POLLINGSTMTRECORD[i].TRANSDATE,
request.POLLINGSTMTRECORD[i].DESCRIPTION);
}
Console.WriteLine("\nHit <RETURN> to stop polling");
}
}
class Program
{
static void Main(string[] args)
{
ServiceHost srvHost = null;
// This URI is used to specify the address for the ServiceEndpoint
// It must contain credentials and the PollingId (if any) that was used to generate
// the WCF service callback interface
Uri serviceUri = new Uri("OracleDb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivity");
// This URI is used to initialize the ServiceHost. It cannot contain
// userinfoparms (credentials) or a query_string (PollingId); otherwise,
// an exception is thrown when the ServiceHost is initialized.
Uri[] baseUri = new Uri[] { new Uri("OracleDb://Adapter") };
Console.WriteLine("Sample started, initializing service host -- please wait");
// create an instanc of the WCF service callback class
PollingStmtService pollingInstance = new PollingStmtService();
try
{
// Create a ServiceHost with the service callback instance and a base URI (address)
srvHost = new ServiceHost(pollingInstance, baseUri);
// Create and configure a binding for the service endpoint. Note: binding
// parameters are set here for clarity but these are already set in the
// generated configuration file
//
// The following properties are set
// AcceptCredentialsInUri (true) to enable credentials in the connection URI for AddServiceEndpoint
// PollingStatement
// PostPollStatement calls PROCESS_ACTIVITY on Oracle. This procedure moves the queried records to
// the ACCOUNTHISTORY table
// PollingInterval (15 seconds)
// TransactionIsolationLevel
OracleDBBinding binding = new OracleDBBinding();
// The Credentials are included in the Connection Uri so set this property true
binding.AcceptCredentialsInUri = true;
// Same as statement specified in Configure Adapter dialog box
binding.InboundOperationType = InboundOperation.Polling;
binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE";
binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";
// Be sure to set the interval long enough to complete processing before
// the next poll
binding.PollingInterval = 15;
// Polling is transactional, be sure to set an adequate isolation level
// for your environment
binding.TransactionIsolationLevel = TransactionIsolationLevel.ReadCommitted;
// Add service endpoint: be sure to specify POLLINGSTMT_OperationGroup as the contract
srvHost.AddServiceEndpoint("POLLINGSTMT_OperationGroup", binding, serviceUri);
Console.WriteLine("Opening the service host");
// Open the service host to begin polling
srvHost.Open();
// Wait to receive request
Console.WriteLine("\nPolling started. Returned records will be written to the console.");
Console.WriteLine("Hit <RETURN> to stop polling");
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("Exception :" + e.Message);
Console.ReadLine();
/* If there is an Oracle 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 (srvHost.State == CommunicationState.Opened)
srvHost.Close();
else
srvHost.Abort();
}
}
}
}
Consulte también
Desarrollo de aplicaciones de Oracle Database mediante el modelo de servicio WCF