daron yöndem | Microsoft Regional Director | Silverlight MVP
Microsoft Regional Director | Nokia Developer Champion | Azure MVP

Bundan yaklaşık iki sene önce Azure Drives ile ilgili bir yazı yazmıştım. Özellikle migration veya on-prem (şirket içi) legacy uygulamalar, sistemlerle cloud ortamındaki yapıları konuşturmak için kullanılabilecek bir alt yapıydı Azure Drive. Neden geçmiş zamanlı konuşuyorum? Çünkü Azure Drive hizmeti 2015 yılı içerisinde sonlandırılacak ve onun yerine şu anda Preview olan Azure Files gelecek. Durum bu olunca ben de erkenden Azure Files ile ilgili bir yazı yazarak hem ne nedir sorusunu biraz cevaplayalım, hem de Azure Drive kullandığınız yerleri nasıl Azure Files'a geçirirsiniz göz atalım istedim.

Azure Drives servisi normal Storage Account'lar üzerinden veriliyor. Hizmet şu anda Preview olduğu için ilk olarak Preview hizmetler sayfasından aktif hale getirmeniz gerekecek. Hizmeti aktif hale getirdikten sonra yeni bir Storage Account yaratmanız gerekiyor. Eski hesaplara şu an için Azure Files otomatik olarak eklenmiyor.

Nasıl kullanılır?

Azure Files esasen SMB 2.1 destekleyen bir Folder Share. Yani bildiğimiz Folder Share. Azure Drive kullananlar hatırlayacaktır; Azure Drive yazma-okuma anlamında sadece bir instance/VM'e ataçlanabiliyordu. Bu durum Azure Files'da böyle değil :) İstediğiniz kadar makineye, instance'a ataçlayabilirsiniz Folder Share'leri. Azure Drive ile en büyük farklılıklarından biri zaten bu SMB 2.1 desteği. Bu protokol desteği Azure Drive'ın ITPro'lar tarafından da rahatlıkla kullanılmasını sağlıyor. Karşılaştıracak olursak Azure Drive aslında sadece developerlara hitap eden bir araç olarak kalmıştı ve özünde çözmeye çalıştığı sorunlar düşünüldüğünde ITPro'lar tarafından kullanılamıyor olması aslında çok da akıllıca değildi. Azure Files ile bu sorun çözülürken bu sefer de aklınıza, "Tamam da ben developer olarak REST isterim!" haykırışı gelebilir :) Merak etmeyin, o da var. Zaten benim de odaklanacağım taraf o olarak. ITPro tarafına bulaşma niyetim yok :)

REST API'lar üzerinden Azure Files'a ulaşmak için Storage Client'ın 4.0 ve üstü sürümlerinden birini kullanmanız gerekiyor. Ben bu yazıyı yazarken Storage Account kütüphanesi zaten 4.2 sürümünde.  Gelin ufak bir proje yaratıp Nuget paketini ekleyelim bakalım neler yapabiliyoruz.

