Küçük bir proje için Biztalk Server ile çalışmam, Biztalk Server üzerinde “Suspend” olarak takılmış mesajları görüntüleyip bunları tekrar “Resume” etmem gerekti. Bütün bu işleri Biztal Server’ın Administration arayüzleri ile yapabiliyoruz tabi ki ama proje kapsamı bunları farklı bir uygulamadan yönetebilmekti. WMI kullanarak, kısaca nasıl Biztalk üzerinde bu tür işlemlerin yapabileceğimizi paylaşmaya çalışacağım. Biztalk ve WMI ile ilgili tecrübesi olmayanlar için pek bir şey ifade etmeyecektir belki ama çok fazla Türkçe kaynak bulunmadığından bu konu ile ilgili paylaşmak istedim…O zaman hemen başlıyalım. (:
Öncelikle çok basit konsol uygulaması olacak yapacağımız şey örnek olması adına. WMI arayüzünden, ulaşabileceğimiz özellikler için .NET Framework içerisinde ki System.Management namespace’inden ManagementScope, ObjectQuery ve ManagementObjectSearcher sınıflarını kullanıyor olacağız.
ManagementScope sınıfı için, WMI’da hangi arayüze bağlanacağımızı belirttiğimiz yönetim kapsamını belirleyen sınıf diyebiliriz. WMI’da, Biztalk ile ilgili yönetimsel özeliklere bağlanıyor olduğumuzu bu sınıf ile belirtiyoruz.
ObjectQuery ile WMI üzerindeki sorgularımızı tanımlıyoruz. WQL diye adlandırılan, T-SQL’e benzeyen bu sorgularımız sonucunda ki bilgilere göre işlemlerimizi gerçekleştireceğiz.
ManagementObjectSearcher sınıfı ile de, oluşturduğumuz WQL sorgularını çalıştırabiliyoruz. Çalıştırdığımız sorgular bize WMI üzerinden, belirtmiş olduğumuz namespace’ler üzerindeki bilgileri getiriyor olacaktır.
Aşağıdaki kod örneğinde Biztalk’un namespace’ine bağlanıp, “Suspend” olmuş mesajları alıyoruz.
ManagementScope scope = new ManagementScope(@"\\192.168.111.75\root\MicrosoftBizTalkServer"); scope.Connect(); ObjectQuery query = new ObjectQuery("SELECT * FROM MSBTS_MessageInstance WHERE ServiceInstanceStatus=4 "); ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); ManagementObjectCollection queryCollection = searcher.Get();
searcher nesnesinin Get() metodu ile ManagementObject tipinde elemanları olan bir koleksiyon alıyoruz. Bu koleksiyon içerisinde WMI’ya yapmış olduğumuz sorgunun sonuçları, yani Biztalk’da “Suspend”de kalmış mesajları alıyor olacağız. ManagementObject tipindeki elemanlar üzerinden, Biztalk’da ki mesajların bilgilerine ulaşabiliriz. Ancak .NET Framework’ün ve Visual Studio’nun sağladığı bazı avantajları kullanarak, biraz daha OOP yaklaşımında, Biztalk mesajlarının nesnelerini oluşturup, işlerimizi kolaylaştırabiliyoruz.
Visual Studio‘da bildiğiniz üzere, Server Explorer diye alt bir pencere mevcut. Belirtmiş olduğumuz bilgisayara bağlanıp çeşitli özelliklere ve bilgilere ulaşabiliyoruz. WMI üzerindeki “class”lar da bunlardan biri. Eklemiş olduğumuz bilgisayarın bu WMI namespace’lerinde ki sınıflarına , “Management Classes” altındaki elemanlardan ulaşabiliriz.
Ancak ilk bakışta burada Biztalk ile ilgili herhangi bir sınıf göremiyor olacağız. Bunun için “Management Classes” üzerine sağ tıklayıp, “Add Classes…” dememiz gerekmekte. Karşımıza çıkan ekrandan “Find class containing” kısmına bağlanacağımız Biztalk makinasının adresi ve WMI namespace’ini yazmamız gerekmekte.(Ör: \\192.168.1.2\root\MicrosoftBizTalkServer) Yazıp “Find Next” dediğimiz da sol tarafdaki listeye Biztalk ile ilgili namespace’ler ekleniyor olacaktır, bunları seçip sağ tarafa “Add” diyip ekledikten sonra, artık “Management Classes” altında Biztalk ile ilgili WMI bilgilerini görebiliriz.
Daha kolay kod yazabilmek için bu bilgilerden .NET Framework için managed kodları oluşturmamız lazım. Bunun için “Managed Classes” altından hangi eleman bizim işimiz için gerekliyse, sağ tıklayıp “Generate Managed Class” dememiz gerekiyor. Bu örnekte MSBTS_MessageInstance‘ın üzerine sağ tıklayıp, “Generate Managed Class” diyoruz…Artık Biztalk tarafında ki mesajları temsil eden, MessageInstance sınıfımız projemiz dahilinde bizi bekliyor.
Şimdi tek yapmamız gereken WMI bilgisini bu sınıfımıza dönüştürüp, ilgili nesneleri yaratıp ilgili kontrolleri yapmak. İlla bu oluşturduğumuz sınıfa dönüştürmemize, hatta bu sınıfı yaratmamıza gerek yok. Ama bu şekilde, tanımlı sınıf ve özellikler ile yazacağımız kod daha sağlıklı olacaktır.
foreach (ManagementObject m in queryCollection) { //ManagementObject tipinde ki koleksiyon elemanımızı, yarattığımız MessageInstance nesnesine //yapıcı metod ile çeviriyoruz. ROOT.MICROSOFTBIZTALKSERVER.MessageInstance instance = new ROOT.MICROSOFTBIZTALKSERVER.MessageInstance(m); //Artık Biztalk tarafında Suspend olmuş mesajımız nesne olarak elimizde. Bu mesajın //çeşitli özelliklerine çok rahat bir şekilde ulaşabiliriz. GUID tipinde olan //MessageInstanceID'yi bu örnekte yazdırıyoruz. Console.WriteLine("Message with ID " + instance.MessageInstanceID + " is suspended"); //Suspend olmuş mesajların, neden Suspend olduğunu anlamak için, bu mesajın servisine //mesajın ServiceInstanceID'si ile bir sorgu yapıyoruz query = new ObjectQuery("SELECT * FROM MSBTS_ServiceInstance WHERE InstanceID='"+instance.ServiceInstanceID+"'"); searcher = new ManagementObjectSearcher(scope, query); queryCollection = searcher.Get(); //Önceki benzer şekilde yaptığımız sorgunun sonuçları alıyoruz foreach (ManagementObject item in queryCollection) { //Mesajların bağlı olduğu ServiceInstance'ları ManagementObject nesnesinden yaratıyoruz. //ServiceInstance tipindeki bu yeni nesnemiz ile artık mesajların neden Suspend olduğu bilgisine ulaşabilirz. ROOT.MICROSOFTBIZTALKSERVER.ServiceInstance s = new ROOT.MICROSOFTBIZTALKSERVER.ServiceInstance(item); Console.WriteLine(s.ErrorDescription); }
Kısaca özetlemek gerekirse, Biztalk tarafında “Suspend” durumunda ki mesajları alıp, daha sonra bu mesajların daha ayrıntı bilgilerine ulaşmak için onların Service Instance‘larında ki bilgilerine ulaşmak için WMI’yı kullanmış olduk. İlk başta biraz karmaşık gelebilir ama kullanmaya başladıkça aslında o kadar da karışık olmadığının farkına varıyor olacaksınız.
WMI ile ilgili daha fazla ve farklı konuya ilerleyen yazılarda değinmeye çalışacağım. Şimdilik bu kadar…Bu arada “Suspend” olmuş mesajları, “Resume” etmeyi de size bırakıyorum… (: