kamer.dev

Hyperledger Composer ile Uygulama Geliştirme — 2. Composer Modelleme Dili (.cto Dosyası)

- #hyperledger - #blockchain

Merhaba. Bir önceki yazımda uygulamadaki olası aktörlerden ve bunları nasıl tanımlayacağımızdan, Kurumsal Ağ Tanımından(Business Network Definition) ve Kurumsal Ağ Tanımının bileşenlerinden bahsetmiştim. Bu yazıda ise Model dosyasının söz diziminden (syntax) bahsedeceğim.

Gereklilikler

Bu yazıdaki herhangi bir gereklilik bulunmamaktadır. Temel seviyede yazılım ve veritabanı bilgisi konuyu anlamanızı kolaylaştıracaktır.

1. Giriş

Model dosyası, uygulamamızdaki katılımcıları, varlıkları ve işlemleri tanımladığımız .cto uzantılı dosyadır. Konuya ilişkin gözden kaçan kavram olmasın diye resmi dokümandaki modeling language tanımını beraber irdeleyelim. Tanıma ilişkin yapacağım açıklamalar büyük oranda yazılım bilgisi yeterli seviyede olmayan kişilere yöneliktir. Bilgi seviyenizin yeterli seviyede olduğuna inanıyorsanız giriş bölümünün bundan sonraki kısmını okumadan diğer bölüme geçebilirsiniz.

“Hyperledger Composer includes an object-oriented modeling language that is used to define the domain model for a business network definition.”

  • object-oriented modeling language ifadesi, yazılım dünyasından birçoğumuzun aşina olduğu ve Türkçeye nesne yönelimli modelleme dili olarak çevrilebilecek bir kavram. Modelleme dili zaten adından anlaşılabilecek basitlikte bir kelime. İrdelememiz gereken kısım bu modelleme dilinin nesne yönelimli olması. En net ve kısa ifadeyle yazılım geliştirirken yaptığımız şey genelde dünyadaki bazı olguları koda çevirmektir. Bu çevirme işlemi sırasında nesne yönelimli bir dil kullanıyorsak her şey bizim için bir nesnedir. Her nesnenin bazı özellikleri (attribute) ve davranışları (behaviour) vardır. Biz bu nesnelerin birbiriyle olan ilişkilerini düzenleriz. Yazdığımız kodla yaratacağımız dünyada bakış açımız buna göre olur. Örneğin bir kütüphane otomasyon sistemi yapacaksınız. Kitaplar ve kütüphane üyeleri birer nesnedir. Üyelerin kimlik numarası, isim soyisim, doğrum tarihi gibi bilgileri özellik, kitap ödünç alma, ödünç aldığı kitabı iade etme gibi eylemleri davranıştır. Kitaplar da aynı şekilde nesnelerdir, ISBN numarası, adı, yazar adı, basım yılı gibi özellikleri vardır. Otomasyonda da genellikle yapılacak şey üye nesnesinin kitap nesnesiyle olan ilişkisini kurmak ve düzenlemek olacaktır.

  • domain model for a business network definiton ifadesindeki domain model, yazılım tasarımının temelidir. Gerçek dünyadaki varlıkları ve bu varlıkların birbiri arasındaki ilişkiyi tanımladığımızda çıkardığımız model domain model’dir. Hyperledger Composer’da bu modeli kurumsal ağ tanımı (business network definition) için yaparız.

Yukarıda bahsettiğim birkaç kavramı iyice anladıktan sonra tanıma genel bir açıklama getirmekte fayda var. Hyperledger Composer’ın kurumsal ağ tanımına gerçek hayattaki bir modeli, bir problemi anlatmamız gerekiyor. Bu bir tedarik zinciri olabilir veya bir sertifika/belge yönetimi olabilir. Gerçek hayatta bu modelin bazı aktörleri, aktörlerin birbirleri arasındaki ilişkileri ve özellikleri vardır. Bu modeli nesne yönelimli modelleme dili ile Hyperledger’a aktardığımız dosya, model dosyasıdır.

.cto uzantılı olan bu dosya üç temel bileşenden oluşur:

  • namespace tanımlaması.
  • Uygulamamızdaki kaynakların tanımlaması.
    •  Varlıklar (assets)
    •  İşlemler (transactions)
    • Katılımcılar (participants)
    •  Olaylar (events)
  • (Opsiyonel) Diğer namespace’lerden kaynak almak.(import)

2. namespace Tanımlamak