[C#]

CloudStorageAccount account = CloudStorageAccount.Parse(this.connString);
CloudFileClient client = account.CreateCloudFileClient();
CloudFileShare share = client.GetShareReference("birklasor");
share.CreateIfNotExistsAsync().Wait();

Storage Account'larla çalışanlar için yukarıdaki kod süper tanıdık gözükecektir. Her zamanki StorageAccount objesi üzerinden normal Blob, Table, Queue ile çalıştığımız zamanlardaki gibi bu sefer de CloudFileClient alıyoruz. Bu client üzerinden var olan veya olmayan bir ShareFolder'ın ismini verip referansını aldıktan sonra IfNotExist ile Share Folder'ı oluşturuyoruz. Hepsi bu kadar aslında. REST üzerinden Folder Share'i yaratmış olduk.

Azure Files Storage Account Endpoint'lerinden biri.
Azure Files Storage Account Endpoint'lerinden biri.

Şimdi bu noktada birkaç uyarıda bulunmam gerek ve bunlar maalesef can sıkıcı olacak. İlk olarak şu anda maalesef Azure Files desteği local Storage Emülatöründe yok. O nedenle herşeyi Cloud ortamına karşı çalıştırmak zorundasınız. Bir diğer sıkıntı ise SMB desteğinin sadece storage accountun bulunduğu bölgede (region) verilmesi. Yani başka bir datacenterdaki VM'i alıp da storage accounttaki Folder Share'i bağlayamazsınız. Bu durum local bilgisayarınız için de geçerli :( Yani yukarıdaki kod REST üzerinden gittiği için bilgisayarınızdan çalıştırdığınızda sıkıntı olmayacaktır ama gidip de bu Folder Share'i kendi bilgisayarınız map etmeye kalkarsanız maalesef sonuç hüsran olacak. İşin o kısmını test etmek için benim tavsiyem Storage Account ile aynı Region'da Visual Studio yüklü bir VM provision etmeniz. İtiraf etmek gerekirse dev/testing açısından bu durum biraz kötü. En azından local emülatör desteği gelirse süper olacak.

Azure Files Folder Share VM'e maplendi.
Azure Files Folder Share VM'e maplendi.

Kod ile REST üzerinden Folder Share'i oluşturduktan sonra hemen test için bir console açıp "net use" ile yukarıdaki ekran görüntüsünde de görebileceğiniz üzere share'i VM'e mapledim. Böylece Azure Files üzerinde bir Folder Share'imiz var artık. Buraya atılan tüm dosyalar, dosya sistemi artık hem SMB hem de REST üzerinden ulaşılabilir durumda. Test sonrası "net use z: /delete" ile mapi kaldırabilirsiniz.

Web ve Worker Role'dan kullanımı?

Aslında yukarıdaki taktikten yola çıkarsak ne yapacağımı tahmin edebilirsiniz sanırım. Net Use'ü doğrudan process olarak çalıştırarak map işlemini Web veya Worker role içerisinde de yapabiliriz. Burada önemli olan nokta WebRole.cs'teki RoleStart'ta yapmamak. Aslında bu genel bir kural değil. Esas sorun Role'ünüz security context'ini elevated hale getirirseniz ortaya çıkıyor. Malum Folder Share Map'leri söz konusu user context içerisinde çalışıyor. RoleEnvironment ile Application farklı security contextlerde çalışırsa doğal olarak birbirlerinin oluşturduğu mapleri göremeyeceklerdir. Eğer Role'ün security contexti yükseltirseniz Role System hesabı ile çalışırken uygulamanız varsayılan kullanıcı hesap ile çalışır. Unutmayan Role WaIISHost.Exe tarafından host edilirken uygulama w3wp.exe tarafından host ediliyor. Bu gibi durumları engellemek için en iyisi mapleme işlemini uygulama içerisinde yapmak. Eğer her iki tarafta da diske ihtiyacınız varsa hem Role Start hem de App Start'da mapleme yapmanız şart.

[C#]

Process p = new Process();
int exitCode;
p.StartInfo.FileName = "net.exe";
p.StartInfo.Arguments = "use z: \\azurefilesdarontest.file.core.windows.net\birklasor 
                                        /u:azurefilesdarontest HhAItw2Q=="
;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.Start();
string error = p.StandardError.ReadToEnd();
p.WaitForExit(20000);
exitCode = p.ExitCode;
p.Close();

using (StreamWriter outfile = new StreamWriter(@"Z:\deneme.txt"))
{
    outfile.Write("Merhaba Dünya!");
}

Map işlemi bittikten sonra gördüğünüz üzere normal System.IO altındaki her şeyi bu diskte kullanabiliyorum. Artık birden çok instance, role tarafından erişilebilecek bir folder share'imiz var :) Süper! Örneğin bu diski IAAS tarafından alınmış bir VM'e mapleyip, PAAS tarafındaki role instancelarınıza da mapleyip IAAS ortamına kurulu stand-alone bir uygulama ile PAAS taki uygulamanızın birbiri ile basit bir folder share üzerinden konuşmasını sağlayabilirsiniz. Bu senaryo özellikle kodu ve mimarisi sizin yönetiminizde olmayan uygulamalarla entegrasyon için çok anlamlı olabiliyor.

REST üzerinden disk erişimi

SMB haricinde REST desteğinin de olduğundan bahsetmiştik fakat bu noktaya kadar REST üzerinden Share Folder yaratmak dışında bir şey yapmadık. REST üzerinden doğrudak diskteki tüm dosya ve klasörlere full erişim hakkınız da var. Bu seçenek özellikle uygulamanız ayrı bölge (region) içerisinde değilse süper işe yarayacaktır. Malum SMB için aynı region içerisinde olmanız şart.

[C#]

CloudStorageAccount account = CloudStorageAccount.Parse(this.connString);
CloudFileClient client = account.CreateCloudFileClient();
CloudFileShare share = client.GetShareReference("birklasor");
CloudFileDirectory rootDirectory = share.GetRootDirectoryReference();
CloudFile aCloudFile = rootDirectory.GetFileReference("deneme.txt");
Response.Write(aCloudFile.DownloadText());

Yukarıdaki kod içerisinde CloudFileShare'den root klasörü istedikten sonra artık iş CloudFileDirectory ve CloudFile objeleri ile çalışmaya kalıyor. Tüm buradaki objeler üzerinde yaptığınız işlemler doğrudan REST API'lar üzerinden gerçekleştiriliyor. O nedenle bu şekilde Azure Files'a erişen bir uygulamanınz SMB protokolüne bağımlılığı yok.

Blob mu File Share mi?

İtiraf etmem gerek eğer bu soruyu soruyorsanız kafanız epey karışmış demektir :) Ama bu çok da normal. Birincisi Azure Files'da SMB var. Bu aslında servisin çözmeye çalıştığı sorun adına çok şey anlatıyor. Buradaki amaç sadece bir storage sistemi sağlamak değil, hatta storage sistemi sağlamak da değil. Buradaki amaç Bloblar gibi inanılmaz ölçeklenebilirliliğe sahip storage yapılarını kullanamayan, migrate edilemeyen senaryolarda bir çözüm sunabilmek. Daha açıkçası, uygulamaların Cloud'a taşınmasını kolaylaştırmak ve (IAAS/PAAS) hybrid uygulama yapılarını kolaylaştırmak. Teknik karşılaştırma isterseniz eğer; bloblarda bir container 500TB olabilirken burada bir Share azami 5TB olabiliyor. Erişim olarak 60MBps storage'da blob başına gelirken Azure Files'da Share başına geliyor. Diğer yandan bloblarda esasen Directory diye bir konsept yokken burada var. Bloblarda isimler büyük, küçük harf duyarlıyken burada değil. Bloblarda snapshow var, burada yok :) Son olarak bloblarda byte başına para ödeniyor burada toplam size için.

Azure Disk ile Azure Files farkı nedir?

Azure Disk'i hatırlamayanlar için hemen ip ucu veriyim; bir VM yarattığınızda ona ataçladığınız disk bir Azure Disk. Azure Disk'ler tek bir VM tarafından kullanılabiliyorlar. Azure Files ile en büyük farklılıkları aslında bu. Diğer yandan REST üzerinden erişim şansınız da yok ama Azure Disk'ler aslında Blob'lar üzerinde yaşadığı için Snapshot özelliği var. Azure Disk'lerde en büyük disk boyutu 1TB, Azure Files'da Share boyutu 5TB. Veri erişimi hızı aynı olsa da 8KB IOps'da Azure Disk 500 verirken Azure Files 1000 veriyor.

Son olarak, yukarıdaki kodları hemen alıp test etmek isterseniz makaleyi yazarken kullandığım test kodlarını Github'a attım.

Görüşmek üzere.

Azure Mobile Services konusunda bundan önce sizlerle bazı videolar paylaştım, webcastler yaptık ama itiraf etmek gerekirse Azure Mobile Services kullanımını pek de Mobile dışında düşünmedik. Zaten aslına bakarsanız Microsoft da böyle düşünmüyor :) Fakat ürünün ismini bir kenara koyar ve ne yaptığına bakarsak kaba tabiri ile bize REST üzerinde basit ve hızlı olarak data erişimi sağlıyor. Tabi ki data erişimi dışında Mobile Services'da daha bir çok component var ama dedim ya, kaba bir şekilde ürünün olayı bu. Bu noktaya kadar aynı fikirdeysek şimdi geçelim hikayenin diğer açısına.

Geçenlerde bir web sitesi projesi ile ilgili düşünürken sitenin tüm veri erişimini REST üzerinden bir API set ile tasarlamaya karar verdim. Genelde bu gibi mimari tasarımları pek sevmem. Neden mi? Siteye giren ziyaretçinin ilk yaptığı request ile ona ihtiyacı olan veriyi yollamak yerine ihtiyacı olan veriyi alabileceği bir uygulama yolluyor olmak ve sonrasında ikinci, üçüncü HTTP talepleri ile esas ziyaretçinin görmek istediği şeyi vermek bence kullanıcı deneyimi açısından inanılmaz anlamsız ve saçma. Böyle projelerde bulundum :), gördüm, saçma. Yanlış olmasın, özellikle bahsettiğim saçmalık daha ilk sayfa açıldığında yüklenecek verinin sonradan async API call ile yüklenmesi. Bu durum özünde bir "mimari moloz sendromu" :) Ah şu "Mimari Moloz Sendormu" yazısını yazmış olsaydım link verirdim şimdi. Neyse, kısmet :) Konumuza dönersek, peki ben neden bu bahsettiğim web projesinde işleri böyle yapiyim dedim? Aslında nedeni çok da önemli değil çünkü konumuz o değil ama kabaca anlatmak gerekirse söz konusu web sitesinin full HTML olması gerekiyordu :) Dedim ya, uzun hikaye.

