MicroStrategy Command Manager Script’lerini C# ile Tetiklemek

Merhaba,

Bugün iş hayatımızda sıklıkla başımıza gelebilecek bazı istenmeyen olayları engellemek adına MicroStrategy Command Manager Script’lerini kullanarak nasıl önlem alabileceğimizi anlatmaya çalışacağım. Aslında konuyu bir senaryo üzerinden incelemek daha net anlamamızı sağlayacak.

Gece kaynak sistemden ETL ile SQL tarafına akan günlük satış sipariş verilerimiz var ve ETL tamamlandıktan sonra veri MicroStrategy tarafında Intelligent Cube’lere alınıyor ve gece tüm bu süreç tamamlandıktan sonra sabah 08.30’da üst yönetime MicroStrategy’den günlük satış sipariş verilerini içeren kritik mailler gönderiliyor.

Kritik olan konu burada ne dediğinizi duyar gibiyim. O zaman sorunuza kısaca yanıt verelim. Eğer kaynak sistemden gelen veriler yanlışsa ya da gece sistemlerde bir kesinti yaşanmışsa ve akabinde yönetime eksik veri içeren mailler giderse bununla ilgili sıkıntılar yaşamanız kaçınılmaz olacaktır.

Burada işte yapmamız gereken şey verinin kaynak sistemden yanlış gelip gelmediğini anlamak ve eğer etl job adımlarınızı log tablonuzda tutuyorsanız joblarınızın düzgün çalışıp çalışmadığını loglardan kontrol etmektir.

Teori kısmını geçip hemen işi pratiğe dökelim. Bunun için bir tane C# Console uygulaması yazacağız. Bu uygulama ile hem kaynak sistemden gelen verileri ve hem de bizim ETL joblarımızın doğru çalışıp çalışmadığını log tablosuna bakarak kontrol edeceğiz. Eğer kaynak sistemden gelen verilerde veya joblarımızda bir problem varsa üst yönetime mail gitmeden önce sql tablolarındaki verileri silip MicroStrategy Intelligent küplerini boş olarak güncelleyeceğiz. Böylece küplerin içinde boş veri olduğunda MicroStrategy mail göndermeyecektir. MicroStrategy ayarlarında veri yoksa mail gönderme şeklinde bir seçenek bulunmaktadır. Biz de tam olarak bunu kullanacacağız.

Deliveries – Error Handling

Peki tüm bunları nasıl yapacağız?

