14 Eylül 2023 Perşembe

OAuth2 Authorization Code Grant

Giriş
Sunucu tarafındaki uygulamalar tarafından kullanılır. Yani server-side applications içindir.

Authorization Code Grant Nedir?
Açıklaması şöyle.
The flow works this way, you visit a third-party site and it redirects you to the authorization server's login page, and you log in there, the authorization server redirects you back to the site issuing the authorization code. The client application then uses the authorization code to get the access token for accessing your protected resources on the resource server.
Akış şöyle
     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

Authorization Request
Örnek
/oauth/authorize 
   ?client_id=a17c21ed 
   &response_type=code 
   &state=5ca75bd30 
   &redirect_uri=https://example.com/cb 
   &scope=photos
Açıklaması şöyle
Once the authorization server receives the request it should perform the following steps:
1. Verify user identity for example against access token. The request contains users' consent so it must be secured with user identity.

2. Validate request parameters:
  - client_id should be registered to authorization server with exact redirect_uri
  - response_type specifies which OAuth 2.0 flow is requested; for authorization code flow it should be equal to code
  - state contains a random string generated on the client to be verified against the one returned in response; they should be equal
  - scope contains a list of scopes requested by the client

3. Generate authorization code: This should be a random string secure enough to not be guessed.
4. Store in DB request data: The authorization code and user data (probably from token) to use them while token issuance
Authorization Request İçin Authorization Response
Örnek
Şöyledir Burada authorization code cevabını alıyoruz
https://example.com/cb ?state=txcSDMn3Q5bZ-w32 &code=EVOcNHq7TBVaxVw
Açıklaması şöyle
The authorization response is a redirect back to the client to the redirect_uri specified in the authorization request. The code parameter contains the authorization code and the state originally passed by the client.
Açıklaması şöyle
After successful user authentication, the Authorization Server sends the client Authorization Code. The Authorization Code can be used only once by the client to get access token. It doesn’t matter whether the request by the client was successful or not, once the Authorization Code is consumed by the Authorization Server it cannot be used anymore.
Token Exchange Request - Yani Exchange Authorization Code For Tokens
Şöyledir. Burada backend de de çalışan uygulamamız authorization code + client credentials gönderiyor
/token ?code=EVOcNHq7TBVaxVw &grant_type=authorization_code &redirect_uri=https://example.com/cb &client_id=a17c21ed &client_secret=ZGVmMjMz
Açıklaması şöyle
The /token endpoint receives parameters needed to issue access token:
code contains authorization code generated as a result of authorization request; it's a key by which authorization server should look for data in DB.
grant_type specifies which way the server should issue access tokens; code means the token should be issued based on the authorization code.
client_id and client_secret (or code_verifier in case of using PKCE) are needed to authorize the request since just authorization code validation is not enough because it might be intercepted.
- Get data from DB by the authorization code, the most important of which are user id and scopes requested. Therefore, the access token issued should represent the users and should be limited to scopes they confirmed giving consent.
- Issue tokens (most probably your would like to issue refresh token alongside with access one)
Token Exchange Response 
Şöyledir. Burada access token alıyoruz
{ "token_type": "Bearer", "expires_in": 86400, "access_token": "sjmHG1EywNbSDAelt", "refresh_token": "Qb6kKM4BWPIwq" }
Delegated Authorization vs Federated Authentication
Authorization Code Grant akışına "Delegated Authorization" denilir. Çünkü sadece bir kaynağa (resource) belli bir erişim hakkı veriyoruz. "OpenID Connect" ile ayrıldıkları nokta burası, çünkü "OpenID Connect"  "Delegated Authorization" yerine "Federated Authentication" kullanıyor. Açıklaması şöyle. Yani authorization (yetkilendirme) yerine, authentication (doğrulama) yapılıyor
Note that Federated Authentication is different from Delegated Authorization.

Federated Authentication allows you to login to a site using your facebook or google account.

Delegated Authorization is the ability of an external app to access resources. This use case would be for example Spotify trying to access your google contacts list to import it into Spotify.