Yani?

Şimdi geleceğim nokta şudur ki, tüm veri kaynağını vs REST üzerinden siteye beslemeye karar verince bir baktım normal bir asp.net projesinden daha kompleks (doğal olarak) istemci-sunucu kafasında bir yapı nedeniyle iş yükü gereksiz artıyor. API yaz, tüket vs... ohooo yapacağımız bir web sitesi zaten ve malum HTML'den öteye bile geçemiyor. İşte o anda aklıma aslında tam da bu işleri çözen yani otomatik olarak API açan ve üzerinden veri erişimi vs sağlayan Mobile Services geldi. Dedim ya normalde Mobile Services mobil uygulamalar için tasarlanmış bir yapı ama sonuç itibari ile bu Mobile Services HTML5 ile programlanan Windows8 Tablet uygulamalarında da kullanılabiliyor ve tam da bu nedenle bir JavaScript SDK'yi var!! İşte bu!

Service erişimi anahtarı... Hmm...

Hayalimde taşlar çok güzel yerli yerine oturuyordu ki hemen aklıma Mobile Services endpoint erişimi için kullandığımız management key'ler geldi. O key'leri normal şartlarda biz mobil uygulamanın içine gömüyoruz ve doğrudan erişilemiyor. En azından kolay yoldan erişilemiyor diyelim. Bir web sitesi üzerinden Mobile Services kullandığımızda ise söz konusu key/anahtar apaçık JavaScript kodunun içerisinde durmak zorunda. Bir an hayallerim söndü. Sonra bir silkelendim :) Azure Mobile Services ile daha önce ilgilenenler hatırlayacaktır her entity set, table için permission / izinler ayarlayabiliyoruz. O ayarlar listesinde "Everyone" diye bir seçenek var :) O seçeneği kullanmak mobil uygulama geliştirirken pek de aklımıza gelmiyor çünkü zaten key'i uygulamanın içine gömüyoruz ve her tür erişimi "key ile erişilebilir" diye ayarlıyoruz. Oysa web ortamında "Everyone" olarak ayarlı bir tablo çok daha işimizi görebilir ve keyi alenen paylaşmaktan kurtuluruz. Tabi bu noktada aklınıza "Key yok herkes erişecek aman Allah'ım" gibi korku cümleleri gelebilir :) Tamam da zaten REST API değil de normal web sitesi üzerinden HTML ile sunsaydık veriyi herkes erişemeyecek miydi? Pelki REST olduğu için :) otomatik kötüye kullanımı bilenler için kolaylaştırmış oluyoruz fakat konsept olarak herkesin ulaşmasını istediğiniz veriyi ne formatta açacaksanız açın sonuç itibari ile herkese açacaksınız :) "Everyone" candır diyerek devam edelim. Böylece "key"i JavaScript'in içinde bulundurmaktan kurtulduk.

<script src='//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>
<script src='http://ajax.aspnetcdn.com/ajax/mobileservices/MobileServices.Web-1.1.0.min.js'></script>

<script type="text/javascript">
   
    var client = new WindowsAzure.MobileServiceClient('https://darondeneme.azure-mobile.net/');
    todoItemTable = client.getTable('todoitem');
    var sorgu = todoItemTable.where({ complete: false });

    sorgu.read().then(function (todoItems) {
        for (var i = 0; i < todoItems.length; i++) {
            alert(todoItems[i].text)
        };
    }, hataolursa);

    function hataolursa(hata) {
        var text = hata + (hata.request ? ' - ' + hata.request.status : '');
        alert(text);
    }
</script>

Yukarıdaki kod süper basit bir şekilde Azure Mobile Services SDK ile beraber gelen Windows 8 HTML5 örneklerinden çırptığım bir kod :) MobileServices Client'ı oluştururken key vermek için kullanılan ikinci parametreyi tamamen sildim. "todoItem" adındaki mobile services varsayılan örneği ile gelen tabloya da "Everyone" okuma izni verdim.

Herkese okuma izni verdik.
Herkese okuma izni verdik.

İşte bu kadar :) artık Azure Mobile Services SDK içerisindeki Windows 8 HTML uygulama geliştirmek için yer alan tüm kaynakları kullanabilir, tüm JavaScript SDK'yi kullanabilir ve her türlü veri erişimizi Mobile Services üzerinden yapabilirsiniz. Özetle web sitenizin arka planı tamamen Azure Mobile Services olmuş oluyor.

Her şey güzel gibi....

