Recevoir des appels RFC entrants dans SAP à l’aide du modèle de service WCF
L’adaptateur Microsoft BizTalk pour mySAP Business Suite peut agir comme un serveur RFC pour recevoir des RFC appelés par un système SAP.
Pour recevoir les RFC entrants dans le modèle de service WCF, vous devez :
Vérifiez qu’une destination RFC existe sur le système SAP.
Vérifiez que la RFC est définie sur le système SAP.
Générez un contrat de service WCF (interface) pour l’opération RFC à partir des métadonnées exposées par l’adaptateur. Pour ce faire, vous utilisez le plug-in Visual Studio Ajouter un service d’adaptateur ou l’outil utilitaire de métadonnées ServiceModel (svcutil.exe).
Implémentez un service WCF à partir de cette interface. Les méthodes du service WCF contiennent la logique nécessaire pour traiter la RFC et retourner une réponse à l’adaptateur (et donc au système SAP).
Hébergez ce service WCF à l’aide d’un hôte de service (System.ServiceModel.ServiceHost).
Les sections suivantes vous montrent comment recevoir des RFC du système SAP à l’aide de l’adaptateur SAP.
Comment configurer le système SAP pour envoyer une RFC à l’adaptateur SAP
Avant de pouvoir envoyer une RFC à partir du système SAP à l’adaptateur SAP, vous devez vous assurer que les éléments suivants sont vrais sur le système SAP :
Une destination RFC pour l’adaptateur SAP doit exister. L’adaptateur SAP s’inscrit lui-même auprès d’une destination RFC pour recevoir des RFC du système SAP. Vous fournissez des paramètres dans l’URI de connexion SAP, tels que l’hôte de passerelle SAP, le service de passerelle SAP et l’ID de programme SAP que l’adaptateur utilise pour s’inscrire. Pour plus d’informations sur la configuration d’une destination RFC sur SAP, consultez Créer une destination RFC, RFC et envoyer une RFC à partir d’un système SAP.
Le RFC doit être défini sur le système SAP. Vous devez créer un module de fonction qui définit la RFC sur le système SAP. L’adaptateur SAP utilise la définition RFC sur le système SAP pour récupérer les métadonnées relatives à la RFC (au moment de la conception et au moment de l’exécution). Pour plus d’informations, consultez Création d’un RFC dans un système SAP.
Notes
Vous devez définir la RFC sur le système SAP ; toutefois, vous implémentez le RFC dans le code client de votre adaptateur. La RFC doit être définie sur le système SAP afin que l’adaptateur puisse récupérer les métadonnées de la RFC.
Voici un exemple de code source sur le système SAP pour une RFC qui ajoute deux entiers et retourne leur résultat. Le code appelle simplement la RFC via une destination spécifiée. L’implémentation de la fonction est effectuée par le code client de l’adaptateur SAP.
FUNCTION Z_RFC_SAMPLE_ADD.
*"---------------------------------------------------------------------*"*"Local interface:
*" IMPORTING
*" VALUE(X) TYPE INT4
*" VALUE(Y) TYPE INT4
*" VALUE(DEST) TYPE CHAR20 DEFAULT 'SAPADAPTER'
*" EXPORTING
*" VALUE(RESULT) TYPE INT4
*"---------------------------------------------------------------------CALL FUNCTION 'Z_RFC_MKD_ADD' DESTINATION DEST
EXPORTING X = X
Y = Y
IMPORTING RESULT = RESULT.
ENDFUNCTION.
Contrat de service WCF pour une RFC
Vous utilisez le plug-in Visual Studio Add Adapter Service ou l’outil Utilitaire de métadonnées ServiceModel (svcutil.exe) pour générer un contrat de service WCF pour les RFC que vous souhaitez recevoir du système SAP. Les sections suivantes montrent les classes de code managé et les interfaces générées pour l’opération Z_RFC_MKD_ADD.
Interface Rfc (contrat de service WCF)
L’adaptateur SAP affiche toutes les opérations RFC sous un seul contrat de service, « Rfc ». Cela signifie qu’une interface unique, Rfc, est créée pour toutes les opérations RFC que vous souhaitez recevoir. Chaque opération RFC cible est représentée en tant que méthode de cette interface. Chaque méthode prend un paramètre unique, qui représente le contrat de message pour le message de demande de l’opération, et retourne un objet, qui représente le contrat de message du message de réponse de l’opération.
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/", ConfigurationName="Rfc")]
public interface Rfc {
// CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.Sap/2007/03/Rfc/) of message Z_RFC_MKD_ADDRequest does not match the default value (http://Microsoft.LobServices.Sap/2007/03/)
[System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.LobServices.Sap/2007/03/Rfc/Z_RFC_MKD_ADD", ReplyAction="http://Microsoft.LobServices.Sap/2007/03/Rfc/Z_RFC_MKD_ADD/response")]
Z_RFC_MKD_ADDResponse Z_RFC_MKD_ADD(Z_RFC_MKD_ADDRequest request);
}
Messages de demande et de réponse
Chaque opération RFC prend un paramètre qui représente le message de requête et retourne un objet qui représente le message de réponse. Les propriétés du message de requête contiennent les paramètres IMPORT et (entrée) CHANGING du RFC. Les propriétés du message de réponse contiennent les paramètres EXPORT et (sortie) CHANGING pour l’opération.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="Z_RFC_MKD_ADD", WrapperNamespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", IsWrapped=true)]
public partial class Z_RFC_MKD_ADDRequest {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", Order=0)]
public string DEST;
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", Order=1)]
public System.Nullable<int> X;
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", Order=2)]
public System.Nullable<int> Y;
public Z_RFC_MKD_ADDRequest() {
}
public Z_RFC_MKD_ADDRequest(string DEST, System.Nullable<int> X, System.Nullable<int> Y) {
this.DEST = DEST;
this.X = X;
this.Y = Y;
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="Z_RFC_MKD_ADDResponse", WrapperNamespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", IsWrapped=true)]
public partial class Z_RFC_MKD_ADDResponse {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", Order=0)]
public int RESULT;
public Z_RFC_MKD_ADDResponse() {
}
public Z_RFC_MKD_ADDResponse(int RESULT) {
this.RESULT = RESULT;
}
}
Service WCF généré
Le plug-in Add Adapter Service Reference génère également un service WCF qui implémente le contrat de service WCF (Rfc). Les méthodes de cette classe sont stoubées. Cette classe est générée dans un fichier distinct. Vous pouvez implémenter votre code directement dans les méthodes de cette classe.
namespace SAPBindingNamespace {
public class SAPBindingService : Rfc {
// CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.Sap/2007/03/Rfc/) of message Z_RFC_MKD_ADDRequest does not match the default value (http://Microsoft.LobServices.Sap/2007/03/)
public virtual Z_RFC_MKD_ADDResponse Z_RFC_MKD_ADD(Z_RFC_MKD_ADDRequest request) {
throw new System.NotImplementedException("The method or operation is not implemented.");
}
}
}
Comment créer une application serveur RFC
Pour recevoir des RFC du système SAP à l’aide du modèle de service WCF, vous pouvez suivre les étapes décrites dans Vue d’ensemble du modèle de service WCF avec l’adaptateur SAP. Veillez à spécifier « Rfc » pour le contrat de service lorsque vous ajoutez le point de terminaison de service (étape 6 de la procédure de création et d’implémentation d’un service WCF).
Le code suivant montre un exemple complet de la façon de recevoir les Z_RFC_MKD_RFC d’un système SAP à l’aide de l’adaptateur SAP. Cette RFC prend deux paramètres entiers et retourne le résultat au système SAP.
using System;
using System.Collections.Generic;
using System.Text;
// Add WCF, WCF LOB Adapter SDK, and SAP adapter namepaces
using System.ServiceModel;
using Microsoft.Adapters.SAP;
using Microsoft.ServiceModel.Channels;
// Include this namespace for the WCF LOB Adapter SDK and SAP adapter exceptions
using Microsoft.ServiceModel.Channels.Common;
namespace SapRfcServerSM
{
// Implement a WCF service callback class by sub-classing the generated service callback class (SAPBindingService).
// You must annotate this class with the InstanceContextMode.Single ServiceBehavior
// If you implement your code in SAPBindingService.cs be sure to annotate the SAPBindingService class
// The callback method should return a Z_RFC_MKD_ADDResponse to indicate successful processing
// or throw an exception to indicate an error.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,UseSynchronizationContext = false)]
class RfcServerClass : SAPBindingNamespace.SAPBindingService
{
public override Z_RFC_MKD_ADDResponse Z_RFC_MKD_ADD(Z_RFC_MKD_ADDRequest request)
{
// If either parameter is null, throw an exception
if (request.X == null || request.Y == null)
throw new System.ArgumentNullException();
int result = (int) (request.X + request.Y);
Console.WriteLine("\nRfc Received");
Console.WriteLine("X =\t\t" + request.X.ToString());
Console.WriteLine("Y =\t\t" + request.Y.ToString());
Console.WriteLine("Result =\t" + result);
Console.WriteLine("\nHit <RETURN> to end");
return new Z_RFC_MKD_ADDResponse(result);
}
}
class Program
{
static void Main(string[] args)
{
// Listener connection for the service URI -- the connection URI must contain credentials
Uri serviceUri = new Uri("sap://User=YourUserName;Passwd=YourPassword;Client=800;Lang=EN;@a/ADAPSAP47/00?ListenerGwServ=SAPGW00&ListenerGwHost=ADAPSAP47&ListenerProgramId=ADDER");
// The baseUri cannot contain userinfoparams or query_string parameters
Uri[] baseUri = new Uri[] { new Uri("sap://a/ADAPSAP47/00") };
Console.WriteLine("RFC server sample started");
// create service instance
RfcServerClass rfcServerInstance = new RfcServerClass();
try
{
Console.WriteLine("Initializing service host -- please wait");
// Create and initialize a service host
using (ServiceHost srvHost = new ServiceHost(rfcServerInstance, baseUri))
{
// Add service endpoint
// Specify AcceptCredentalsInUri=true for the binding
// NOTE: The contract for the service endpoint is "Rfc".
// This is the generated WCF service callback interface (see SAPBindingInterface.cs).
SAPBinding binding = new SAPBinding();
binding.AcceptCredentialsInUri = true;
srvHost.AddServiceEndpoint("Rfc", binding, serviceUri);
srvHost.Open();
Console.WriteLine("\nReady to receive Z_RFC_MKD_ADD RFC");
Console.WriteLine("Hit <RETURN> to end");
// Wait to receive request
Console.ReadLine();
}
}
catch (ConnectionException cex)
{
Console.WriteLine("Exception occurred connecting to the SAP system");
Console.WriteLine(cex.InnerException.Message);
}
catch (TargetSystemException tex)
{
Console.WriteLine("Exception occurred on the SAP system");
Console.WriteLine(tex.InnerException.Message);
}
catch (Exception ex)
{
Console.WriteLine("Exception is: " + ex.Message);
if (ex.InnerException != null)
{
Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);
}
}
}
}
}
Voir aussi
Développer des applications en utilisant le modèle de service WCF
Schémas de message pour les opérations RFC