WCF サービス モデルを使用して SAP で受信 RFC 呼び出しを受信する
Microsoft BizTalk Adapter for mySAP Business Suite は、SAP システムによって呼び出された RFC を受信する RFC サーバーとして機能できます。
WCF サービス モデルで受信 RFC を受信するには、次の手順を実行する必要があります。
RFC 変換先が SAP システムに存在することを確認します。
RFC が SAP システムで定義されていることを確認します。
アダプターによって公開されるメタデータから、RFC 操作の WCF サービス コントラクト (インターフェイス) を生成します。 これを行うには、アダプター サービス参照の追加 Visual Studio プラグインまたは ServiceModel メタデータ ユーティリティ ツール (svcutil.exe) を使用します。
このインターフェイスから WCF サービスを実装します。 WCF サービスのメソッドには、RFC を処理し、アダプター (および SAP システム) に応答を返すために必要なロジックが含まれています。
サービス ホスト (System.ServiceModel.ServiceHost) を使用して、この WCF サービスをホストします。
次のセクションでは、SAP アダプターを使用して SAP システムから RFC を受信する方法について説明します。
SAP アダプターに RFC を送信するように SAP システムを設定する方法
SAP システムから SAP アダプターに RFC を送信する前に、SAP システムで次のことが当てはまることを確認する必要があります。
SAP アダプターの RFC 変換先が存在する必要があります。 SAP アダプターは、RFC 変換先に自身を登録して、SAP システムから RFC を受信します。 SAP ゲートウェイ ホスト、SAP ゲートウェイ サービス、アダプターが自身の登録に使用する SAP プログラム ID など、SAP 接続 URI にパラメーターを指定します。 SAP で RFC 変換先を設定する方法については、「RFC、 RFC 変換先を作成し、SAP システムから RFC を送信する」を参照してください。
RFC は SAP システムで定義する必要があります。 SAP システムで RFC を定義する汎用モジュールを作成する必要があります。 SAP アダプターは、SAP システムの RFC 定義を使用して、RFC に関するメタデータを取得します (デザイン時と実行時の両方)。 詳細については、「 SAP システムでの RFC の作成」を参照してください。
Note
SAP システムで RFC を定義する必要があります。ただし、アダプター クライアント コードに RFC を実装します。 アダプターが RFC のメタデータを取得できるように、RFC を SAP システムで定義する必要があります。
2 つの整数を追加し、その結果を返す RFC の SAP システム上のソース コードの例を次に示します。 このコードは、指定された宛先を介して RFC を呼び出すだけです。 関数の実装は、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.
RFC の WCF サービス コントラクト
アダプター サービス参照の追加 Visual Studio プラグインまたは ServiceModel メタデータ ユーティリティ ツール (svcutil.exe) を使用して、SAP システムから受信する RFC の WCF サービス コントラクトを生成します。 次のセクションでは、Z_RFC_MKD_ADD操作用に生成されたマネージ コード クラスとインターフェイスを示します。
Rfc インターフェイス (WCF サービス コントラクト)
SAP アダプターは、1 つのサービス コントラクト "Rfc" に基づくすべての RFC 操作を表示します。 つまり、受信するすべての RFC 操作に対して 1 つのインターフェイス Rfc が作成されます。 各ターゲット RFC 操作は、このインターフェイスのメソッドとして表されます。 各メソッドは、操作の要求メッセージのメッセージ コントラクトを表す 1 つのパラメーターを受け取り、操作の応答メッセージのメッセージ コントラクトを表す オブジェクトを返します。
[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);
}
要求メッセージと応答メッセージ
各 RFC 操作は、要求メッセージを表すパラメーターを受け取り、応答メッセージを表す オブジェクトを返します。 要求メッセージのプロパティには、RFC の IMPORT パラメーターと (入力) CHANGING パラメーターが含まれています。 応答メッセージのプロパティには、操作の EXPORT パラメーターと (出力) CHANGING パラメーターが含まれています。
[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;
}
}
生成された WCF サービス
アダプター サービス参照の追加プラグインでは、WCF サービス コントラクト (Rfc) を実装する WCF サービスも生成されます。 このクラスのメソッドはスタブ化されています。 このクラスは、別のファイルで生成されます。 コードは、このクラスの メソッドに直接実装できます。
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.");
}
}
}
RFC サーバー アプリケーションを作成する方法
WCF サービス モデルを使用して SAP システムから RFC を受信するには、「SAP アダプターを使用した WCF サービス モデルの概要」の手順に従います。 サービス エンドポイントを追加するときは、必ずサービス コントラクトに 'Rfc' を指定してください (WCF サービスを作成して実装する手順の手順 6)。
次のコードは、SAP アダプターを使用して SAP システムからZ_RFC_MKD_RFCを受信する方法の完全な例を示しています。 この RFC は、2 つの整数パラメーターを受け取り、結果を 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);
}
}
}
}
}