İtiraf etmek gerekirse Azure Mobile Services'ın bu şekilde kullanılabileceğinin Microsoft'un aklına geldiğini bile sanmıyorum. Materyallere, dokümanlara vs baktığınızda Azure Mobile Services'ın web sitelerinde kullanımından bahsedildiğini hiç görmedim. Zaten ürünün adı da belli :) Mobile Services. Peki bu işin altından bir sıkıntı çıkar mı? Tek bir olası sıkıntı var; maliyet. Mobile services ücretsiz sürümünde 500.000 API erişimi limiti var. Yani sitenizde bir ayda 500.000 kişi girip sadece ana sayfanıza baksa bile bu limite dayanabilirsiniz. 1.5 milyon API Call ise kabaca 25$. Kesinlikle ucuz değil. Mobile uygulamlarda Mobile Services kullanımı bu fiyatlandırmada çok daha karlı oluyor çünkü o marketteki getiri potansiyeli normal web ortamından daha farklı ve mobile services'ın ölçeklenebilirliği göreceli daha değerli bir pozisyonda oluyor. Normal web sitesi kullanımında ise insan biraz daha teredütte kalıyor. İlla sitenizin verisini API üzerinden verecekseniz ve aceleniz varsa, yeterli yazılım geliştirme kaynaklarınız (zaman vs) yok ama bütçeniz varsa Mobile Services süper uygun bir seçenek olabilir. Bir diğer senaryo ise zaten hali hazırda Mobile Services kullanan mobil uygulamalarınız varken web sitenizi de buradan besleyebilmek olabilir. Böylece mobil uygulaması olan web sitesi olmayan çoğu startup web sitelerini daha hızlı bir şekilde release etme şansına sahip olabilir. Daha eminim ki benim aklıma gelmeyen bir çok senaryo vardır ama genel olarak maliyeti akılda tuttukça ben başka bir olası sorun ile karşılaşılabileceğini düşünmüyorum.

Görüşmek üzere.

Aslında epey oluyor ben Dell Venu 8 Pro'yu satın alalı. Sanırım bir seneyi bulmuştur. Fakat tabi ki sizin de tahmin edebileceğiniz üzere 8" bir bilgisayarı, tableti ana bilgisayarım olarak kullanmıyorum :) Aslına bakarsanız tablet olarak da pek kullanmıyorum. Hayatımda maalesef bir tabletin yeri yok. Nedense kullanamıyorum, zaman veya fırsat olmuyor. Genelde ne yapacak olsam hep bir PC'ye ihtiyacım oluyor. Kitap okuma konusuna da gelince ya okuyacağım kitapların dijital halleri olmuyor ya da zaten AudioBook halleri oluyor ve o şekilde tüketmeyi çok daha uygun buluyorum. Kitap okumak konusundaki fikirlerimi ve deneyimleri daha önce bir yazıda sizlerle paylaşmıştım. Okumayanlar göz atsın derim :) Biz dönelim Dell Venue 8 Pro'ya.

Benim Dell Venue 8 Pro'yu esas satın alma amacım özellikle iş gezilerinde kullanabileceğim ve bir PC'de yapabileceğim her şeyi yapabileceğim bir cihaza sahip olmaktı. Ayrıca tablet kullanamıyorum dediğimi hatırlıyorum :) ama gerçek anlamda bir tablet ihtiyacı hissettiğim ve kullandığım tek yer de 17 saati bulan Amerika uçuşları oluyor. Eh bilenler bilir, çalıştığım şirket nedeniyle iş gezisi demek benim için Seattle'a uçmak demek. Bu da doğrudan 17-18 saatlik uçuş demek. Tüm bu ihtiyaçları toparladığımızda ve yılda en az dört defa bu tip iş gezileri yapmak zorunda kaldığım düşünülürse Dell Venu 8 Pro doğru bir yatırım olarak gözüküyordu. Öyle de oldu. İş gezilerinde tüm ihtiyaçlarımı karşılayabilen bir cihaz olarak başarılı bir şekilde Dell Venue 8 Pro'yu kullanabildim, kullanıyorum. Ufak bir araştırma yaptığımda Türkiye'de şu anda satışta bulamadım Venue8'yi ama satışta olduğunda 750TL gibi güzel bir fiyatla satılmış anladığım kadarıyla.

Teknik özellikler?

İlk merak ettikleriniz tabi ki teknik özellikleri olacak ama öncesinde şu kadarından bahsediyim, cihaz süper ince ve ufak. Zaten adı üzerinde 8". Ben 64GB bellek ile gelen en yüksek bellek seçenekli sürümünü satın aldım. Yanına bir de 64GB MicroSD kart koydum. Böylece benim için kabul edilebilir sayılabilecek 128GB'a ulaşabildim. Cihazın 1280*800 çözünürlüklü IPS ekranı süper parlak ve ışıl ışıl. Cihaz şu göreceli yeni çıkan dört çekirdekli Intel Atom'larla (Z3740D) geliyor. Eski Atom'lar gibi yerlerde sürünmüyor ama inanılmaz performans beklemek de doğru olmaz tabi ki. 2GB bellekli Intel HD Graphics de 8" bir cihaz için fazlası ile idare eder nitelikte. Tabletin üzerinde bir micro-USB bir de kulaklık-mikrofon kombo girişi var. Hepsi bu kadar :)

Kişisel deneyimlerime gelirsek...

Tablet olarak çok kullanmasam da cihaz bence tablet olarak başarılı bir cihaz. Pil ömrü hiç rahatsız etmedi. Kaç saat gidiyor derseniz... valla hiç pili bittiği için şarj etmedim. iPad'den farksız bence. Tabi bu noktada Win8 uygulamalarının zenginliği de etkili olmuş olabilir :) Yani pili tüketecek kadar kullanacak uygulama bulamamış olabilirim. Şaka bir yana ben Kindle uygulaması ile kitap okuyarak bir günde pilini bitiremedim. 10-15 saat çok rahat kitap okumuşumdur bir defada. Tablet olarak bunun dışında pek de kullanmadım zaten. Hafif, ince, pili güzel giden Win8 bir tablet için bence en başarılı cihazlardan biri. Şarj olayı da üzerinde micro-USB ile yapılıyor ama bu noktada bir sıkıntısı var. Şarj konusunda epey seçici Dell Venu8. 2AMP şarj cihazlarının hepsi ile çalışmıyor. Nedeni ile ilgili hiçbir fikrim yok. iPad şarj cihazı yetmiyor örneğin. 1AMP şarj soketleri ise kesinlikle şarj etmiyor. Bence bu çok büyük bir eksik. Örneğin uçakta, koltuk arkalarından USB'lerden şarj edemedim. Dell'in bunu düşünmüş olması gerekirdi.

