21 Şubat 2023 Salı

Devops Terms

CI CD Pipelie

Pipeline kodumuzu otomatik olarak build eder, test eder ve her hangi bir clouda deploy eder.


Docker İmages

Her Image bir Base Image'dan türemektedir. Tüm Base Image'lar içerisinde Linux'un çok küçük bir Core'unu bulundurur. Yani kısaca her Image bir işletim sistemi barındırır ve biz container ayağa kaldırdığımızda o container içerisinde çalışan Image bir işletim sistemi üzerinde çalışır. Dolayısı ile o işletim sistemine bağlanabiliriz ve hatta kendi komutlarımızı onun üzerinde çalıştırabiliriz.


Kubernetes

Yazmış olduğumuz kodu dockerize edip bir image içerisine koyuyoruz. Bu imageden bir adet container oluşturup bunu kubrnetes pod içerisine koyuyoruz. Pod içerisinde secrets, maps yada volumes mount ediyoruz. Podun önüne kubernetes servis koyuyoruz bu servise de load balancer kullanan ingress aracılığıyla erişiyoruz.

Aggregates

  •  Aggregateler, Entity ve Value Objectlerin kümesidir.
  • Entity ve Value Objectlerin tek bir transaction içerisinde yönetilmesini sağlar. Dolayısıyla Entity ve Value Objectlerin tutarlılığından sorumludur. 
  • Aggregateler bir Id ye sahiptir ve aynı zamanda bir Entitydir.
  • Bir aggregate, başka bir aggregateyi navigation property olarak içermemelidir. Sadece Id sini içermelidir.
𝗛𝗼𝘄 𝘁𝗼 𝗗𝗲𝘁𝗲𝗿𝗺𝗶𝗻𝗲 𝗶𝗳 𝗮𝗻 𝗢𝗯𝗷𝗲𝗰𝘁 𝗦𝗵𝗼𝘂𝗹𝗱 𝗕𝗲 𝗧𝗿𝗲𝗮𝘁𝗲𝗱 𝗮𝘀 𝗮𝗻 𝗔𝗴𝗴𝗿𝗲𝗴𝗮𝘁𝗲 𝗥𝗼𝗼𝘁?🌟

In Domain-Driven Design, an Aggregate Root is a fundamental concept representing the entry point to an aggregate.

a cluster of related objects treated as a single unit for data management and consistency.

I often use a simple question to determine the Aggregate Root: 𝗦𝗵𝗼𝘂𝗹𝗱 𝗱𝗲𝗹𝗲𝘁𝗶𝗻𝗴 𝘁𝗵𝗲 𝗔𝗴𝗴𝗿𝗲𝗴𝗮𝘁𝗲 𝗥𝗼𝗼𝘁 𝗮𝗹𝘀𝗼 𝗿𝗲𝗾𝘂𝗶𝗿𝗲 𝗱𝗲𝗹𝗲𝘁𝗶𝗻𝗴 𝘁𝗵𝗲 𝗼𝗯𝗷𝗲𝗰𝘁𝘀 𝗶𝗻 𝘁𝗵𝗲 𝗮𝗴𝗴𝗿𝗲𝗴𝗮𝘁𝗲?

Consider an e-commerce system with entities like Order, OrderItem, and Customer. The Order serves as the Aggregate Root because deleting it should also delete OrderItems, which are meaningful only within the context of an Order. On the other hand, the Customer entity remains valid even after the deletion of the Order, indicating that it's not a good candidate to be inside the aggregate root.