OAuth 2.0 was designed primarily for delegated authorization, OpenId Connect is the few additional steps added over OAuth 2.0 to extend OAuth 2.0 for Federated Authentication.
Fark aslında çok basit bir şeyden kaynaklanıyor. Open ID access token'a ilave olarak bir de id_token kullanıyor. Açıklaması şöyle
1. it introduces a completely new token (id_token) with radically different semantics than the OAuth 2.0 access_token and a standardized format that is understood by the Client as opposed to the access_token which is opaque to the Client

2. it "twists" the role of the Client, now becoming the "audience" (or: intended recipient) of a token (i.e. the id_token) whilst the audience of the access_token is still a remote entity (aka. Resource Server) and the Client is only the "presenter" of the latter

The 2nd item is the primary source of confusion between OAuth 2.0 and OpenID Connect.

13 Eylül 2023 Çarşamba

Redis Hash Veri Yapısı

Giriş
Açıklaması şöyle
Redis Hashes offer built-in functionality for sorting and searching data, making it easy to find specific data points or organize data based on certain criteria.

Redis Hashes offers transaction support, allowing you to perform multiple operations on data in a single transaction, ensuring consistency and reducing the risk of data corruption.

Redis Hashes are highly reliable, with built-in data replication and backup features to ensure that your data is always available and recoverable in the event of a failure.

Redis Hashes offer built-in security features, including support for SSL/TLS encryption and password authentication, making it a secure solution for applications that handle sensitive data.
1. HSET
Açıklaması şöyle
The HSET command sets the value of a field in a hash. If the field does not exist, it creates a new field and sets its value. If the field already exists, it overwrites its value.
Örnek
Şöyle yaparız. This command sets the name of user1 to “John”.      
HSET user1 name "John"
2. HGET
Açıklaması şöyle
The HGET command gets the value of a field in a hash. If the field exists, it returns its value. If the field does not exist, it returns nil.
Örnek
Şöyle yaparız. This command gets the name of user1.
HGET user1 name
3. HMSET
Açıklaması şöyle
The HMSET command sets multiple fields in a hash.
Örnek
Şöyle yaparız. This command sets the name, email, and age of user1.
HMSET user1 name "John" email "john@example.com" age 30
4. HMGET
Açıklaması şöyle
The HMGET command gets the values of multiple fields in a hash.
Örnek
Şöyle yaparız. This command gets the name, email, and age of user1.
HMGET user1 name email age
5. HDEL
Açıklaması şöyle
The HDEL command deletes one or more fields in a hash.
Örnek
Şöyle yaparız. This command deletes the age field of user1.
HDEL user1 age
6. HEXISTS
Açıklaması şöyle
The HEXISTS command checks if a field exists in a hash.
Örnek
Şöyle yaparız. This command checks if the name field exists in user1.
HEXISTS user1 name
7. HKEYS
Açıklaması şöyle
The HKEYS command gets all the keys in a hash.
Örnek
Şöyle yaparız. This command gets all the keys in user1.
HKEYS user1
8. HVALS
Açıklaması şöyle
The HVALS command gets all the values in a hash.
Örnek
Şöyle yaparız. This command gets all the values in user1.
HVALS user1
9. HLEN
Açıklaması şöyle
The HLEN command gets the number of fields in a hash.
Örnek
Şöyle yaparız. This command gets the number of fields in user1.
HLEN user1
10. HINCRBY
Açıklaması şöyle
The HINCRBY command increments the value of a field in a hash by a specified amount.
Örnek
Şöyle yaparız. This command increments the age of the user1 by 5.
HINCRBY user1 age 5
11. HINCRBYFLOAT
Açıklaması şöyle
This command increments the value of a floating-point field in a hash by a specified amount.
Örnek
Şöyle yaparız. This command increments the weight of user1 by 2.5
HINCRBYFLOAT user1 weight 2.5
Örnek
Şöyle yaparız
// create a Redis Hash named “customer1” using the HMSET
HMSET customer1 name "John Doe" email "johndoe@example.com" address "123 Main St"
  phone "555-1234" orders "5"