Cihazı bir PC'den beklediğim her şeyi yapabilir bir cihaz olarak tanımladım ama diskin 128GB olduğunu unutmamak gerek. Ben Visual Studio yüklemedim çünkü zaten Dropbox dosyaların SD kartı tamamen doldurdu ve VS yükleyecek yer kalmadı. VS gerektiğinde Azure'daki VM'ime bağlanıyorum. O nedenle Visual Studio performansı konusunda yorum yapamayacağım. Tahmin etmemi isterseniz eğer, sonuç olarak Atom :) yani compile sürelerinde çılgın hızlar beklemeyin ama zaten 8" cihazda da en fazla bir bugfix check-ini yaparsınız o kadar. Onu da rahatlıkla yaparsınız bence.

Venue8'in şarj sıkıntısı haricinde en büyük sıkıntısı firmware ve driverlarda. Random bir şekilde 2-3 günlük kullanımda en az bir kere Wireless sürücüleri tamamen dağılıyor. Bilgisayara full restart atmadan kendine gelmiyor. Tabi cihazın micro-USB'sini şarj için kullandığım için mouse ve klavye de bluetooth ve tabi ki wireless sürücüleri çatlayınca Bluetooth da çatlıyor. Allah'tan 2-3 günde bir oluyor bu durum da cihazı tamamen kullanılmaz hale getirmiyor.

Peki sunum yapmak isterseniz? Yani bu ufacık cihaza bir harici monitör bağlamak isteseniz? Harici USB ekran kartlarından alıyorsunuz, micro-USB to USB çevirici ile olayı çözebiliyorsunuz. Ama tabi ki harici monitöre var olan tek micro-USB'yi kullanarak bağlanacağınız için bu sürede pilinizi şarj etmeniz mümkün olmuyor. Bence Dell'in bu konuda bir adaptör çıkarması gerekirdi. Maalesef böyle bir adaptör yok. Elle yapanlar var internette ama uğraşır mısınız bilmem.

Yukarıda sürekli problemleri sıraladım ama bunların dışında cihaz bir yolculuk boyunca tüm işlerinizi görebileceğiniz ve Win8 tablet uygulamaları yettiğince tablet olarak da kullanabileceğiniz, şarj süresi vs yerinde güzel bir 8" tablet, PC. Yukarıdaki sorunlar çözülse, üzerine bir de 256GB bellek gelse bu cihazı kimse tutamazmış :)

Peki size tavsiyem nedir?

Açıkçası eğer iPad'iniz yoksa :) büyük ihtimal bir tablet alma ihtiyacı hissetmediniz bugüne kadar demektir. Bu durumda birkaç seçenek var. Ya tablete ihtiyacınız yok ve Venue8 de sizin için gereksiz olabilir. Ya da tablet cihazları sadece tablet olarak yatırıma uygun görmüyorsunuz. Ben ikinci gruba giriyorum. Sanırım iki defa farklı iPad'ler aldım ve her seferinde kullanmadığım, bir kenarda durduğu için elden çıkardım. Yolculuklarda çok işime yarıyordu ama hem tablet hem laptop taşımak anlamsız geliyordu. Diğer yandan sadece yolculuklarda yolda kullanabileceğimiz bir cihazı kenarda tutmak da pek anlamlı gelmedi bana. Dell Venue 8 hem uçuş süresince uçakta tablet olarak kullanabileceğim hem de gittiğim şehirde bir bilgisayar olarak kullanabileceğim bir cihaz olarak çok daha anlamlı oldu :) Hybrid cihazlarla ilgili genelde karışık duygular içerisindeyim. İtiraf etmek gerekirse çok yolculuk yapmasam Dell Venue 8'de süper anlamsız olacak. Tabi benim hayal edemediğim senaryolar da söz konusu olabilir. Ben deneyimlerimi paylaşiyim istedim ;) Umarım işinize yarar.

Görüşmek üzere.

"Körün istediği bir göz allah verdi iki göz" şeklinde esasen uygunsuz bir örnek vererek başlangıç yapıyorum. Blogumu sürekli takip edenler bilirler yoğun istek üzerine geçen ay başında azure mobile services üzerine bir webiner düzenlemiştim. Hatta video kaydını da sonrasında sizlerle paylaşmıştım. Kaçıranlar, "Benim sorum vardı, soramadım." diyenler üzülmesin :) 12 Haziran akşamı 19.30'da bir azure mobile services webineri daha yapıyoruz. Bu sefer tek başıma da değilim. Webinerde bana Microsoft'tan Yazılım Geliştirme Teknolojileri Yöneticisi Selçuk Uzun’un da katılacak. Data, Push Notification, Authorization, Scheduler, Diagnostic & Scale gibi konulara değinerek sorularınızı da alacağız. Her zamanki gibi webiner tamamen ücretsiz!

Webinerde örneklerimizi JavaScript ve C# ile yapacağız ama aklınızda bulunsan Azure Mobil Services'in Android, iPhone SDK'leri de mevcut. Mobil uygulama geliştirme ile ilgilenen herkes için ilginç bir webiner olacağından eminim.

Azure Mobile Services Webiner

Katılım için kayıt olmayı unutmayın! http://msft.it/Microsoft-Azure-Mobil-Servisler-Kayit

Görüşmek üzere.

Dün akşam 22.00'da başlayarak Azure Mobile Services webinerimizi gerçekleştirdik. Saat 23.30'a kadar kalan herkese çok teşekkürler :) Webinerin kaydını da başarılı bir şekilde almayı başarmışım. Kaçıranlara iyi seyirler!

Dün Konya yollarındaydım. Selçuk Üniversitesi'ndeki "Girişimcilik ve Ekonomi Zirvesi" için Endüstri Mühendisliği Topluluğu tarafından davet edildim. Malum etkinlik bir developer etkinliği değil :) Benim de zaten bir süredir aklımda anlatmak istediğim farklı konular vardı. İşte onlardan birini sahneye attım ve "Boş Durma Boşa Çalış." adında bir sunum yaptım. Sunum dosyasını paylaşmamı isteyenler oldu ama paylaşmayacağım :) çünkü zaten tek başına sunum dosyasının bir anlamı yok ve gereksiz spoiler niteliği taşımaktan öteye bir işlevi olmaz. O yüzden içeriği merak ediyorsanız bu oturuma bir yerlerde denk gelmeniz gerekecek :)