Uygulamamızda aynı amaç için bir araya getirdiğimiz tüm kaynakların oluşturduğu kümeye namespace denir. Bu namespace içinde tüm kaynaklar eşsiz olarak tanımlanır. Herhangi bir namespace’e ait olan bir kaynağa erişmek için o kaynağı namespace’in adıyla çağırırız. Çünkü aynı isme sahip olan ve farklı namespace’lerde bulunan iki varlık birbirinden farklıdır. Biyolojideki isimlendirmeler gibi düşünebiliriz. Örneğin mangifera indica mango demekken, apis indica bir bal arısı türüdür. Yazımı gayet basittir. Örnek olarak:

namespace org.hyperledgerturkiye.ornekuygulama

Burada tanımlamayı istediğiniz şekilde yapabilirsiniz. Fakat genelde org’den sonra organizasyon, şirket veya proje ismi; sonrasında genelden özele doğru inen bir adlandırma tercih ediliyor. Benim verdiğim örnekte org.organizasyonİsmi.projeİsmi şeklinde bir tanımlama var. Birden fazla namespace eklemek isteseydim ona göre tanımlamamı değiştirebilirdim. Örneğin,

namespace org.hyperledgerkiye.ornekuygulama.alimSatim

Bu namespace içindeki bir kaynağa ulaşmak içinse aşağıdaki şekilde bir yazım kullanıyoruz.

org.hyperledgerturkiye.ornekuygulama.alimSatim.ilan

Yazım şekline dair bahsedeceklerim bu kadar. İki tane uyarı yapıp bir sonraki bölüme geçelim:

  • İnternette, özellikle IBM’in örneklerinde, “org.acme…." şeklinde tanımlamalar görmeniz muhtemeldir. Acme kelimesi başta bir kural veya dile ait bir şey gibi hissettirdiği için kafanız karışabilir. IBM’in bu gibi örnekler verirken kullandığı hayali lojistik firmasının adı Acme Freight’tir. Yani acme yerine kendi organizasyonunuzu yazabilirsiniz. Github’da bu konuda dert yanıp issue açanlar olmuş fakat hala acme örneği yaygın olarak kullanılıyor.

  • Sizin oluşturduğunuz namespace dışında Hyperledger Composer’ın kendine ait bir namespace’i de vardır. Adı system namespace olan bu namespace, asset, event, participant ve transaction değişkenleri için temel tanımlamaları içerir. Bu tanımlamalar soyut (abstract) tiptedir ve oluşturduğunuz tüm değişkenler bunları extend eder. Bu soyut tanımlamalarda participant ve asset için değer yoktur. Fakat event ve transaction tanımlamalarında

eventId veya transactionId ve timestamp değişkenleri vardır. Bu demek oluyor ki eğer tanımladığınız herhangi bir participant veya asset içinde bu değişkenler bulunuyorsa silmeniz gerekir. System namespace’in .cto dosyasını Github’da bulabilirsiniz.

3. Kaynakları Tanımlamak

3.1. Sınıf Tanımlamaları (Class Definitions)

Hyperledger Modelleme dilinde asset, participant, transaction ve event tanımlamaları sınıf tanımlamasıdır. Daha önce belirttiğim gibi ağdaki kaynaklar eşsiz olmak zorundadır. Hepsinin kendine ait eşsiz bir değişkeni vardır. Event ve transaction sınıflarının system namespace’deki soyut (abstract) sınıflarında eventId ve transactionId değişkenleri bulunduğu için onları eşsiz yapan ekstra bir tanımlayıcıya ihtiyaç duymazlar. Bu yüzden participant ve asset sınıflarını tanımlarken onları eşsiz yapan bir değer belirtmek zorundayız. Aşağıda örnek sınıf tanımlamalarını görebilirsiniz.

asset Sertifika identified by sertifikaId {
    ...
    ...
    ...
}

Yukarıda tanımladığımız Sertifika asset’ini eşsiz yapan değer sertifikaId’dir. Değişken tanımlama kısmına gelmediğimiz için henüz sertifikaId’nin nasıl tanımlanacağını yazmadım. Participant tanımlamasında da aynı söz dizimini kullanılır.

transaction Onay {
    ...
    ...
    ...
}

Yukarıdaki Onay transaction’ınında asset ve participant tanımlamasından farklı olarak yalnızca eşsiz bir değer vermedik. Event tanımlaması da transaction ile aynı formatta olacaktır.

Son olarak sınıflar arasında kalıtım da sağlanabilir. Yani bir sınıfı başka bir sınıfın alt sınıfı olarak tanımlayıp üst sınıfın sahip olduğu tüm değişkenleri alt sınıfta kullanabiliriz. Bu birçok yazılım dilinde bulunan bir özelliktir. Örneğin:

asset Telefon identified by imei {
    o String imei
}
asset AkilliTelefon extends Telefon {
    o String marka
    o String model
}