// use the HGET command to get the name and email of the customer
HGET customer1 name
//Output: “John Doe”

HGET customer1 email
// Output: “johndoe@example.com”

// use the HSET command to update the phone number of the customer
HSET customer1 phone "555-5678"

// use the HINCRBY command to increment the order count for the customer
HINCRBY customer1 orders 1

// se the HMGET command to get the customer’s address and order history
HMGET customer1 address orders
// Output: [“123 Main St”, “6”] 

// use the HDEL command to delete the customer’s phone number
HDEL customer1 phone

// use the HEXISTS command to check if a field exists in the customer1 hash
HEXISTS customer1 email
// Output: 1 (true)

HEXISTS customer1 phone
// Output: 0 (false)



Engineering Manager - Managing People, Developing Talent

Şimdi Ne Yapmalı
Açıklaması şöyle
Having the hard conversation when two engineers have a conflict that's affecting the whole team. Figuring out that someone is burned out before they quit, not after. Helping a mid-level engineer figure out what they actually want in their career, not just what the promotion criteria say. Shielding the team from organizational chaos that would otherwise eat their focus.
Eskiden Engineering Manager Ne İş Yapardı?
Açıklaması şöyle
EM was the hub of everything. 
- He ran standups. 
- He ran retros. 
- He ran planning. 
- He tracked velocity. 
- He reported status to leadership. 
- He handled 1:1s with every engineer on the team. 
- He managed hiring. 
- He dealt with HR stuff when someone had an issue.
Bunların bir kısmını artık yapmaya gerek yok.
Standup
Açıklaması şöyle
We stopped doing synchronous standups eight months ago. We post async updates in Slack. A bot summarizes them. Nobody misses the meeting. Our EM used to facilitate standups and now there's nothing to facilitate.
Velocity tracking, Status reporting
Açıklaması şöyle
Velocity tracking. We have a Linear dashboard that shows velocity, cycle time, PR throughput, deployment frequency. Updated in real time. Our EM used to spend hours every sprint compiling this stuff into slides for leadership. Now the VP just looks at the dashboard directly. The middleman step disappeared.

Status reporting. Same thing. Leadership has access to the same dashboards we do. They can see what's in progress, what's blocked, what shipped. Our EM used to translate this into narrative form for weekly updates. Two months ago the VP told him to stop sending the weekly email because "I can see everything in Linear."
Sprint planning
Açıklaması şöyle
We still do this. But the tech lead runs it now. He knows the codebase better than our EM does. He knows which tasks are actually complex and which ones look complex but aren't. Our EM sits in the meeting but mostly listens. I watched him last sprint. He spoke three times in 90 minutes.
1:1s
Açıklaması şöyle
We still do this. But the tech lead runs it now. He knows the codebase better than our EM does. This is the one thing that hasn't been replaced. Our EM still does 1:1s with everyone. But I'll be honest. Half the engineers on the team treat 1:1s as a formality. They say things are fine, talk about something surface level for fifteen minutes, and go back to coding. The 1:1s that actually help are the ones where someone is struggling or frustrated. Those happen maybe once a month per engineer. The rest are calendar filler.
Hiring
Açıklaması şöyle
We haven't hired anyone in seven months. So this whole category of work just doesn't exist right now.
Otomasyon
Açıklaması şöyle. Yani bazı şeylerin otomasyona geçmesi için çaba sarf eder
... as an engineering manager (EM) on the Interfaces team in October 2022, I was focused on organizing the work in our Jira board and setting up automation to streamline the software development lifecycle.
Teknik Lider vs Engineering Manager
Şeklen şöyle

Açıklaması şöyle
- The manager should delegate the team technical leadership to the technical lead and get out of the weeds. Managers should not fall off the bus and forget decades of technical background. However, managing is fundamentally a policy job, and managers should respect boundaries. Anything else is micromanaging and breaking trust.
- The technical lead should delegate the career, team growth, communications, and coordination work to the engineering manager and focus on architecture, technical choices, technical direction, and helping to drive execution.

11 Eylül 2023 Pazartesi

SSTable - Sorted String Table

