API Dokümantasyonu
Hospital Storage, AWS S3 protokolüyle tam uyumlu bir nesne depolama API'si sunar. Mevcut S3 istemcileri, SDK'lar ve araçlar doğrudan çalışır — yalnızca endpoint URL'i değiştirin.
X-Request-ID, x-amz-request-id ve x-amz-id-2 header'larını içerir. Destek taleplerinde bu değerleri paylaşın.Kimlik Doğrulama
Tüm korumalı endpoint'ler AWS Signature V4 gerektirir. Sunucu saati ile ±15 dakika tolerans uygulanır.
Authorization: AWS4-HMAC-SHA256 Credential=<ACCESS_KEY>/<YYYYMMDD>/tr/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=<hex_signature>
| Header | Açıklama |
|---|---|
| Authorization | AWS4-HMAC-SHA256 formatında imza |
| X-Amz-Date | ISO8601 — örn: 20240115T120000Z |
| X-Amz-Content-Sha256 | Body SHA-256 hash'i |
| Host | Sunucu adresi |
# Bir kez çalıştır aws configure set aws_access_key_id ERISIM_ANAHTARINIZ aws configure set aws_secret_access_key GIZLI_ANAHTARINIZ aws configure set default.region tr aws s3 ls --endpoint-url http://localhost:8080
Hata Yanıtları
{ "error": { "code": "NoSuchBucket", "message": "bucket bulunamadi" } }
| HTTP | Kod | Açıklama |
|---|---|---|
| 400 | InvalidRequest | Eksik veya hatalı parametre |
| 403 | AccessDenied | Geçersiz imza veya yetersiz yetki |
| 404 | NoSuchBucket / NoSuchKey | Kaynak bulunamadı |
| 409 | BucketAlreadyExists / ObjectLocked | Çakışma veya WORM kilidi |
| 429 | RateLimitExceeded | 100 req/s tenant limiti aşıldı |
| 503 | StorageFull / ServiceUnavailable | Disk >%95 veya bağımlılık hatası |
| 503 | LeaderElectionInProgress | Cluster lider seçimi — 2s bekle, tekrar dene |
Roller
Retry-After header'ı gelir.Bucket İşlemleri
{ "buckets": [{ "name": "xray-arsiv", "created": "2024-01-15T10:00:00Z" }] }
Bucket adı: [a-z0-9][a-z0-9-]{1,61}[a-z0-9]
| Query | Açıklama |
|---|---|
| ?cors | CORS konfigürasyonu (body: JSON) |
| ?policy | Bucket policy (body: JSON) |
aws s3 mb s3://xray-arsiv --endpoint-url http://localhost:8080
(boş body)
| Query | Varsayılan | Açıklama |
|---|---|---|
| prefix | — | Ön ek filtresi: 2024/xray/ |
| delimiter | — | Klasör ayracı: / |
| max-keys | 1000 | Maks nesne sayısı |
| continuation-token | — | Sayfalama token'ı |
| ?uploads | — | Aktif multipart upload'ları listele |
{ "objects": [{ "key": "2024/hasta_001.dcm", "size": 2048576, "etag": "\"d41d...\"" }] }
{ "enabled": true, "mode": "COMPLIANCE", "retention_days": 2555 }
{ "rules": [{ "id": "7-yil", "expiration_days": 2555, "enabled": true }] }
Nesne İşlemleri
Anahtar slash içerebilir: 2024/xray/hasta.dcm. Tüm nesneler AES-256-GCM ile otomatik şifrelenir.
| Header | Zorunluluk | Açıklama |
|---|---|---|
| Content-Length | zorunlu | Body boyutu (byte) |
| Content-Type | opsiyonel | Örn: application/dicom |
| x-amz-meta-* | opsiyonel | Özel metadata: x-amz-meta-patient-id: 123 |
{ "etag": "\"d41d8cd...\"", "version_id": "v1710076920-abc123" }
aws s3 cp hasta.dcm s3://xray-arsiv/2024/hasta.dcm --endpoint-url http://localhost:8080
| Query | Açıklama |
|---|---|
| ?versionId=... | Belirli bir versiyonu indir |
| ?versions=true | Tüm versiyonları listele |
| Header | Açıklama |
|---|---|
| ETag | Nesne MD5 hash'i |
| x-amz-version-id | Version ID |
| x-amz-server-side-encryption | AES256 |
| x-amz-meta-* | Yüklenirken eklenen özel metadata |
Body olmadan tüm metadata header'larını döner. Büyük dosyaların varlık kontrolü için idealdir.
WORM/Object Lock aktif nesneler silinemez — ObjectLocked hatası döner.
| Query | Açıklama |
|---|---|
| ?versionId=... | Belirli bir versiyonu sil |
<Delete><Object><Key>2024/hasta_001.dcm</Key></Object></Delete>
| Query | Zorunluluk | Açıklama |
|---|---|---|
| bucket | zorunlu | Bucket adı |
| key | zorunlu | Nesne anahtarı |
| expires | opsiyonel | Saniye — varsayılan 300, maks 604800 |
{ "url": "http://host:8080/presign/eyJ...", "expires_at": "2024-03-10T15:30:00Z" }
Multipart Upload
5 GB üzeri dosyalar için. Her parça en az 5 MB olmalı (son parça hariç).
{ "upload_id": "mpu-abc123" }{ "etag": "\"abc123\"", "part_number": 1 }{ "parts": [{ "part_number": 1, "etag": "\"abc\"" }] }Upload'u iptal eder, yüklenen tüm parçaları siler.
Sistem Endpoint'leri
{ "status": "ok", "version": "v62", "is_leader": true,
"checks": { "redis": "ok", "postgres": "ok", "disk_used_pct": "34.2%", "nats": "ok" } }
Prometheus text formatında sistem metrikleri. Grafana ile doğrudan kullanılabilir.
Admin Endpoint'leri
{ "access_key": "admin", "role": "super_admin", "tenant_id": "system" }| Query | Varsayılan | Açıklama |
|---|---|---|
| format | csv | csv veya json |
| from | 30 gün önce | RFC3339: 2024-01-01T00:00:00Z |
| to | şimdi | RFC3339 |
| tenant | — | Tenant filtresi (super_admin) |
| action | — | PUT, GET, DELETE, LOGIN... |
| limit | 10000 | Maks 50000 |
{ "total_runs": 48, "deleted_bytes_human": "2.3 GB", "last_run_at": "2024-03-10T14:00:00Z" }{ "old_master_key_hex": "<64 karakter hex>" }
Tüm nesne DEK'lerini eski key ile çözer, yeni key ile şifreler. Yeni key sunucu yeniden başlatılmadan önce yerinde olmalıdır.
AWS CLI
# Konfigürasyon aws configure set aws_access_key_id ERISIM_ANAHTARINIZ aws configure set aws_secret_access_key GIZLI_ANAHTARINIZ aws configure set default.region tr # Kısayol alias s3h="aws s3 --endpoint-url http://localhost:8080" # Bucket s3h ls # listele s3h mb s3://xray-arsiv # oluştur # Nesne s3h cp hasta.dcm s3://xray-arsiv/2024/hasta.dcm # yükle s3h cp s3://xray-arsiv/2024/hasta.dcm lokal.dcm # indir s3h ls s3://xray-arsiv/2024/ # listele s3h rm s3://xray-arsiv/2024/hasta.dcm # sil s3h sync ./dosyalar/ s3://xray-arsiv/2024/ # senkronize et # Presign URL (5 dakika) aws s3 presign s3://xray-arsiv/2024/hasta.dcm \ --expires-in 300 --endpoint-url http://localhost:8080
Python — boto3
import boto3 from botocore.client import Config s3 = boto3.client( "s3", endpoint_url="http://localhost:8080", aws_access_key_id="ERISIM_ANAHTARINIZ", aws_secret_access_key="GIZLI_ANAHTARINIZ", region_name="tr", config=Config(signature_version="s3v4") ) # Yükle with open("hasta.dcm", "rb") as f: s3.put_object(Bucket="xray-arsiv", Key="2024/hasta.dcm", Body=f, ContentType="application/dicom", Metadata={"patient-id": "12345678901"}) # Listele resp = s3.list_objects_v2(Bucket="xray-arsiv", Prefix="2024/") for obj in resp.get("Contents", []): print(obj["Key"], obj["Size"]) # Presign URL url = s3.generate_presigned_url("get_object", Params={"Bucket": "xray-arsiv", "Key": "2024/hasta.dcm"}, ExpiresIn=3600) # Multipart (>5 GB) mpu = s3.create_multipart_upload(Bucket="xray-arsiv", Key="buyuk.dcm") parts = [] for i, chunk in enumerate(chunks, 1): p = s3.upload_part(Bucket="xray-arsiv", Key="buyuk.dcm", UploadId=mpu["UploadId"], PartNumber=i, Body=chunk) parts.append({"PartNumber": i, "ETag": p["ETag"]}) s3.complete_multipart_upload(Bucket="xray-arsiv", Key="buyuk.dcm", UploadId=mpu["UploadId"], MultipartUpload={"Parts": parts})
Go — aws-sdk-go-v2
package main import ( "context"; "os" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" ) func newClient() *s3.Client { cfg, _ := config.LoadDefaultConfig(context.Background(), config.WithRegion("tr"), config.WithCredentialsProvider( credentials.NewStaticCredentialsProvider("ANAHTAR", "GIZLI", ""), ), ) return s3.NewFromConfig(cfg, func(o *s3.Options) { o.BaseEndpoint = aws.String("http://localhost:8080") o.UsePathStyle = true }) } func main() { client, ctx := newClient(), context.Background() // Yükle f, _ := os.Open("hasta.dcm"); defer f.Close() client.PutObject(ctx, &s3.PutObjectInput{ Bucket: aws.String("xray-arsiv"), Key: aws.String("2024/hasta.dcm"), Body: f, }) // Listele out, _ := client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{ Bucket: aws.String("xray-arsiv"), Prefix: aws.String("2024/"), }) for _, o := range out.Contents { println(*o.Key) } }