Etkinlik benim için inanılmaz eğlenceli geçti. Anadolu üniversitelerinde sahne almayı özlemişim diyebilirim :) Tüm öğrenciler inanılmaz içten ve sevecen! "Avrupa'dakiler öyle değil mi?" diye yorum gelir şimdi :) Baştan söyliyim; Avrupa'dakiler de içten ve sevecen. ("İnanılmaz derecede değil" :D) Şaka bir yana güzel bir gün geçirdim Selçuk EMT ekibi ile. Organizasyon ekibinden teşekkür edebileceğim bir çok kişi var ama bir kişinin adını buraya yazmazsam ayıp etmiş olurum. Sevgili Savaş Kalkan'a buradan çok teşekkürler. Etkinlik öncesi, süresince ve sonrasında beni hiç yalnız bırakmadı Savaş :) Teşekkürler!

Hepinize bu akşam Azure Mobile Services webinerinde görüşmek üzere!

Hatırlarsanız Şubat ayında bir anket yapmıştım :) İşte o anketin sonuçlarına göre bu Cuma akşamı 22.00-23.00 arasında Azure Mobile Services üzerine bir webcastim olacak. Sonunda planlayabildim :) Webcast zamanı geldiğinde katılabilmek için bilgisayarınızda Live Meeting yüklü olması gerekiyor. Şimdiden yükleyebilir veya webcast'e 10 dk önce gelirseniz o esnada da hemen yüklemeyi gerçekleştirebilirsiniz.

Konu: Client Developer'ın Hayali: Azure Mobile Services
Tarih: Cuma, Mayıs 9, 2014 22:00-23.00 EEST
Katılım Linki: https://www.livemeeting.com/cc/mvp/join?id=D9FP3T&role=attend
Meeting ID: D9FP3T

Katılım tabi ki ücretsiz :) ve tek yapmanız gereken zamanında yukarıdaki linke tıklayıp Live Meeting ile webcasti izlemek ;)

Cuma görüşmek üzere!

Eski Basic günleri...

Benim programlama ile tanıştığım yıldır 1994. QBasic zamanları :) O zamanlar yazdıklarımdan bir şeyler bulamadım maalesef :) Ama bugün şöyle bir girip karıştırdığımda komutların çoğunu hatırlamakta zorlandığımı gördüm. Eh şaka değil tam 20 yıl geçmiş. Çok uzun bir süre gibi geliyor kulağa değil mi? Oysa bugün Basic'in 50. doğum günü.

1964'de Basic ilk olarak yaratıldığında doğal olarak dominant programlama dili Assembly'di. Dartmouth College Matematik Profesörleri John G. Kemeny (Albert Einstein'ın Asistanı) ve Thomas E. Kurtz tarafından programlamanın öğrenilmesini kolaylaştırmak için yaratıldı Basic. Öyle de oldu. Basic kısa zamanda popüler hale geldi. İlk sürümünde sadece PRINT, LET, IF-THEN, FOR-NEXT, GOTO, ve END komutları vardı :) INPUT bile iki yıl sonraki sürümde eklendi.

Basic'in yolu sonraki yıllarda Micro-Soft ile kesişti :) ve esas popülerliliğini de Altair ile beraber kazandı. Bu süreçte farklı Basic varyantları da çıktı. CBASIC, True Basic vs derken 1990'larda GWBasic ve sonrasında QuickBasic çıktı. Aslında aynı zamanlarda Visual Basic de kendini Windows 3.0 üzerinde göstermişti ama hala MS-DOS'da çalışanlar için Microsoft, QuickBasic'i de çıkardı.

Visual Basic 3.0'la eski günler...
Visual Basic 3.0'la eski günler...

Bugün Basic'in geldiği nokta Visual Basic.NET ile çok daha farklı :) Yolda geçirilen evrim inanılmaz nitelikte. Ama değişmeyen tek bir şey var. Basic hala iş bitirmeye odaklı ve öğrenilmesi kolay tutulan dillerden. Hatta Microsoft son yıllarda Basic'in bir SmallBasic sürümünü de çıkartıp dilin kolay öğrenilme özelliğinden faydalanarak çocuklar için de bir programlama dili ve ortamı oluşturdu. Yazdığınız SmallBasic kodu Silverlight ile tarayıcı içerisinde bile çalıştırılabiliyor.

Eğer siz de eski günleri hatırlamak ve eski Basic ile bir şeyler yapmak isterseniz MS-DOS 6.00 disklerinizi aramadan önce Basic'in online sürümü olan QuiteBasic'e bir göz atın derim :) Yok ben yeni ortamlarda nostalji yaparım diyorsanız bu sefer de QuickVisualBasic ile devam edelim :)

Roslyn ile QuickVisualBasic

1 Nisan şakası gibi geliyor değil mi kulağa? Ama değil. Basic'in 50.yılını kutlamak adına Microsoft, QuickVisualBasic'i çıkarttı :) Roslyn üzerinden beslenen bu arkadaşı hemen buradan edinebilirsiniz. İndirdikten sonra kendi Visual Studio'nuz ile compile ettikten sonra karşınıza bir console gelecek. İşte orası QuickVisualBasic!

QuickVisualBasic! Budur!
QuickVisualBasic! Budur!

Benim Basic sevdam görüldüğü üzere çok eskilere dayanıyor. Bugün her ne noktadaysam bunu Basic'e borçluyum. Basic olmasa başka bir şey olmaz mıydı? Belki olurdu, belki de olmazdı ama benim programlama ana dilim Basic oldu ve kalbimde her zaman ayrı bir yeri olacak. 50. doğum günün kutlu olsun Basic!

Görüşmek üzere!