Bunun için yemekte (C# Console Application) kullanacağımız malzemeler:

  • 1 Adet MicroStrategy Command Manager Script
  • 1 Adet ETL Log Tablosu
  • 1 Adet Kaynaktan Akan Ham Verinin Tutulduğu Tablo
  • 1 Adet Sunucuda Tanımlı Mail Hesabı

C# uygulamamızda her bir bölümün ne iş yaptığını kod içinde yorumlarda belirttim. Beyninizin yanmasını istemiyorsanız kod içideki yorumları okumanızı şiddetle salık veririm xD

1using System;
2using System.Collections.Generic;
3using System.Data;
4using System.Data.SqlClient;
5using System.Globalization;
6using System.Linq;
7using System.Net.Mail;
8using System.Text;
9 
10namespace SE_DATA_CHECK
11{
12class Program
13{
14static void Main(string[] args)
15{
16try
17{
18//Dünün tarihini DD.MM.YYYY formatında verir.
19string bir_gun_onceki_tarih = DateTime.Now.AddDays(-1).ToShortDateString();
20 
21//Bugünün tarihini DD.MM.YYYY formatında verir.
22string bugunku_log_tarih = DateTime.Now.AddDays(0).ToShortDateString();
23 
24//Bugünkü tarihin gün ismini İngilizce olarak verir.
25string gun = System.DateTime.Now.DayOfWeek.ToString();
26 
27//scp uzantılı dosyamızda bulundan MicroStrategy Command Manager scriptlerimizi çalıştırmak için aşağıdaki yapıyı kullanıyoruz.
28//Bu yapıyı daha sonra cmdmgr.exe üzerinden çalıştırarak scriptlerimiz içinde bulunan trigger'ları tetikleyeceğiz.
29//Trigger'lar da kendilerine bağlı olan MicroStrategy Intelligent Cube'leri çalıştıracak.
30string cmd = "-n \"YOUR_MSTR_SERVER_NAME\" -u YOUR_MSTR_USERNAME -p YOUR_MSTR_PASSWORD -f \"E:\\JOBS\\SE_DATA_CHECK.scp\" -o \"E:\\JOBS\\SE_DATA_CHECK.out\"";
31 
32//Kaynak sistemden bize akan verilerden günlük satış sipariş verilerini alıyoruz.
33DataTable DEGER = GetDataTable("SELECT ISNULL(SUM(ISNULL(Net_Sales, 0)) / 1000,0) AS SALES_DEGER,ISNULL(SUM(ISNULL(Order_Amount, 0)) / 1000,0) AS ORDER_DEGER FROM SATSIP_DAILY WHERE Calendar_Day_DESC='" + bir_gun_onceki_tarih + "'");
34 
35//Bugün içinde oluşan log kayıtlarının sayısını öğreniyoruz. Eğer 8 kayıt oluşmuşsa başarılı demektir.
36//8'in altında bir kayıt varsa job patlamıştır.
37DataTable LOG = GetDataTable("SELECT COUNT(*) AS LOG_DEGER FROM DW_LOG WHERE CONVERT(VARCHAR,LOG_DATE,104)='" + bugunku_log_tarih + "'");
38 
39//Bu kısım cmdmgr.exe (MicroStrategy Commang Manager) uygulamasını Command Prompt üzerinde çalıştırmak için gereklidir.
40System.Diagnostics.Process process = new System.Diagnostics.Process();
41System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
42startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
43startInfo.FileName = "cmdmgr.exe";
44startInfo.Arguments = cmd;
45process.StartInfo = startInfo;
46 
47//Ham verilerin olduğu tablolardan sorguladığımız satış ve sipariş değerlerini double veri tipine,
48//log sayısını ise int veri tipine çeviriyoruz.
49double SALES_DEGER = Convert.ToDouble(DEGER.Rows[0]["SALES_DEGER"]);
50double ORDER_DEGER = Convert.ToDouble(DEGER.Rows[0]["ORDER_DEGER"]);
51int LOG_DEGER = Convert.ToInt32(LOG.Rows[0]["LOG_DEGER"]);
52 
53//Pazartesi dışındaki günlerde BW verileri ve MSTR log kayıtları beraber kontrol ediliyor.
54if (gun != "Monday")
55{
56//Eğer gün içinde oluşan log sayısı 8'den küçükse veya satış değeri 0 ile 1 arasındaysa
57//veya sipariş değeri 0 ile 1 arasındaysa veya satış değeri 0'dan küçükse veya sipariş değeri 0'dan küçükse;
58//MSTR küplerinin baktığı FACT_SATSIP_DAILY tablosundaki verileri sil ve MSTR scriptini process.Start() ile çalıştır.
59//Script MSTR'da tanımlı trigger'ları tetikleyecek ve bu trigger'a bağlı MSTR küpleri de FACT_SATSIP_DAILY tablosu ile boş güncellenecek.
60//Ardından ilgili sistem yöneticilerine bilgilendirme maili gönderilecek.
61//Uygulamayı sonlandır.
62if ((LOG_DEGER < 8) || (SALES_DEGER >= 0 && SALES_DEGER <= 1) || (ORDER_DEGER >= 0 && ORDER_DEGER <= 1) || (SALES_DEGER < 0) || (ORDER_DEGER < 0))
63{
64SqlCommand TruncateCommand = new SqlCommand("TRUNCATE TABLE FACT_SATSIP_DAILY", Connection());
65TruncateCommand.ExecuteNonQuery();
66process.Start();
67SendMail("YOUR_MAIL_ADDRESS""YOUR_MAIL_ADDRESS""YOUR_SUBJECT""YOUR_MESSAGE");
68Environment.Exit(0);
69}
70}
71 
72//Pazartesi günlerinde sadece MSTR log kayıtları kontrol ediliyor.
73else
74{
75//Eğer gün içinde oluşan log sayısı 8'den küçükse;
76//MSTR küplerinin baktığı FACT_SATSIP_DAILY tablosundaki verileri sil ve MSTR scriptini process.Start() ile çalıştır.
77//Script MSTR'da tanımlı trigger'ları tetikleyecek ve bu trigger'a bağlı MSTR küpleri de FACT_SATSIP_DAILY tablosu ile boş güncellenecek.
78//Ardından ilgili sistem yöneticilerine bilgilendirme maili gönderilecek.
79//Uygulamayı sonlandır.
80if (LOG_DEGER < 8)
81{
82SqlCommand TruncateCommand = new SqlCommand("TRUNCATE TABLE FACT_SATSIP_DAILY", Connection());
83TruncateCommand.ExecuteNonQuery();
84process.Start();
85SendMail("YOUR_MAIL_ADDRESS""YOUR_MAIL_ADDRESS""YOUR_SUBJECT""YOUR_MESSAGE");
86Environment.Exit(0);
87}
88}
89}
90 
91//Uygulamamızda herhangi bir hata oluştuğunda yetkili kişiler mail ile bilgilendirilecektir.
92catch (Exception ex)
93{
94SendMail("YOUR_MAIL_ADDRESS""YOUR_MAIL_ADDRESS""YOUR_SUBJECT", ex.Message);
95Environment.Exit(0);
96}
97 
98//Uygulama başarıyla çalışsa bile yetkili kişiler mail ile bilgilendirilecektir.
99finally
100{
101SendMail("YOUR_MAIL_ADDRESS""YOUR_MAIL_ADDRESS""YOUR_SUBJECT""YOUR_MESSAGE");
102Environment.Exit(0);
103}
104}
105 
106//SQL Server tanımlarımızı burada yapıyoruz.
107//Bu fonksiyon bizi ilgili SQL Server sunucusuna bağlayacak ve erişim izni sağlayacaktır.
108public static SqlConnection Connection()
109{
110SqlConnection con = new SqlConnection(@"Server=SQL_ADDRESS; Database=DB_NAME; User ID=SQL_USERNAME; Password=SQL_PASSWORD; Connection Timeout=0; Max Pool Size=500");
111con.Open();
112return con;
113}
114 
115//GetDataTable fonksiyonumuza bir sql query yolladığımızda sonucu bize datatable olarak dönüyor.
116//Sonrasında datatable'dan aldığımız sonuçla istediğimiz gibi oynayabiliriz.
117public static DataTable GetDataTable(string sql)
118{
119DataTable dt = new DataTable();
120 
121SqlDataAdapter da = new SqlDataAdapter(sql, Connection());
122da.Fill(dt);
123Connection().Close();
124da.Dispose();
125 
126return dt;
127}
128 
129//Mail göndermek için aşağıdaki SendMail fonksiyonunu kullanıyoruz.
130//Bu fonksiyonun aldığı değerler kimden,kime,konu,mesaj.
131//Eğer kendi ağınızda kullanacaksınız SMTP adresini girmeniz yeterli olacaktır.
132//Mail göndermeye yetkiniz yoksa IT ekibinizden yetki almanız gerekebilir.
133public static void SendMail(string from, string to, string subject, string message)
134{
135MailMessage mail = new MailMessage();
136mail.From = new MailAddress(from);
137mail.To.Add(to);
138mail.Subject = subject;
139string link = @"<img />";
140mail.Body = @";Sayın Yetkili,
141 
142" + message + "
143 
144Bilginize,
145 
146" + link + "
147 
148----------------------------------------------------
149Bu e-posta mesaji ve ekleri sadece gonderildigi kisi veya kuruma ozeldir.
150Dogru aliciya ulasmamis olmasi halinde, bu mesajin baska bir aliciya yonlendirilmesi, kopyalanmasi veya kullanilmasi yasaktir.
151----------------------------------------------------
152This e-mail and any attachments transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed.
153If you are not the intended recipient you are hereby notified that any forwarding, copying or use of the information is prohibited.</font>";
154mail.IsBodyHtml = true;
155SmtpClient client = new SmtpClient("YOUR_SMTP_ADDRESS");
156client.Send(mail);
157}
158}
159}

Bu kodla hem sql’e sorgu atabilecek hem de gelen sonuçlara göre belli koşullarda MicroStrategy Command Manager scriptlerinizi çalıştırabileceksiniz.

Siz burada if koşullarını istediğiniz gibi kendinize göre özelleştirebilirsiniz.

Bu kodu T-SQL ile de yazabilirdik ancak SQL Server ile MicroStrategy Command Manager aynı sunucu üzerinde bulunmak zorunda olduklarından böyle yapmadık.

Bu senaryoda SQL Server ve MicroStrategy farklı sunucularda olduğundan C# Console uygulaması yazmayı tercih ettik.

Kodunuzu Visual Studio’da hatasız bir şekilde derledikten sonra Görev Zamanlayıcı’sında günlük görevler oluşturabilirsiniz.

Görev Zamanlayıcısı

Özetle yukarıdaki koşullarınıza göre herhangi bir sorun oluştuğunda MSTR küpleri boş olarak güncelleyecek ve üst yönetime mail göndermeyecektir.

Yazan: Onur YURTSEVER (Eczacıbaşı Bilişim)