C# ve SAP RFC Entegrasyonu

Esse dolorum voluptatum ullam est sint nemo et est ipsa porro placeat quibusdam quia assumenda numquam molestias.

SAP ve .NET Core Entegrasyonu

.NET Core ve SAP RFC Entegrasyon Mimarisi ve Kod Rehberi

  • AkyuzSoft Ar-Ge
  • Teknik Otorite, SAP

SAP ERP sistemleriyle harici uygulamaların entegrasyonu, özellikle kurumsal süreç otomasyonlarında hayati bir öneme sahiptir. Bu makalede, .NET Core ve modern C# yapılarını kullanarak SAP sistemleriyle RFC (Remote Function Call) ve BAPI üzerinden nasıl güvenli ve yüksek performanslı bağlantılar kurabileceğinizi derinlemesine inceleyeceğiz.

SAP entegrasyonlarında en çok yapılan hata, bağlantı havuzlarının (connection pool) düzgün yönetilmemesidir. Bu durum sunucuda port tükenmesine (socket exhaustion) ve SAP sunucusunda bağlantı patlamalarına (connection overflow) yol açar. AkyuzSoft olarak, kurumsal projelerimizde bu entegrasyonları kurarken SAP'nin resmi SAP Connector for .NET (NCo 3.0) kütüphanesini ve dinamik bağlantı yöneticilerini tercih ediyoruz.

SAP NCo 3.0 Kurulumu ve Mimarisi

SAP Connector, SAP sistemleriyle güvenli ağ bağlantıları (SNC), RFC çağrıları ve XML tabanlı SOAP servis entegrasyonları için gerekli temel kütüphaneleri barındırır. Bu kütüphaneler resmi olarak NuGet üzerinden dağıtılmadığı için SAP Support Portal (Service Marketplace) üzerinden indirilerek projenizin işletim sistemi mimarisine göre (genelde x64) doğrudan dll referansı olarak eklenmelidir.

Kritik Uyarı: SAP NCo 3.0 kütüphanesinin düzgün çalışabilmesi için uygulamanızın koştuğu sunucuda Microsoft Visual C++ Redistributable paketlerinin yüklü olması şarttır.

C# ile Bağlantı Yönetimi ve Connection Pool Kurulumu

SAP NCo kütüphanesinde bağlantıları yapılandırmak için IDestinationConfiguration arayüzünü implemente etmemiz gerekir. Bu yapı, bağlantı parametrelerini bir dosyadan, veritabanından ya da çevre değişkenlerinden (environment variables) güvenli bir şekilde okuyarak SAP bağlantı yöneticisine sunar.

Aşağıda, 10 adet hazır bağlantı içeren (Pool Size: 10) ve 10 dakika boyunca boşta kalan bağlantıları otomatik sonlandıran yüksek performanslı bir bağlantı havuzu yapılandırma örneği yer almaktadır:

using System;
using System.Collections.Generic;
using SAP.Middleware.Connector;

namespace AkyuzSoft.SapIntegration
{
    // 1. SAP Bağlantı Konfigürasyon Sağlayıcısı
    public class SapDestinationConfig : IDestinationConfiguration
    {
        private readonly Dictionary<string, RfcConfigParameters> _destinations = new();

        public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;

        public RfcConfigParameters GetParameters(string destinationName)
        {
            if (_destinations.TryGetValue(destinationName, out var parameters))
            {
                return parameters;
            }
            return null;
        }

        public bool ChangeEventsSupported() => false;

        public void AddOrUpdateDestination(string name, string host, string sysNr, string client, string user, string password)
        {
            var parms = new RfcConfigParameters
            {
                { RfcConfigParameters.Name, name },
                { RfcConfigParameters.AppServerHost, host },
                { RfcConfigParameters.SystemNumber, sysNr },
                { RfcConfigParameters.Client, client },
                { RfcConfigParameters.User, user },
                { RfcConfigParameters.Password, password },
                { RfcConfigParameters.Language, "TR" },
                { RfcConfigParameters.PoolSize, "10" }, // Bağlantı havuzu boyutu
                { RfcConfigParameters.PeakLimit, "30" }, // Maksimum eşzamanlı bağlantı sınırı
                { RfcConfigParameters.IdleTimeout, "600" } // 10 dakika boşta kalma süresi (sn)
            };
            _destinations[name] = parms;
        }
    }
}

