Eseguire il polling di Oracle E-Business Suite usando stored procedure con il modello di servizio WCF
È possibile configurare l'adapter Oracle E-Business per ricevere messaggi periodici di modifica dei dati usando stored procedure per eseguire periodicamente il polling del database Oracle. È possibile specificare una stored procedure come istruzione di polling eseguita periodicamente dall'adapter per eseguire il polling del database Oracle.
Per abilitare il polling, è necessario specificare determinate proprietà di associazione, come descritto in questo argomento. Per altre informazioni su come l'adapter supporta il polling, vedere Supporto per le chiamate in ingresso usando il polling.
Configurazione di un'operazione di polling con le proprietà di associazione dell'adapter Oracle E-Business
Nella tabella seguente vengono riepilogate le proprietà di associazione dell'adapter Oracle E-Business usate per configurare la scheda per ricevere messaggi di modifica dei dati. È necessario specificare queste proprietà di associazione durante l'esecuzione dell'applicazione di polling.
Binding, proprietà | Descrizione |
---|---|
InboundOperationType | Specifica se si vuole eseguire un'operazione di polling o notifica in ingresso. Il valore predefinito è Polling. |
PolledDataAvailableStatement | Specifica l'istruzione SQL eseguita dall'adapter per determinare se i dati sono disponibili per il polling. Solo se è disponibile un record, verrà eseguita la stored procedure specificata per la proprietà di associazione PollingInput . |
PollingInterval | Specifica l'intervallo, in secondi, in cui l'adapter Oracle E-Business esegue l'istruzione specificata per la proprietà di associazione PolledDataAvailableStatement . Il valore predefinito è 30 secondi. L'intervallo di polling determina l'intervallo di tempo tra i polling successivi. Se l'istruzione viene eseguita all'interno dell'intervallo specificato, l'adapter dorme per il tempo rimanente nell'intervallo. |
PollingInput | Specifica l'istruzione di polling. Per eseguire il polling usando una stored procedure, è necessario specificare l'intero messaggio di richiesta per questa proprietà di associazione. Il messaggio di richiesta deve essere lo stesso che si invia all'adapter per richiamare la stored procedure come operazione in uscita. Il valore predefinito è Null. È necessario specificare un valore per la proprietà di associazione PollingInput per abilitare il polling. L'istruzione polling viene eseguita solo se sono disponibili dati per il polling, che viene determinato dalla proprietà di associazione PolledDataAvailableStatement . |
PollingAction | Specifica l'azione per l'operazione di polling. È possibile determinare l'azione di polling dall'interfaccia del servizio generata per l'operazione usando il plug-in Add Adapter Service Reference Visual Studio. |
PostPollStatement | Specifica un blocco di istruzioni eseguito dopo l'istruzione specificata dalla proprietà di associazione PollingInput . |
PollWhileDataFound | Specifica se l'adapter Oracle E-Business ignora l'intervallo di polling ed esegue continuamente l'istruzione di polling, se i dati sono disponibili nella tabella in cui viene eseguito il polling. Se nella tabella non sono disponibili dati, l'adapter esegue l'istruzione di polling all'intervallo di polling specificato. L'impostazione predefinita è false. |
Per una descrizione più completa di queste proprietà, vedere Informazioni sulle proprietà di associazione BizTalk Adapter for Oracle E-Business Suite. Per una descrizione completa di come usare l'adapter Oracle E-Business per eseguire il polling, leggere le sezioni seguenti.
Come viene illustrato il polling di questo argomento
In questo argomento viene illustrato come l'adapter Oracle E-Business supporta la ricezione di messaggi di modifica dei dati usando stored procedure, usare la stored procedure GET_ACTIVITYS per eseguire il polling della tabella ACCOUNTACTIVITY nel database Oracle. Questa stored procedure è disponibile con il pacchetto ACCOUNT_PKG. È possibile eseguire gli script SQL forniti con gli esempi per creare questi oggetti nel database.
Nota
L'esempio in questo argomento esegue il polling della tabella ACCOUNTACTIVITY, ovvero una tabella di database di base creata eseguendo gli script forniti con gli esempi. È necessario eseguire procedure simili come descritto in questo argomento per eseguire il polling di qualsiasi altra tabella, incluse le tabelle dell'interfaccia.
Per illustrare un'operazione di polling, eseguire le operazioni seguenti:
Specificare un'istruzione SELECT per la proprietà di associazione PolledDataAvailableStatement per determinare dove viene eseguito il polling della tabella (ACCOUNTACTIVITY). In questo esempio è possibile impostare questa proprietà di associazione come:
SELECT COUNT (*) FROM ACCOUNTACTIVITY
Ciò garantisce che l'adapter esegua l'istruzione di polling solo quando la tabella ACCOUNTACTIVITY contiene alcuni record.
Eseguire una stored procedure, GET_ACTIVITYS, fornendo il messaggio di richiesta come parte della proprietà di associazione PollingInput . Questa stored procedure recupera tutte le righe della tabella ACCOUNTACTIVITY e verrà visualizzato un messaggio di risposta dall'adapter.
Eseguire un blocco PL/SQL come parte della proprietà di associazione PostPollStatement . Questa istruzione sposta tutti i dati dalla tabella ACCOUNTACTIVITY a un'altra tabella nel database. Dopo questo problema, la prossima volta che PollingInput viene eseguito, non recupera i dati e quindi la stored procedure GET_ACTIVITYS restituirà un messaggio di risposta vuoto.
Fino a quando non vengono aggiunti altri dati alla tabella ACCOUNTACTIVITY, si continueranno a ottenere messaggi di risposta vuoti in modo da ripopolare la tabella ACCOUNTACTIVITY con nuovi record. È possibile farlo eseguendo lo script more_activity_data.sql fornito con gli esempi. Dopo aver eseguito questo script, l'operazione di polling successiva recupera i nuovi record inseriti nella tabella.
Configurazione del polling nel modello di servizio WCF
Per eseguire il polling usando stored procedure con l'adapter Oracle E-Business con il modello di servizio WCF, è necessario:
Generare un contratto di servizio WCF (interfaccia) per la stored procedure con cui si intende eseguire il polling. Per questo esempio, è necessario generare il contratto di servizio WCF per la stored procedure GET_ACTIVITYS come operazione in ingresso. A tale scopo, è possibile usare il plug-in Aggiungi plug-in del servizio adapter.
Implementare un servizio WCF da questa interfaccia.
Ospitare questo servizio WCF usando un host del servizio (System.ServiceModel.ServiceHost).
Informazioni sugli esempi usati in questo argomento
Gli esempi in questo argomento eseguano il polling della tabella di database ACCOUNTACTIVITY usando la stored procedure GET_ACTIVITYS. Uno script per generare la tabella e la stored procedure viene fornita con gli esempi. Per altre informazioni sugli esempi, vedere Esempi per l'adapter Oracle EBS. Un esempio, StoredProcPolling_ServiceModel, basato su questo argomento, viene fornito anche con gli esempi di adapter Oracle E-Business.
Contratto e classe del servizio WCF
È possibile usare il plug-in Add Adapter Service Reference per creare un contratto di servizio WCF (interfaccia) e le classi di supporto per l'operazione GET_ACTIVITYS in ingresso. Per altre informazioni sulla generazione di un contratto di servizio WCF, vedere Generare un client WCF o un contratto di servizio WCF per gli artefatti della soluzione Oracle E-Business Suite.
Contratto di servizio WCF (interfaccia)
Il codice seguente mostra il contratto di servizio WCF (interfaccia) generato per l'operazione in ingresso 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);
}
Contratti messaggio
Di seguito è riportato il contratto di messaggio per l'operazione GET_ACTIVITYS in ingresso.
[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;
}
}
Classe di servizio WCF
Il plug-in Add Adapter Service Reference genera anche un file con stub per la classe di servizio WCF implementata dal contratto di servizio (interfaccia). Il nome del file è OracleEBSBindingService.cs. È possibile inserire la logica per elaborare l'operazione di GET_ACTIVITYS direttamente in questa classe. Il codice seguente mostra la classe di servizio WCF generata dal plug-in 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.");
}
}
}
Ricezione di messaggi in ingresso per il polling tramite una stored procedure
Questa sezione fornisce istruzioni su come scrivere un'applicazione .NET per ricevere messaggi di polling in ingresso usando l'adapter Oracle E-Business.
Per ricevere messaggi di polling usando una stored procedure
Usare il plug-in Add Adapter Service Reference per generare un contratto di servizio WCF (interfaccia) e le classi helper per l'operazione GET_ACTIVITYS in ingresso. Per altre informazioni, vedere Generare un client WCF o un contratto di servizio WCF per gli artefatti della soluzione Oracle E-Business Suite. Facoltativamente, è possibile specificare le proprietà di associazione durante la generazione di classi del contratto di servizio e helper. Ciò garantisce che siano impostate correttamente nel file di configurazione generato.
Implementare un servizio WCF dalle classi di interfaccia e helper generate nel passaggio 1. Il metodo GET_ACTIVITYS di questa classe può generare un'eccezione per interrompere la transazione di polling, se si verifica un errore durante l'elaborazione dei dati ricevuti dall'operazione di GET_ACTIVITYS ; in caso contrario, il metodo non restituisce nulla. È necessario specificare la classe di servizio WCF come indicato di seguito:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
All'interno del metodo GET_ACTIVITYS è possibile implementare direttamente la logica dell'applicazione. Questa classe è disponibile in OracleEBSBindingService.cs. Questo codice in questa sottoclasse di esempio esegue la classe OracleEBSBindingService . In questo codice il messaggio di polling ricevuto e viene scritto nella console.
[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"); } }
È necessario implementare la classe seguente per evitare di passare le credenziali come parte dell'URI. Nella seconda parte dell'applicazione verrà creata un'istanza di questa classe per passare le credenziali.
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; } }
Creare un oggetto OracleEBSBinding e configurare l'operazione di polling specificando le proprietà di associazione. È possibile eseguire questa operazione in modo esplicito nel codice o in modo dichiarativo nella configurazione. Almeno, è necessario specificare le proprietà di associazione InboundOperationType, PolledDataAvailableStatement, PollingInput e 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
Si noti che il valore per la proprietà di associazione PollingInput contiene il messaggio di richiesta per richiamare la stored procedure GET_ACTIVITYS come operazione in uscita.
Importante
In questo esempio, poiché si esegue il polling di una tabella di database, non è necessario impostare il contesto delle applicazioni. Tuttavia, se si esegue il polling di una tabella di interfaccia, è necessario impostare il contesto delle applicazioni specificando le proprietà di associazione OracleUserName, OraclePassword e OracleEBSResponsibilityName . Per altre informazioni sul contesto dell'applicazione, vedere Impostare il contesto dell'applicazione.
Specificare le credenziali di Oracle E-Business Suite creando un'istanza della classe PollingCredentials creata nel passaggio 3.
PollingCredentials credentials = new PollingCredentials(); credentials.UserName.UserName = "<Enter user name here>"; credentials.UserName.Password = "<Enter password here>";
Creare un'istanza del servizio WCF creata nel passaggio 2.
// create service instance PollingService service = new PollingService();
Creare un'istanza di System.ServiceModel.ServiceHost usando il servizio WCF e un URI di connessione di base. L'URI di connessione di base non può contenere l'ID in ingresso, se specificato. È anche necessario passare le credenziali qui.
// Enable service host Uri[] baseUri = new Uri[] { new Uri("oracleebs://ebs_instance_name") }; ServiceHost serviceHost = new ServiceHost(service, baseUri); serviceHost.Description.Behaviors.Add(credentials);
Aggiungere un endpoint di servizio all'host del servizio. Per eseguire questa operazione:
Usare l'associazione creata nel passaggio 4.
Specificare un URI di connessione contenente le credenziali e, se necessario, un ID in ingresso.
Specificare il contratto come "PollingPackageApis_APPS_ACCOUNT_PKG" per eseguire il polling della tabella dell'interfaccia 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);
Per ricevere i dati di polling, aprire l'host del servizio. L'adapter restituirà i dati ogni volta che la query restituisce un set di risultati.
// Open the service host to begin polling serviceHost.Open();
Per terminare il polling, chiudere l'host del servizio.
Importante
L'adapter continuerà a eseguire il polling fino alla chiusura dell'host del servizio.
serviceHost.Close();
Esempio
Nell'esempio seguente viene illustrata un'applicazione di polling che esegue il polling della tabella di database ACCOUNTACTIVITY usando la stored procedure GET_ACTIVITYS. La proprietà di associazione PollingInput contiene il messaggio di richiesta per richiamare la stored procedure GET_ACTIVITYS che legge tutti i dati della tabella ACCOUNTACTIVITY e l'istruzione post poll sposta tutti i dati dalla tabella ACCOUNTACTIVITY alla tabella ACTIVITYHISTORY.
Il primo messaggio di polling fornisce tutti i record della tabella ACCOUNTACTIVITY. I messaggi di polling successivi non contengono record perché l'istruzione post poll elimina i record. Fino a quando non vengono aggiunti altri dati alla tabella ACCOUNTACTIVITY, non verranno visualizzati messaggi di polling, pertanto è necessario ripopolare la tabella ACCOUNTACTIVITY con nuovi record. È possibile farlo eseguendo lo script more_activity_data.sql fornito con gli esempi.
Dopo aver eseguito questo script, l'operazione di polling successiva recupera i nuovi record inseriti nella tabella. L'adapter continuerà a eseguire il polling fino a chiudere l'host del servizio premendo <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();
}
}
}
}
Vedere anche
Eseguire il polling di Oracle E-Business Suite usando il modello di servizio WCF