Azure tarafında uzun yıllardır en sıkıntılı konulardan biri ScheduledService'ler. Aslında sıkıntı da zaten bu gibi zamanlanmış servislerin oluşturulması için tabiri caiz ise adam gibi bir altyapının olmaması. Tabi ki isterseniz bir VM alıp "Windows Scheduler" kullanabilirsiniz veya Cloud Service'inize bir worker ekleyip işi çözebilirsiniz ama bu çözümlerden biri PAAS çözümü değilken diğeri ise basit bir Scheduler için çok maliyetli. Bu yazıda bahsedeceğimiz WebJobsSDK bu sorunu çözmeyi amaçlarken kendisi de Preview'da olan WebJobs konsepti ile Azure Web Sites üzerinden sunuluyor. Şu an için Preview olmasından dolayı çok eleştirel yaklaşmayacağım fakat WebJobs'ı nasıl kullanırıza gelmeden önce bilmeniz gereken birkaç şey var. İlk olarak bu servisin Azure Web Sites altında gelmesi manidar. WebJobs şu anda Cloud Service'daki ölçeklenebilirlik ihtiyaçlarınızla paralel yükleri kaldırabilecek nitelikte değil. Azure Web Site deploymentınızın boyutu bugün neyse WebJobs'da aynı kaynaklarda çalışıyor ve kaynakları paylaşıyor. Yani ayrıca scale etme vs şansınız yok. Cloud Service'ler için şu anda daha low level bir implementasyon sunan Azure Scheduler'ı tavsiye edebilirim. Zaten her iki servisin adındaki farklılık da çok anlamlı. Biri Scheduler biri Job :) Yani sonuç itibari ile Job'ları da schedule edebiliyoruz ama WebJobs çok daha yüksek seviyeli, Azure Web Sites'a uygun bir altyapı sağlayarak çok daha kolay kullanımlı bir ortam sağlıyor. Konsept üzerinden konuşmayı bu noktada bırakıp gelin Webjobs SDK ile neler yapabiliyoruz görelim.

WebJobsSDK

WebJobs üzerinden bir çok senaryo ilerletmek mümkün. Ben .NET tarafına odaklanacağım ama Bash, PHP, Node, Python veya basit BAT dosyları ile de Job yazabilirsiniz. .NET tarafında yazdığımız Job'ı bir "Console Application" olarak tasarlayacağız ve sağladığı kolaylıklardan da faydalanmak için WebJobsSDK'i referans olarak projemize ekleyeceğiz. Yeni bir konsol uygulaması yarattıken sonra SDK'in Preview Nuget paketlerini indirmek için Nuget Package Manager Console'da aşağıdaki komutları çalıştırabilirsiniz.

Install-Package Microsoft.WindowsAzure.Jobs -Pre
Install-Package Microsoft.WindowsAzure.Jobs.Host -Pre

Bu komutları çalıştırdığında projenize dört tane referans eklenecek. AzureConfiguration, StorageClient, Jobs ve JobsHost adındaki bu referansların ikisi doğrudan JobsSDK ile alakalı iken diğer ikisi ise JosbSDK'in doğrudan Azure'daki Storage Servislerini kullanmak zorunda olmasından kaynaklanıyor. Yanında bir de JSON.NET gelecektir. Onun da ileriki makalelerde JobsSDK'in Storage'lardaki Queue'lar ile olan ilişkisine bakarken hep beraber göreceğiz :)

Blob üzerinden "Trigger" ve "Output"

Ortamımız hazır olduğuna göre artık kod yazmaya başlayabiliriz. Yapacağımız uygulamanın iki bölümü olacak. WebJobsSDK'i kullanarak harici bir Storage Account içerisindeki bir Blob Container'ın içine dosya konduğu anda kendi tanımlayacağımız bir işlem yapmak istediğimizi varsayalım. Örneğin ben özel bir container'a bir text dosyası konduğunda içindeki metni küçük harflere çevirerek başka bir containera yeni bir text dosyası olarak kopyalamak istiyorum. Bunun tamamen otomatik olarak WebJobs tarafından sürekli yeni bloblar için yapılmasını istiyoruz. Tabi böyle saçma bir örnek vermemin nedeni örneği basit tutabilmek ama siz daha karmaşıklarını hayal edebilirsiniz. Örneğin bir container'a konan resimleri resize etmek güzel bir senaryo olabilir.

[C#]

class Program
{
    static void Main(string[] args)
    {
        JobHost host = new JobHost();
        host.RunAndBlock();
    }

    public static void LowerCase(
        [BlobInput(@"gelenblobcontainer/{name}")] Stream gelenStream,
        [BlobOutput(@"gidenblobcontainer/{name}")] Stream gidenStream)
    {
        string tumMetin = "";

        using (StreamReader st = new StreamReader(gelenStream))
        {
            tumMetin = st.ReadToEnd();
        }

        using (StreamWriter stw = new StreamWriter(gidenStream))
        {
            stw.Write(tumMetin.ToLower());
        }
    }
}

Yukarıdaki kafa karıştırabilecek bir çok şey var. O nedenle gelin adım adım ilerleyelim. Konsol uygulaması ilk çalıştığında JobHost adında bir nesne yaratıp RunAndBlock ile Host'u çalıştırıyoruz. Bu noktada WebJobs'a bizim konsol uygulaması ile tüm jobların çalışması gerektiği mesajını vermiş olduk. Sonrasında hemen altta ise LowerCase diye bir metod var. Bu metodun parametrelerinde bir anlamda "Model Binding" mevcut. BlobInput ve BlobOutput için verdiğiniz değerler doğrudan container adı üzerinden giden ve takip etmek istediğiniz Blobların adresini tanımlayan path değerleri. {name} keyword'ü blobun kendi adını temsil ediyor. Böylece benim storage account'um içerisindeki containerlardan "gelenblobcontainer" adındaki container içindeki bloblar takip edilecek ve bu blobların içeriği doğrudan Stream olarak gelenStream'e atanacak. Aynı işlem OutputBlob ile de Storage Account'a geri blob atmak için kullanılacak. OutputBlob için ben farklı bir container kullandım. Blob ismi olarak ilk gelen InputBlob'un ismini atadım. Bu noktadan sonra gidenStream'e her ne yazarsam yaziyim OutputBlob'a verdiğim path çerçevesinde Storage Account'ta bir blob'a yazılacak. Geri bize geri kalan da gelen Stream'i okuyup istediğimiz değişiklikleri yapıp OutputStream'e son hali yollamak.

Gördüğünüz üzere WebJobs SDK süper bir implementasyona sahip. Neredeyse tün Blob kullanımına dair karışıklıkları çözüp atıyor. Peki hangi StorageAccount'u kullanacağını nasıl biliyor derseniz işte onu da tabi ki Web.Config'den alacak. Bunun için Azure Web Sites'ın yönetim paneline gidip iki farklı Connection String tanımlamamız gerek.

Webjobs'a özel iki Connection String.

Yukarıdaki ekran görüntüsüne de görebileceğiniz üzere Azure Web Site'ımızın Connection String'lerine iki adet yeni item ekliyoruz. Bunlardan "AzureJobsData" doğrudan bizim kullanacağımız verilerin bulunduğu Storage Account'un Connection Stringi. Örneğimizdeki "gelenblobcontainer" bu Storage Account'un içerisinde olacak. Diğer Connection String ise AzureJobsRuntime'ın kullanacağı ve kendi loglarını tutacağı yer. Her iki connection string de aynı Storage Account'u hedefleyebilir. O konuda bir sıkıntı olmayacaktır. Runtime Logging için WebJobsSDK iki adet ek container yaratacak. Bunlar "azure-jobs-invoke-log" ve "azure-jobs-event-queue" şeklinde. Umuyorum ki sizin aynı isimde containerlarınız yoktur :) Bu containerların içinde sistem kendi loglarını tutuyor.

