Neden FTP hâlâ önemli bir entegrasyon aracı

Kafka ve vektör veritabanlarından bahsettiğim yazıdan sonra FTP eski moda görünebilir, ama gerçek ERP projelerinde hâlâ en yaygın entegrasyon yöntemlerinden biri — özellikle banka, e-fatura entegratörü ya da eski (legacy) partner sistemleriyle çalışırken. TROIA, FTP, FTPS ve SFTP protokollerinin üçünü de destekliyor (5.01.04 041203 sonrası build'lerde) ve önemli bir mimari detay: tüm FTP işlemleri application server üzerinde çalışır, istemci tarafı transfer desteklenmiyor.

Bağlantı kurmak

MAKEFTPCONNECTION HOST {host} [PORT {port}] [USERNAME {kullanici}]
    [PASSW {sifre}] [PROTOCOL {FTP|FTPS|SFTP}];

CLOSEFTPCONNECTION {host};

Protokole göre varsayılan portlar: FTP için 21, FTPS için 990, SFTP için 22. Bağlantı zaman aşımı 10 saniye ile sınırlı — bu, yavaş ya da güvenlik duvarı arkasında geciken bir FTP sunucusuna bağlanırken "bağlantı kurulamadı" hatasını açıklayabilecek pratik bir detay.

Çalışma dizini

FTPRUNCOMMAND CURRENTDIRECTORY TO {hedefdegisken} ON {host};
FTPRUNCOMMAND CHANGEDIRECTORY {ftpsunucusundakiyol} ON {host};

Bağlantı kurulduğunda sunucu size varsayılan bir çalışma dizini atıyor; sonraki tüm göreli yol işlemleri bu dizine göre yorumlanıyor.

Dosya indirme ve yükleme

FTPDOWNLOAD {ftpsunucusundakiyol} TO {yerelyol} FROM {host};
FTPUPLOAD {yerelyol} TO {host};

Kritik kısıtlama: Bu yollar istemci tarafı (* önekli) olamaz — hem FTPDOWNLOAD'ın hedefi hem FTPUPLOAD'ın kaynağı sunucu tarafı bir yol olmalı. Yani dosyayı önce application server'a indirip, sonra istemciye ayrıca (COPYFILE gibi bir komutla) taşımanız gerekebilir — FTP komutları tek başına "doğrudan kullanıcının masaüstüne indir" senaryosunu desteklemiyor.

Listeleme ve dizin/dosya yönetimi

FTPRUNCOMMAND FILELIST TO {hedeftablo} ON {host};
FTPRUNCOMMAND CREATEDIRECTORY {yol} ON {host};
FTPRUNCOMMAND DELETEDIRECTORY {yol} ON {host};
FTPRUNCOMMAND DELETEFILE {yol} ON {host};

FILELIST sonucu, troiada-dosya-kopyalama-ve-listeleme yazısındaki yerel FILELIST'e benzer bir tablo yapısı üretiyor — aynı zihinsel modeli, uzak bir sunucuya uyguluyor.

Gerçek bir örnek: banka ekstresini indirip işlenmiş klasöre taşımak

/* Bankanın SFTP sunucusundan günlük ekstre dosyasını indirir. */
LOCAL:
    STRING SUNUCUDAKIYOL;
    STRING YERELYOL;

MAKEFTPCONNECTION HOST 'sftp.banka.com' PORT 22
    USERNAME 'entegrasyon' PASSW 'gizlisifre' PROTOCOL SFTP;

IF SYS_STATUS == 1 THEN
    MESSAGE 'Banka sunucusuna bağlanılamadı: ' + SYS_STATUSERROR TYPE ERROR;
    RETURN;
ENDIF;

FTPRUNCOMMAND CHANGEDIRECTORY '/ekstreler' ON 'sftp.banka.com';

SUNUCUDAKIYOL = 'gunluk_ekstre.txt';
YERELYOL = 'C:\Entegrasyon\Indirilenler\gunluk_ekstre.txt';

FTPDOWNLOAD SUNUCUDAKIYOL TO YERELYOL FROM 'sftp.banka.com';

IF SYS_STATUS == 1 THEN
    MESSAGE 'Dosya indirilemedi.' TYPE ERROR;
ELSE
    FTPRUNCOMMAND DELETEFILE SUNUCUDAKIYOL ON 'sftp.banka.com';
ENDIF;

CLOSEFTPCONNECTION 'sftp.banka.com';

Burada dosyayı indirdikten sonra sunucudan sildim — bu sıralama bilinçli: silme işlemini indirmeden önce yapmak, indirme başarısız olursa dosyayı geri getiremeyeceğiniz bir duruma yol açar.

Sık yapılan hatalar

  • İstemci tarafı yol (* önekli) vermeye çalışmak — FTPDOWNLOAD/FTPUPLOAD'ın kabul etmediği geçersiz yol türlerinden biri tam olarak bu; sunucu tarafı bir ara adım (OPEN FILE/COPYFILE) olmadan doğrudan istemciye indirmek mümkün değil.
  • Bağlantı zaman aşımını (10 saniye) hesaba katmadan yavaş bir hat üzerinden büyük dosya beklemek — bağlantının kendisi 10 saniyede kurulmazsa başarısız olur; bu süre transfer süresi değil, sadece bağlantı kurma süresidir, ama yavaş/aşırı yüklü sunucularda bağlantı adımının kendisi de bu sınıra takılabilir.
  • Silme işlemini indirmeden önce yapmak — yukarıdaki örnekte olduğu gibi, "önce sil sonra indir" sırası, indirme başarısız olduğunda veriyi kalıcı olarak kaybetme riski taşır.
  • Aynı host için birden fazla bağlantı açmayı denemek — belgelerin yaygın hatalar arasında saydığı "duplicate connections" sorunu; bir host için önceki bağlantıyı kapatmadan yenisini açmaya çalışmak hataya yol açabilir.
  • Kimlik bilgilerini kod içine sabit yazmak — production kodunda FTP kullanıcı adı/şifresini doğrudan koda gömmek yerine, 26Domains ya da endpoint tanımlarına benzer şekilde merkezi/güvenli bir konfigürasyon kaynağından okumak daha sürdürülebilir.

Sıradaki adım

Bir sonraki yazıda kalıtımın TROIA'ya özgü ikinci yüzü olan Cross mekanizmasına ve SUPER'e değineceğim.