Giriş
Açıklaması şöyle
- SSTable (Sorted String Table) is a file format used in various storage systems, particularly in LSM (Log-Structured Merge) trees, for storing and accessing sorted key-value pairs on disk.
- SSTables are designed for efficient read operations, especially range queries, and are commonly used in systems that require high-performance data retrieval.
immutable on-disk “Map” implementation
SSTable Bileşenleri Nelerdir?
Açıklaması şöyle
A Sorted String Table consists of two main files, one with actual data and another with an index to speed up look-ups.

LSM-Tree veya Log-Structured Merge Tree

LSM Tree Ne İçindir?
LSM-Tree hızlı yazma içindir. Açıklaması şöyle
- LSM (Log-Structured Merge) tree is a data structure designed for efficient write-intensive workloads, commonly used in storage systems and database engines.
- It offers high write throughput and efficient disk space utilization by leveraging sequential write operations and periodic merging of data.
LSM Tree Bileşenleri
Açıklaması şöyle
We can distinguish two key components of the tree, the in-memory buffer, also called Memtable, and the disk-resident tables. The main idea is to accept writes to the in-memory part of the tree, and to flush them periodically, or when a certain size is met.

A key aspect of this structure is ordering, indeed, keys are sorted both in RAM and on disk, enabling logarithmic searches.
Yani LSM Tree iki kısımdan oluşur
1. Memtable
2. Disk Resident Tables

1. Memtable
Sıralı yani sorted olması gerekir.  Red-Black Tree , AVL Tree Skip List gibi bir veri yapısı kullanılabilir

2. Disk Resident Tables
 SSTable - Sorted String Table  veri yapısı kullanılır

3. Yani
Skiplist + SSTable  kullanılabilir. 
 Skip List + SSTable kullanılabilir

Compaction
Açıklaması şöyle
Level 0 segments are periodically merged into Level 1 segments. This process is called compaction
B-Tree vs LSM-Tree
Açıklaması şöyle
The biggest difference is probably this:
  -B-Tree enables faster reads
 - LSM-Tree enables fast writes

6 Eylül 2023 Çarşamba

GitHub Actions Workflow

Örnek
Bir repository yaratırız ve .github/workflows/create-spring-boot-repository.yaml  dosyasını yaratırız. Dosya şöyle. Dosyanın çalışması için bir personal access token yaratılır ve secret olarak kaydedilir
name: Create Spring Boot Repository

on:
  workflow_dispatch:
    inputs:
      name:
        description: 'Repository Name'
        required: true
      description:
        description: 'Repository Description'
        required: true
      private:
        description: 'Private Repository'
        required: true
        default: 'false'
      groupId:
        description: 'Maven Group ID'
        required: true
      artifactId:
        description: 'Maven Artifact ID'
        required: true
      springBootVersion:
        description: 'Spring Boot Version'
        required: true
        default: '3.0.0'
      mainClassName:
        description: 'Main Class Name'
        required: true
        default: 'Application'
      userName:
        description: 'User Name'
        required: true
      userEmail:
        description: 'User Email'
        required: true
        
jobs:
  create-spring-boot-repository:
    runs-on: ubuntu-latest

    steps:
    - name: Step 1 - Checkout code
      uses: actions/checkout@v3

    - name:  Step 2 - Generate Spring Boot Project with Maven Wrapper
      run: |
        curl https://start.spring.io/starter.zip -o project.zip \
             -d type=maven-project \
             -d bootVersion=${{ github.event.inputs.springBootVersion }} \
             -d groupId=${{ github.event.inputs.groupId }} \
             -d artifactId=${{ github.event.inputs.artifactId }} \
             -d name=${{ github.event.inputs.mainClassName }}
        unzip project.zip -d spring-boot-project
        cd spring-boot-project
        mvn wrapper:wrapper

    - name: Step 3 - Create new GitHub repository
      run: |
        curl -X POST -H "Authorization: token ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}" \
             -d '{
                  "name": "${{ github.event.inputs.name }}",
                  "description": "${{ github.event.inputs.description }}",
                  "private": ${{ github.event.inputs.private }}
                }' \
             https://api.github.com/user/repos

    - name: Step 4 - Push to new repository
      run: |
        cd spring-boot-project
        echo "# ${{  github.event.inputs.name }}" >> README.md
        git config --global user.email "${{ github.event.inputs.userEmail }}"
        git config --global user.name "${{ github.event.inputs.userName }}"
        git init
        git add .
        git add README.md
        git commit -m "first commit"
        git branch -M main
        git remote add origin git@github.com:${{ github.actor }}/${{ github.event.inputs.name }}.git
        git remote set-url origin https://x-access-token:${{ env.GH_PERSONAL_ACCESS_TOKEN }}@github.com/${{ github.actor }}/${{ github.event.inputs.name }}
        git push -u origin main  # Push to 'main' branch
      env:
        GH_PERSONAL_ACCESS_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}