C# Üzerinden SAP BAPI Çağrısı Gerçekleştirme

Havuzu ayağa kaldırdıktan sonra, RfcDestinationManager üzerinden bağlantı nesnemizi havuza alabilir ve istediğimiz BAPI fonksiyonunu çağırabiliriz. Aşağıdaki örnekte, SAP üzerindeki bir malzemenin anlık stok durumunu sorgulayan BAPI_MATERIAL_AVAILABILITY fonksiyonunun C# ile nasıl çağrıldığı gösterilmiştir:

    // 2. RFC Servis Katmanı
    public class SapRfcService
    {
        public void ExecuteRfcCall()
        {
            try
            {
                // Konfigürasyonu SAP Manager'a kaydet (Singleton olmalı)
                var config = new SapDestinationConfig();
                config.AddOrUpdateDestination("SAP_PROD", "192.168.1.50", "00", "800", "AKYUZSOFT_API", "SecurePass123!");
                
                if (!RfcDestinationManager.IsDestinationConfigurationRegistered())
                {
                    RfcDestinationManager.RegisterDestinationConfiguration(config);
                }

                // Bağlantıyı Havuzdan Al
                RfcDestination destination = RfcDestinationManager.GetDestination("SAP_PROD");
                RfcRepository repository = destination.Repository;

                // Örnek RFC / BAPI fonksiyonunu yükle (Örn: Malzeme Stoğu Okuma)
                IRfcFunction function = repository.CreateFunction("BAPI_MATERIAL_AVAILABILITY");

                // Input Parametrelerini Ayarla
                function.SetValue("MATERIAL", "MAT-00912");
                function.SetValue("PLANT", "1000");
                function.SetValue("UNIT", "PC");

                // Fonksiyonu SAP Üzerinde Çalıştır
                function.Invoke(destination);

                // Output Parametrelerini Al
                string avStock = function.GetString("AV_QTY_PLT");
                Console.WriteLine($"SAP Mevcut Stok: {avStock}");
            }
            catch (RfcBaseException ex)
            {
                // SAP RFC Hata Yönetimi
                Console.WriteLine($"SAP Bağlantı Hatası: {ex.Message} (Hata Kodu: {ex.ErrorCode})");
            }
        }
    }

Yukarıdaki yapıda kütüphane bağlantıyı RfcDestinationManager havuzundan otomatik çeker ve işlem tamamlandığında sızıntı yapmadan havuza kendiliğinden iade eder. C# kodlarında herhangi bir Close() veya Dispose() işlemine gerek kalmaz.

AkyuzSoft Teknik Önerisi

Üretim tesislerinde veya B2B e-ticaret sitelerinde anlık stok ve fiyat sorgulamaları yaparken, her istekte SAP'ye gitmek yerine anlık değişmeyen stok kalemleri için web servis seviyesinde Memory Cache (Önbellekleme) mekanizması kurmanızı öneririz. Bu, SAP lisans maliyetlerinizi düşürür ve web sitenizin yanıt süresini 100 kat hızlandırır.

SAP Entegrasyonlarında Sık Yaşanan Hatalar ve Çözümleri

1. RFC_ERROR_SYSTEM_FAILURE (No memory available): SAP sunucusunda belleğin yetersiz kaldığını gösterir. Çözüm için SAP tarafında RFC parametre ayarlarında (rdisp/max_wprun_time) zaman aşımı limiti optimize edilmeli ve .NET tarafında gereksiz büyük tabloları tek seferde sorgulamaktan kaçınılmalıdır.

2. Connection pool is full: .NET uygulamasında bağlantıların serbest bırakılmamasından kaynaklanır. RfcDestinationManager haricinde manuel new RfcDestination tanımlamaları yapmaktan kaçının.