Azure Function App ile veritabanı işlemleri
11 May 2017Bu yazımda basit bir senaryo üzerinden Azure Function ile veritabanı işlemleri nasıl yapılır gösteriyor olacağım.
Senaryo
Bizim için önemli bir görevi yerine getiren bir Azure Function var. Bu Azure Function çeşitli uygulamalar tarafından çağırılmakta. Bizde Azure Function her çağrıldığında Azure SQLDB de log tablomuza bir kayıt atıp, olan biteni kayıt etmek istiyoruz.
Gerekenler
- Azure SQL DB
- Azure Function App
Azure SQL DB
Öncelikle Azure Function ile veri yazacağımız veritabanını yapılandırmamız gerekiyor.
- Azure Portal’de Sol menüden SQL Databases i seçiyoruz.
- Açılacak olaran kısımdan Add butonuna tıklıyoruz.
-
Başlangıç olarak yeni bir Server oluşturuyoruz. Burada daha önce bir Server yapılandırdıysanız hazır olanlardan seçebilirsiniz. Tabi hazır seçtiğiniz sunucuya bağlantı için kullanıcı adı ve şifreye ihtiyacınız olacak.
-
Create a new server ile yeni sunucu oluşturma işlemine başlıyoruz.
-
Server name, alanına sunucu adımızı giriyoruz.
-
Server admin login, bu sonra sunucumuza bağlanmak için kullanacağımız kullanıcı adı olacak.
-
Password, bu alanda aynı şekilde bağlantı bilgilerindeki erişim şifremiz olacak.
-
Confim password, şifremizi tekrar giriyoruz.
-
Location, West Europe seçiyoruz.
-
Select butonuna tıklıyoruz ve sunucumuz hazır. 👍
-
Database name, Loglarımızı tutacağımız veritabanı adı. Ben LogDB olarak girdim. Siz farklı bir isimlendirme standardınız varsa kullanabilirsiniz.
-
Subscription, Veritabanını hangi Azure Subscription içerisinde oluşturacağınızı seçin.
-
Resource Group, Kullanılacak resource group seçimi yapın. Ben daha önce WestEurope ta yapılandırmış olduğum bir resource group seçtim. Eğer daha önceden tanımlı bir resource group yoksa Create new e basarak yeni bir resource group oluşturabilirsiniz.
Resource group oluştururken veya başka bir Azure servisi oluşturuken Hedef kitleniz Türkiye’de ise mutlaka West Europe lokasyonunu seçiniz.
-
Select source, Boş bir veritabanı istediğimiz için Blank database seçiyoruz.
-
Server, Sunucuyu daha önceki adımlarda ayarlamıştık.
-
Want to use SQL elastic pool?, Şimdilik, Not now diyerek ilerleyebiliriz.
-
Pricing tier, Fiyat kademesini seçiyoruz. Ben gerçek bir senaryoda kullanılmayacağı için Basic: 5 DTU, 100MB seçtim.
-
Collation, Kulllanılacak veritabanı Collation olarak SQL_Latin1_General_CP1_CI_AS kalabilir.
-
Create, butonuna tıklayıp veritabanımızı oluşturuyoruz.
-
Oluşturduğumuz veritabanı üzerinde çalışmak için en soldaki menüden SQL databases seçeneğine tıklıyoruz.
-
Gelen kısımdan, LogDB seçiyoruz.
-
Overview e tıklıyoruz.
-
Tools butonuna tıklıyoruz.
- Veritabanına bağlanmak için aslında bir kaç seçeneğimiz mevcut mesela Visual Studio, SQL Server Management Studio gibi. Ancak ben şu an preview aşamasında olan Query editor ü seçeceğim. Böylece Azure Portal ortamından çıkmadan işime devam edebiliyor olacağım. Bu kısımdan Query editor e tıklayıp devam edeceğiz. Ön izleme aşamasında olduğundan size kullanmak istediğinize emin misiniz diye bir soru sorabilir bu soruya olumlu cevap verip devam edebilirsiniz.
-
Login butonuna tıklıyoruz. Ekranda giriş işlemleri yabileceğimiz bir kısım açılacak.
-
Authorization type, olarak SQL server authentication seçiyoruz.
-
Login SQL sunucusu oluştururken tanımlamış olduğumuz kullanıcı adını giriyoruz.
-
Password, kullanıcı için tanımladığımız şifreyi giriyoruz.
-
OK, butonuna tıklayıp sunucuya bağlanıyoruz.
Herşey yolunda gittiyse yukarıdaki ekran görüntüsündeki gibi Authenticated as sizin_kullanıcı_adınız mesajını görmelisiniz.
- Log tutacak tablomuzu oluşturuyoruz. Oluşturmak için gerekli kodu bu alana yazıyoruz.
Tablodaki alanlarımız.
Id Primary Key alanımız.
LogMessage Log mesajlarımızı bu alanda saklayacağız.
CreateDate Log ne zaman oluşturuldu verisi burada saklayacağız.
CREATE TABLE [dbo].[Logs](
[Id] [INT] IDENTITY(1,1) NOT NULL,
[LogMessage] [NVARCHAR](MAX) NULL,
[CreateDate] [DATETIME] NULL,
CONSTRAINT [PK_Logs] PRIMARY KEY CLUSTERED ([Id] ASC)
)
-
Run butonuna tıklayıp kodumuzu çalıştırıyoruz.
-
Messages sekmesinde, Query succeed yazıyorsa kodumuz başarılı şekilde çalışmıştır.
- Tablomuzun oluştuğunu görmek için sorgu editörüne select sorgumuzu yazıyoruz.
SELECT * FROM Logs
-
Run butonuna tıklayıp kodumuzu çalıştırıyoruz.
-
Result sekmesine tıklıyoruz.
-
Gördüğümüz gibi kolonlarımız geldi. Henüz log olmadığı için No results yazması normal.
Bu adımla beraber veritabanımız hazır. 👍
Azure Function App
Azure Function App servisimizi Azure Portal’i kullanarak yapılandırıyoruz.
-
Sol menüden New seçeneğine tıklıyoruz.
-
Arama kısmına Function App yazıyoruz.
-
Everything bölümünde Function App tıklıyoruz.
- Function App kısmından Create butonuna tıklayarak Function App oluşturma işlemine başlıyoruz.
-
App name, uygulamamızın adı
-
Subscription, Function App hangi Azure Subscription içerisinde oluşturulmasını istiyorsanız onu seçin.
-
Resource Group, kullanılacak resource group seçimi yapın. Daha önce oluşturduğunuz resource grouplardan seçebilir veya Create new e basarak yeni bir resource group oluşturabilirsiniz. Ben yeni bir tane oluşturmayı tercih ettim.
-
Hosting Plan, burada Consumption Plan olarak ilerleyebilirsiniz. Bu seçenek detayları farklı bir blog yazısı konusu.
-
Location, Lokasyon tabiki West Europe
-
Storage, Yeni bir storage oluşturabilir veya mevcut olanlarından seçebilirsiniz.
-
Application Insights, Şimdilik Off konumda bırakabilirsiniz.
-
Create butonuna tıklayıp Function App servisimizi oluşturmaya başlıyoruz.
Oluşturmuş olduğumuz Function App i açıyoruz.
-
Sol menüden All resources seçeneğini tıklıyoruz.
-
Gelen listeden daha önce verdiğimiz App name bulup Function App’i açıyoruz.
Liste çok kabarıksa üst taraftaki filtre seçenekleri kullanılabilir.
Function App ekranımız aşağıdaki gibi olacaktır.
Status bölümü Running ✅
Yeni bir Azure Function oluşturmaya hazırız.😄
-
Burada mylogapp’in yanındaki ok işaretini aşağı doğru genişletiyoruz.
-
Functions seçeneğinin sağ tarafındaki + ikonuna tıklıyoruz.
-
Sağ taraf ekranda gördüğünüz create your own custom function. linkine tıklıyoruz.
Aslında burada Webhook + API, CSharp ve Create this function butonuna tıklayabilirsiniz. Ancak fonksiyonumuzun adı otomatik olarak verilecek. Henüz portal üzerinde yeniden fonksiyon adlandırma yapılamadığından ve son adımda yazdığım gibi ilerliyoruz.
-
Language Kullanacağımız dil olarak C# seçiyoruz.
-
Scenario Bir güzellik Function Apps ekibi senaryo senaryo yapılabilecekleri gruplamış.
-
GenericWebHook-CSharp şu an için bize en uygun senaryo.
-
Name your function Burada fonksiyonumuzun adını veriyoruz. Daha öncede belirttiğim gibi fonksiyon adı daha sonradan değiştirmek zor. İyice düşünerek verin. Ben MyImportantFunction olarak yazdım. Yazımızın başında önemli olduğunu söylemiştim. 😄
-
Create butonu ile fonksiyonumuzu oluşturuyoruz.
Fonksiyonumuz oluştuktan sonra kod editörü yukarıdaki gibi görünecektir.
- View files paneline tıklayarak görünür hale getiriyoruz.
-
Gerekli paketleri kullanabilmek için View files kısmından Add butonuna tıklıyoruz.
-
project.json adında bir dosya oluşturuyoruz.
- project.json dosyamızın için boş editörde boş gözükmekte.
{
"frameworks": {
"net46":{
"dependencies": {
"Dapper": "1.42.0",
"System.Data.SqlClient":"4.1.0",
"Microsoft.WindowsAzure.ConfigurationManager":"3.2.1"
}
}
}
}
Kod editörümüze yukarıdaki json’u yazıyoruz.
-
Save butonuna tıklayıp içerimizi project.json dosyasına kayıt ediyoruz.
-
Logs kısmının sağındaki yukarı ok ikonuna tıklıyoruz. Böylece kodu çalıştırdığımızda olan biteni görebileceğiz.
-
Save and run butonuna tıklayıp kodumuzu çalıştırıyoruz.
-
Logs kısmında yazmış olduğumuz paketlerin NuGet ile yüklendiğini görebilirsiniz.
- Logs kısmında Packages restored. ve Compilation succeeded yazdığını gördüğümüzde paketler yüklenmiştir. 👍
Oluşturmuş olduğumuz veritabanına bağlanmak için Connection string bilgisine ihtiyacımız var.
-
Sol menüden SQL databases tıklıyoruz.
-
LogDB yi seçiyoruz.
-
Overview tıklıyoruz.
-
Açılan kısımdan Show database connection strings linkine tıklıyoruz.
- ADO.NET sekmesinde olan connection string bilgisini hızlı erişebileceğimiz (notepad gibi) bir yere kopyalıyoruz.
Server=tcp:log-server.database.windows.net,1433;Initial Catalog=LogDB;Persist Security Info=False;User ID=logserveradmin;Password=LogServer1234;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
Connection string bilginiz yukardakine benzer olacaktır.
{your_username} ve {your_password}** bölümlerini kendi kullanıcı adı ve şifrenizle değiştirdiğinizde connection string bilginiz hazır olacaktır.
Connection string bilgimizi fonksiyonumuzda kullanmak için tanımlamamız gerekiyor.
-
Sol menüden All Resources tıklıyoruz.
-
Üzerinde çalıştığımız Function App bulup tıklıyoruz.
-
Function App i seçiyoruz.
-
Üst taraftaki sekmelerden Platform fetures sekmesini seçiyoruz.
-
Application settings seçeneğine tıklıyoruz.
Açılacak olan Application settings kısmında Connection strings bölümü biraz aşağıda kaldığından sayfayı aşağı kaydırmanız gerekiyor. Connection strings kısmına veritabanı bağlantılarında kullanmak üzere yeni bir satır tanımlayacağız.
-
Name kısmına SqlConnection yazın.
-
Value olarak daha önceden hazırladığımız ve notepad e kopyaladığımız Connection string i yazıyoruz.
-
Veritabanının tipini seçmemiz istenen açılır kutudanda SQL Database i seçiyoruz.
-
Save butonuna tıklayıp ayarlarımız kayıt ediyoruz.
Kodumuzu yazmak için editörümüzü açmamız gerekiyor.
-
Sol menüden All resources seçeneğini tıklıyoruz.
-
Gelen listeden daha önce verdiğimiz App name bulup Function App’i açıyoruz.
-
Function App seçiyoruz.
-
Functions bölümüne tıklıyoruz.
-
MyImportantFunction a tıklayıp kod editörümüzü açıyoruz.
Sağ taraftan View files bölümünü genişletiyoruz.
- Kodumuzu yazıyoruz.
#r "Newtonsoft.Json"
using System;
using System.Net;
using Newtonsoft.Json;
using Dapper;
using System.Data.SqlClient;
using System.Configuration;
public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)
{
log.Info($"Fonksiyon başlatıldı! RequestUri={req.RequestUri}");
//Çok önemli kodlar burada :)
//.....
//.....
//Fonksiyona parametre olarak gelen userName alanını req.Content deserialize ederek alıyoruz.
string jsonContent = await req.Content.ReadAsStringAsync();
dynamic data = JsonConvert.DeserializeObject(jsonContent);
//Kullanıcı adı yoksa hata mesajı dönüyoruz.
if (data.userName == null) {
return req.CreateResponse(HttpStatusCode.BadRequest, new {
error = "Lütfen fonksiyonu çağıran kullanıcı adını giriniz."
});
}
//Azure SQLDB Loglama
var logAdded = true;
try
{
//Tanımladığımız Function App Settings bölümündeki Connection String i alıyoruz.
var connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString;
using(var connection = new SqlConnection(connectionString))
{
//Azure SQL DB bağlantımızı açıyoruz.
connection.Open();
var logMessage = $"Fonksiyon {data.userName} tarafından {DateTime.UtcNow} tarihinde çağırılmıştır.";
// Log'u veritabanına yazıyoruz.
connection.Execute("INSERT INTO [dbo].[Logs] ([LogMessage], [CreateDate]) VALUES (@logMessage, @createDate)", new { logMessage, createDate = DateTime.UtcNow} );
log.Info("Log kaydı başarılı şekilde veritabanına eklenmiştir!");
}
}
catch
{
logAdded = false;
}
// Fonksiyonumuzu bitiriyoruz. Başarı durumuna göre çağıran kullanıcıya mesaj gösterecek.
return !logAdded
? req.CreateResponse(HttpStatusCode.BadRequest, "Hay aksi birşeyler ters gitti!")
: req.CreateResponse(HttpStatusCode.OK, "Azure Function başarılı şekilde çalştı!");
}
- Fonksiyonumuza parametre olarak kullanıcı adı vermemiz gerekmekte. Test sekmesine tıklayıp burada Request body kısmına json olarak yazıyoruz.
{
"userName": "Mehmet Kut"
}
- Save butonuna tıklayıp kodumuzu kayıt ediyoruz.
Çıktıyı görmek için alt taraftaki Logs sekmesini görünür duruma getirmeyi unutmayın!
- Run butonuna tıklayıp kodumuzu çalıştırıyoruz.
Çalışma bittikten sonra bir hata yoksa Logs sekmesinde yukarıdakine benzer sonuçlar gözükecektir.
Kodumuz başarılı şekilde çağırıldı peki tablomuza kayıtlar yansıdımı kontrol edelim.
-
Sol menüden SQL databases seçiyoruz.
-
Log veritabanımızı seçiyoruz.
-
Overview kısmına tıklıyoruz.
-
Tools butonuna tıklıyoruz.
-
Query editor ü seçiyoruz.
-
Login butonuna tıklıyoruz. Ekranda giriş işlemleri yabileceğimiz bir kısım açılacak.
-
Authorization type, olarak SQL server authentication seçiyoruz.
-
Login SQL sunucusu oluştururken tanımlamış olduğumuz kullanıcı adını giriyoruz.
-
Password, kullanıcı için tanımladığımız şifreyi giriyoruz.
-
OK, butonuna tıklayıp sunucuya bağlanıyoruz.
- Log kayıtlarımızın oluştuğunu görmek için sorgu editörüne select sorgumuzu yazıyoruz.
SELECT * FROM Logs
-
Run butonuna tıklayıp kodumuzu çalıştırıyoruz.
-
Result sekmesine tıklıyoruz. Gördüğümüz gibi log kayıtlarımız geldi.👍 Ben iki kere test amaçlı kodumu çalıştırmıştım iki satır log kaydım var.
Sonuç
Eğer yazıyı adım adım takip ettiyseniz tebrikler. Artık aşağıdaki soruların cevaplarını biliyorsunuz. 😄
-
Azure Portal üzerinden SQL sunucu nasıl yapılandırılır?
-
Azure SQL sunucusuna veritabanı ekleme ve bu veritabanı içerisinde nasıl tablo eklenir?
-
Azure SQL veritabanında bir tablo nasıl sorgulanır?
-
Azure Function App nasıl oluşturulur?
-
Azure Function içerisinde NuGet paketlerini nasıl kullanılır?
-
Azure Function kodundan içerisinden Azure SQL DB bağlantısı nasıl yapılır?
-
Azure Function kodundan, veriler Azure SQL DB de istenilen tabloya nasıl eklenir ve görüntülenir?
Ayrıca önemli bir nokta olarak yazı boyunca sadece tarayıcımızı kullandık.
Azure Portal her geçen gün daha güçlü bir araç olma yolunda ilerliyor.👍