İmplementasyon

  • Domain layera MediatR linki üzerindeki nuget paketi indirilir.

  • Doman > Primitives  altına  Entity.cs ,IDomainEvent.cs ve AggregateRoot.cs  isminde üç adet class oluşturulur.

  • Entity.cs
  public abstract class Entity : IEquatable<Entity>
    {
        protected  Entity(Guid id)
        {
            Id = id;
        }
        protected Entity()
        {

        }
        public Guid Id { get; private init; }

        public override bool Equals(object? obj)
        {
            if(obj is null)
            {
                return false;
            }

            if(obj.GetType() != GetType())
            {
                return false;
            }

            if(obj is not Entity entity)
            {
                return false;
            }
            return entity.Id == Id;
        }

        public bool Equals(Entity? other)
        {
            if (other is null)
            {
                return false;
            }

            if (other.GetType() != GetType())
            {
                return false;
            }

            return other.Id == Id;
        }
        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }

        public static bool operator ==(Entity? first, Entity? second)
        {
            return first is not null && second is not null && first.Equals(second); 
        }
        public static bool operator !=(Entity? first, Entity? second)
        {
            return !(first == second);
        }
    }
  • IDomainEven.cs
    public interface IDomainEvent : INotification
    {
    }
  • AggregateRoot.cs
    public abstract class AggregateRoot : Entity
    {
        private readonly List<IDomainEvent> _domainEvents = new();
        public AggregateRoot(Guid id) 
            : base (id)    
        {

        }
        protected AggregateRoot() { }

        public IReadOnlyCollection<IDomainEvent> GetDomainEvents() => _domainEvents.ToList();
        public void ClearDomainEvents() => _domainEvents.Clear();
        protected void RaiseDomainEvent(IDomainEvent domainEvent)
        {
            _domainEvents.Add(domainEvent);
        }
    }

17 Şubat 2023 Cuma

Portainer

docker-compose.yml isminde bir file oluşturup aşağıdaki komutları içine yapıştırıyoruz. Daha sonra cmd consoldan " docker-compose up  " diyerek portaineri ayağa kaldırıyoruz.

version: '3.8'
services:
  portainer:
    image: portainer/portainer-ce
    restart: always
    container_name: portainer
    ports:
      - "8000:8000"
      - "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
volumes:
  portainer_data:


reference

https://medium.com/devopsturkiye/docker-ile-portainer-kurulumu-ve-portainera-h%C4%B1zl%C4%B1-bak%C4%B1%C5%9F-2fdcf2b31deb


Jenkins

Jenkins bir CI(continious integration) aracıdır. Continous Entegrationun  en büyük amacı hataları hızlı bir şekilde ortaya çıkarmasıdır.  Jenkins Projelerin deploy, build ve test işlemlerinin otomatik bir şekilde gerçekleşmesini sağlar. Bunları belli aralıklarla yapıp ve duruma göre bize mail, notification veya feedback verecek şekilde ayarlamalar yapabiliyoruz.


Jenkins nasıl çalışır ? 

Developer git aracılığıyla kodunu  repositoye( Github, Gitlab vs.) commitler. Jenkins sürekli olarak repositoyi dinlemektedir. Kod commit edildiği an bunu yakalar, kodu repositoryden alır ve Build'i tetikler.  Build başladığında, bittiğinde veya bir sorun olduğunda size notification gönderiyor olacaktır. Şayet build kısmınız başarılı olduysa test kısmına geçirir. Test kısmında da hata bulunamazsa deploy edilir.



Pipeline

İşlerin ardışık bir sırada yapılması, bir işlemin çıktısının sonraki gelen işlemin girdisi olması anlamına gelmektedir. Bu yüzden bir sonraki evreye geçebilmek için önceki evrenin başarılı bir şekilde tamamlanmış olması gerekiyor. Adımlar arasında geri bildirimler de vardır.



Stage

Stage , pipeline içerisinde yer alan fazları ifade eder. Mesela aşağıdaki fotoğrafta gördüğünüz Build bir stage’dir. Step ise stage içerisinde yer alan adımları ifade eder. Stage ve step’leri oluştururken pipeline script’i kullanıyoruz.



Docker Jenkins Kurulumu

docker run -p 8080:8080 -p 50000:50000 -v /var/tmp/jenkins_home:/var/jenkins_home -u root jenkins/jenkins

http://localhost:8080/ portuna gidersek jenkinsin ayağa kalktığını göreceğiz. Ayağa kalktığında aşağıdaki ekranı görmüş olacağız. 