Github Actions - maven

Örnek - checkout + Set up JDK + Build
GitHub'daki repository'ye gidilir. Üst başlıktaki "Actions" düğmesine tıklanır. "New workflow" düğmesine tıklanır. "Java with Maven" düğmesine tıklanır. Şeklen şöyle

Karşımıza çıkan dosya şöyle. Dosya yolu şöyle "myrepository/.github/workflows/maven.yaml"
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/ building-and-testing-java-with-maven

name: Java CI with Maven

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
        cache: maven
    - name: Build with Maven
      run: mvn -B package --file pom.xml
Örnek - checkout + Set up JDK + Build
Şöyle yaparız
name: Java CI with Maven

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Set up JDK 11
      uses: actions/setup-java@v2
      with:
        java-version: '11'
        distribution: 'adopt'

    - name: Build with Maven
      run: ./mvnw clean install

Örnek
Push işleminden sonra testleri çalıştırıp, Docker'a image push'lamak için şöyle yaparız
name: CI/CD Pipeline

## The following codes trigger the pipeline when the code is pushed on the main branch.
on:
  push:
    branches: [ main ]

jobs:
  ## First Job: Test
  test:
    name: Unit Test
    ## Run on Ubuntu using the Latest Version
    runs-on: ubuntu-latest
    ## Job's steps
    steps:
      - uses: actions/checkout@v1
      ## Set up JDK 11
      - name: Set up JDK
        uses: actions/setup-java@v1
        with:
          java-version: '11'
      ## Set up Maven Cache
      - name: Cache Maven packages
        uses: actions/cache@v1
        with:
          path: ~/.m2
          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
          restore-keys: ${{ runner.os }}-m2
      ## Run Maven Tests
      - name: Run Tests
        run: mvn -B test

  ## Second Job: Build and Push
  build-and-push:
    name: Build and Push
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'adopt'
          cache: maven
      - name: Build with Maven
        run: mvn -B package --file pom.xml

      - name: Dockerize & Push Docker Image
        uses: mr-smithers-excellent/docker-build-push@v5
        with:
          ## Docker Hub Account Number / Repository Name
          image: 19812381238/product-microservice
          tags: latest
          registry: docker.io
          ## Dockerfile Path
          dockerfile: product/Dockerfile
          ## Keep these secrets on GitHub for the privacy of our information
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
Örnek
Github sayfasına release yapmak için şöyle yaparız
name: Java CI to create and upload release on pull request
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

env:
  build-number: ${GITHUB_RUN_NUMBER}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'temurin'
          cache: 'maven'
      - run: mvn clean package -DskipTests
      - run: mkdir staging && mv target/yb-workload-sim.jar target/yb-workload-sim-${{ env.build-number }}.jar && cp target/*.jar staging
      - uses: actions/upload-artifact@v3
        with:
          name: Package
          path: staging
          retention-days: 1
      - uses: marvinpinto/action-automatic-releases@latest
        with:
          repo_token: "${{ secrets.YOUR-GITHUB-TOKEN }}"
          automatic_release_tag: "${{ github.run_number }}"
          title: "Automated Build ${{ github.run_number }}"
          prerelease: true
          files: staging/*.jar