Yukarıda iki asset tanımladık. Telefon asset’i AkilliTelefon asset’inin üst sınıfı olduğu için imei değişkeni AkilliTelefon’a kalıtım ile geçmiş oldu. Bunu soyut sınıflarla da yapabiliriz. Soyut sınıfların tek farkı diğer sınıflar gibi nesne oluşturmazlar. Yalnızca kalıtımla değişken veren üst sınıf olarak görev alırlar.

3.2. Değişken Tanımlamaları (Variable Definitions) Değişkenler, veya alanlar(fields), sınıfların sahip olduğu özellikleri tanımlamaya yarar.

Değişkenleri iki şekilde tanımlayabiliriz.

  • Owned Property (Sahip olunan değişken): Başındaki ‘o’ harfiyle ifade edilen owned property’ler içinde bulunduğu sınıftan türetilen nesnelere ait olur. Yani bu nesne silindiğinde bu değişkenler de o sınıfla beraber silinir.

  • Related Property (Bağlı Değişken): Başlarındaki –> karakterleriyle ifade edilirler. Bu değişkenler sınıfa ait değildir. Varolan bir değişkenle ilişkilendirilmiş bir alanı ifade eder. Yazılım dillerindeki pointer’ın Hyperledger Composer Modelleme Dilindeki karşılığı olduğu söylenebilir. Yani başında –> karakterleriyle tanımladığımız değişkenler pratikte içinde veri tutmaz. Yalnızca varolan bir değişkenin adresini tutar. Dolayısıyla bu değişkenleri barındıran sınıflar silindiğinde asıl değişken silinmez.

Aşağıda modelleme dilindeki olası değişken tiplerini göreceksiniz:

asset OlasiTumDegiskenler identified by id {

    // Standart UTF8 String değişken.
    o String id;
    // Default değer verebiliyoruz.
    o String paraBirimi default="TL"
    // Numerik değerlere aralık verebiliyoruz.
    o Integer yas range[18,]

    // Dizi tanımlayabiliriz.
    o Integer[] integerArray
    // 64 bit Double değişken.
    o Double ortalama
    // 64 bit Long değişken.
    o Long not
    // Regex pattern ile kısıtlayabiliriz.
    o String isim regex = [a-zA-Z]
    // Boolean değer.
    o Boolean isTrue
    // Tarih.
    o DateTime createdDate
    // Opsiyonel değişken
    o DateTime updatedDate optional
}

3.2. Numaralandırılmış Türler (Enumerated Types)

Yalnızca n adet olası değeri olan tiplerdir. Örneğin haftanın günleri yalnızca 7 tane olabilir. Haftanın günlerine ait enum’ımızı tanımlayalım:

enum HaftaninGunu {
  o PAZARTESI
  o SALI
  o CARSAMBA
  o PERSEMBE
  o CUMA
  o CUMARTESI
  o PAZAR
}

Bu enum’ın sınıf içindeki kullanımı da aşağıdaki gibidir.

asset Etkinlik identified by id {
  o String id
  o HaftaninGunu etkinlikGunu
}

3.2. Konseptler (Consepts)

Konseptler, asset, participant veya transaction olmayan soyut sınıflardır. Anlatmak yerine kod üzerinde göstermek daha anlaşılır olacağından iki örnek vereceğim.

concept AdresBilgisi {
  o String SokakCadde
  o String Mahalle
  o String Sehir
  o String Ilce
  o String Semt
  o String BinaNo
  o String KapiNo
}
participant Personel identified by tc {
  o String tc
  o AdresBilgisi adresBilgisi
}

Bu birinci örnek. Diğer örnek de concept’ler arasındaki kalıtım üzerine.

abstract concept AdresBilgisi {
    o String SokakCadde
    o String Mahalle
    o String Sehir
    o String Ilce
    o String Semt
    o String BinaNo
    o String KapiNo
}

concept YabanciAdres extends AdresBilgisi {
    o String Ulke
}

3.3. İlişkiler (Relationships)

Composer’da ilişkiler, üç bileşenden oluşan veri gruplarıdır.

  • Namespace
  • Tip adı
  • Nesnenin tanımlayıcı (identifier)

Örneğin

org.hyperledgerturkiye.ornekuygulama.alimSatim.Satici#12345678901

yazdığımızda

  • org.hyperledgerturkiye.ornekuygulama.alimSatim namespace’inde bulunan,
  • Satici participantına ait,
  • 12345678901 TC Kimlik numaralı kişiyi referans göstermiş oluyoruz.

4. Import

Diğer namespace’lerden kaynak almak için import anahtar kelimesini kullanırız. Bunun için .cto dosyamızın başına

import org.hyperledgerturkiye.muhasebe.Fatura

şeklinde bir tanımlama yaparız. Eğer bir namespace içindeki her şeyi istersek de

import org.hyperledgerturkiye.muhasebe.*

yazarız.

Kaynaklar