Jenkins ilk ayağa kalktığında bize bir şifre vermektedir. Bu şifreyi terminalden alıp buraya yukarıdaki Administrator password alanına yapıştırıyoruz.


refrenece



13 Şubat 2023 Pazartesi

Expression<𝐅𝐮𝐧𝐜<>>

Func ve Expression

Func değer döndüren bir metot'tur. Kısacası Func sadece bir değer döndüren metodu bir değişkende tutmamızı sağlayan bir tiptir.


IEnumerable<T> Func<T> kabul ederken IQueryable<T> Expression<Func<T>> kabul etmektedir.

Func<T> vs. Expression<Func<T>>

  • The IEnumerable version: Where(Func<T, bool> predicate)
  • The IQueryable version: Where(Expression<Func<T, bool>> predicate)

Kullanım Şekilleri ikisinde de aynıdır.
IEnumberable version: .Where(x => x.property == "value")
IQueryable version: .Where(x => x.property == "value")




Lazy/Eager/Explicit Loading

Entityler içerisinde bulunan ilişkili verilerin yüklenmesini yönetmek için Lazy, Eager ve Explicit olmak üzere 3 yöntem vardır.

Entity framework’ün ilişkili davranışı yüklemedeki default davranışı eager loadingdir. Bu yüzden entity framework üzerinde lazy loading yapmak istiyorsak, nuget üzerinden EntityFrameworkCore.Proxies paketini yüklemeliyiz.


User ve Order tablosu arasına user 1 .......n Order ilişkisi olduğunu düşünelim.



Lazy Loading

Lazy loading uygulamak için EntityFrameworkCore.Proxies nuget paketini indiriyoruz.Ve startup.cs üzerinde aşağıdaki configurasyonu yapıyoruz.


Entity framework üzerinde yükleme türü olarak lazy loading kullanıldığında, ilişkili veriler yüklenmez. Entity sınıfı üzerinden ne zaman ilişkili bir alana erişilmek istenirse, o zaman veri tabanına ilişili tabloya özel yeni bir sorgu atılarak ilişkili veriler getirilir.


  • Yukarıda ilk satır için sadece users getirilmiştir. Daha sonra user.Orders querysi için veritabanına yeni bir sorgu atılmıştır ve Orders getirilmiştir.
  • lazy loading kullanılan işlemlerde, her bir ilişkili alana erişim isteğinde veri tabanına yeni bir query gönderilecektir. Fazla kayıt olan işlemlerde bu performans sorunu doğurabilir. İkinci sorguyu ilişkili tabloya atılıyor buna dikkat edelim yani orders tablosuna.




Eager Loading

Eager loading, veri tabanından kayıtlar çekilirken getirilmesi istenen ilişkili alanların da beraberinde getirilme işlemidir. Eager loading kullanarak ilişkili alanların tek sorguda getirilmesini sağlayabiliyoruz, ancak sonrasında getirilmemiş ilişkili alanlara erişme isteğinde veriler getirilmeyecektir.

Getirilmesi istediğimiz alanları “Include” methodu ile belirtebiliyoruz.




Explicit Loading

Explicit loading için, aslında lazy ve eager loadingin karışımı diyebiliriz. Veri tabanından veriler çekilirken, hiç bir ilişkili alan getirilmez. Eager loadingden farkı, ilişkili alanları sonradan yükleyebilmemizdir.

İlk satırı çalıştırdığımızda, belirtildiği gibi sadece user tablosuna sorgu atılmakta. İkinci satırı çalıştırdığımızda, bu user nesnesi için ilişkili siparişleri entity üzerinde yüklemekte.

Aynı lazy loadingde olduğu gibi order tablosuna ayrı bir sorgu oluşturuldu ve ilgili siparişler getirildi. Buradaki kilit nokta, ilişkili dataların yüklenmesi komutunu bizim kendimizin vermiş olması.




REFERENCE