WebJobs'ın loglarından bir örnek.
WebJobs'ın loglarından bir örnek.

Tabi bu logları tek tek text dosyalarını açarak incelememize gerek yok. Bunun için Azure Web Sites altında bir Extension olarak çalışan özel bir Dashboard var. Dashboard'a ulaşmak için https://SITENIZINADI.scm.azurewebsites.net/azurejobs/ adresine gitmeniz gerekiyor. Deployment Credential'larınızı kullanarak buraya giriş yaptığınız anda inanılmaz güzel detayları görebilmeye başlayacaksınız.

WebJobs Dashboard'u.
WebJobs Dashboard'u.

Bu Dashboard içerisinde sadece WebJobs Host'unuzu yaşam döngüsünü değil tek tek yapılan işlerin detaylarını bile görebilirsiniz. Özellikle birden çok Job'ınız olduğunu düşünürsek buradaki loglar debugging için de süper bir değere sahip.

Dashboard'un detaylarında neler saklı...
Dashboard'un detaylarında neler saklı...

Blobların aynı sıra WebJobs Azure Storage'daki Queue ve Table servisleri ile de çalışabiliyor. Bunların detaylarına ileriki yazılarda göz atacağız. Şimdilik isterseniz bir de gelin yukarıdaki tüm hikayesine göz attığımız örnek WebJob projemizi Azure'a nasıl deploy edeceğimize bakalım. :) O konuyu atladık.

Deployment

Elinizdeki Konsol uygulamasını deploy etmek için her şeyi alıp bir ZIP haline getirmeniz lazım. Bu ZIP'i doğrudan Azure Management portalından upload edeceğiz. Management Portal içerisinde kullanacağınız Web Site'ın detaylarına girdiğiniz en üst kısımda WebJobs tabını göreceksiniz. Oraya girip yenib ir Job yaratmak istediğinizde sizden Job için bir isim, çalışma şekli ve ZIP dosyası istenecek.

Farklı WebJob seçenekleri.
Farklı WebJob seçenekleri.

Biz örneğimizde "Continious" seçeneği kullanmalıyız ki sürekli olarak yeni bir Blob geldiğinde Job'ımız çalışsın. Bu arada Blob'lardaki değişiklikler ortalama 10 dakikada bir kontrol ediliyor. Malum ne kadar sürekli takip et desek de Storage servislerine bir REST call gitmesi lazım. WebJobs için diğer seçeneklerden biri "On Demand". Bu durumda gelip portaldan Job'ın çalışmasını tetikleyebilirsiniz veya JobHost nesnesine erişimi olan herhangi bir yerden JobHost'un Call metodunu da çağırabilirsiniz.

Olayın biraz daha derinlerine inersek aslında Upload ettiğiniz ZIP dosyası doğrudan sitenizde "site\wwwroot\App_Data\jobs\{job tipi}\{job adı}" şeklinde bir pathe extract edilecektir. Job Tipi "Continuous" veya "triggered" olabilir. Hem scheduled hem de On Deman joblar "Triggered" olarak geçiyor. Dosyalarda herhangi bir değişiklik olduğunda sistem ilk olarak "run" adına sahip ve WebJobs tarafından desteklenen uzantılarda bir dosya arayacak. Eğer WebJobs bu gibi bir dosya bulabilirse çalıştıracak aksi halde desteklenen uzantılardaki tüm dosyalara bakacak.

Böylece WebJobs'ın sadece genel kullanımına değil Blob'larla nasıl kullanılabileceğine de göz atmış olduk. İleriki bir yazıda Queue ve Table servisleri ile WebJobs kullanımını da inceleyeceğiz.

Makaledeki örneği Github üzerinden indirebilirsiniz.

Karambolde unutmuşum bu blog postu atmayı :) Build vs yoğunlukta fırsat bulamadım. Her yıl olduğu gibi yine Nisan dönemi benim için bulunduğum programlar adına yenilenmeni dönemi. Bu sene de Microsoft tarafından Windows Azure alanında MVP ünvanına layık görülmüşüm :) Ayrıca Microsoft Regional Director ünvanım da yine 2014 için yenilendi. Tüm bu haberleri alırken Nokia Developer Champion tarafında da ünvanımın 2014 yılı için yenilendiğini öğrendim. Özetle her şey yolunda :)

MVP, RD ve NDC Ünvanları

Buradan teşekkür etmem gereken çok insan var :) ama kısa tutmak gerekirse yaptığım katkıyı gördükleri ve değer verdikleri için hem Microsoft hem de Nokia'ya teşekkürler. Umarım çok daha güzelini ve iyisini yaptığımız bir yıl olur önümüzdeki yıl.

Twitter
RSS
Youtube
RSS Blog Search
Arşiv'de tüm yazıların listesi var. Yine de blog'da arama yapmak istersen tıkla!
Instagram Instagram