Delphi'de gRPC Üzerinden Google Cloud Storage

· Bileşenler

Google Cloud Storage, Google'ın nesne depolama hizmetidir. Veriler bucket'larda bulunur ve her bucket, yüklediğiniz, listelediğiniz, okuduğunuz ve sildiğiniz nesneleri (dosyaları) tutar. Çoğu Delphi kodu ona JSON REST API aracılığıyla ulaşır, ancak depolama hizmeti, HTTP/2 üzerinden Protocol Buffers konuşan bir gRPC API'si de sunar. sgcWebSockets Enterprise, TsgcGRPCClient üzerine kurulu türlü bir Cloud Storage gRPC istemcisi içerir, böylece bucket'ları ve nesneleri Delphi ve C++Builder'dan harici bir çalışma zamanı veya oluşturulmuş saplama (stub) olmadan yönetebilirsiniz.

Nasıl çalışır

gRPC Storage API'si storage.googleapis.com:443 adresinde bulunur ve google.storage.v2.Storage hizmetini konuşur. sgcWebSockets zaten eksiksiz bir HTTP/2 yığını içerir, bu nedenle türlü istemci, TLS etkin bir TsgcHTTP2Client taşımasının üzerine oturur. TsgcGRPCClient, gRPC çerçevelemesini, üst bilgileri ve zaman aşımı işlemeyi yapar, HTTP/2 akışını açar ve yanıt ile trailer'ları bir TsgcGRPCResponse'a geri ayrıştırır.

Türlü katman sgcGRPC_Google_Storage biriminde bulunur. Size, kendilerini Protocol Buffers'a ve Protocol Buffers'tan serileştiren TsgcGRPCStorageListBucketsRequest, TsgcGRPCStorageListObjectsResponse ve TsgcGRPCStorageBucket gibi istek ve yanıt sınıfları verir. Türlü özellikleri ayarlarsınız, istek yükünü almak için ToBytes'i çağırırsınız, onu Call ile gönderirsiniz ve yanıtı LoadFromBytes ile yüklersiniz. Protobuf derleyicisi yok, elle yazılmış alan etiketleri yok.

Kimlik doğrulama, bir Google hizmet hesabı kullanır. İstemci, hizmet hesabı anahtarından bir JSON Web Token imzalar ve onu gRPC authorization meta verisinde bir Bearer belirteci olarak sunar; bu, Google Cloud'un sunucudan sunucuya çağrıları yetkilendirmesinin standart yoludur.

Taşımanın kurulması

Bir gRPC kanalı yalnızca bir HTTP/2 bağlantısıdır. TLS açıkken bir TsgcHTTP2Client'ı depolama uç noktasına yönlendirin, ardından onu TsgcGRPCClient'a ekleyin ve ikili Protocol Buffers içerik türünü seçin.

uses
  sgcHTTP2_Client, sgcGRPC_Client, sgcGRPC_Types, sgcGRPC_Google_Storage;

var
  HTTP2: TsgcHTTP2Client;
  GRPC: TsgcGRPCClient;
begin
  HTTP2 := TsgcHTTP2Client.Create(nil);
  HTTP2.Host := 'storage.googleapis.com';
  HTTP2.Port := 443;
  HTTP2.TLS  := True;

  GRPC := TsgcGRPCClient.Create(nil);
  GRPC.Client := HTTP2;
  GRPC.ChannelOptions.ContentType := grpcProto;
  GRPC.ChannelOptions.Compression := grpcNoCompression;

  HTTP2.Active := True;
end;

Bir hizmet hesabıyla kimlik doğrulama

Hizmet hesabı JSON anahtarını yükleyin, depolama uç noktası için imzalanmış bir JWT yapılandırın ve ortaya çıkan belirteci her çağrıda taşınması için DefaultMetadata'ya yerleştirin. Kendinden imzalı hizmet hesabı JWT'si hedef kitleye bağlıdır, bu nedenle belirtecin kabul edilmesi için API_Endpoint'in storage.googleapis.com adresine işaret etmesi gerekir.

var
  Cloud: TsgcHTTPGoogleCloud_PubSub_Client;
begin
  Cloud := TsgcHTTPGoogleCloud_PubSub_Client.Create(nil);
  Cloud.LoadSettingsFromFile('service-account.json');
  Cloud.GoogleCloudOptions.Authentication := gcaJWT;
  Cloud.GoogleCloudOptions.JWT.API_Endpoint := 'https://storage.googleapis.com/';

  // OnAuthToken fires when the token is ready; copy it into the gRPC metadata
  GRPC.DefaultMetadata.Clear;
  GRPC.DefaultMetadata.Add('authorization', 'Bearer ' + Token);
end;

Bucket'ları listeleme

Bir projedeki bucket'ları listelemek için, proje Parent olacak şekilde bir TsgcGRPCStorageListBucketsRequest doldurun, onu serileştirin ve ListBuckets metoduna tekli bir Call yapın. Yanıt baytları doğrudan, her bucket'ı adı ve konumuyla birlikte sunan bir TsgcGRPCStorageListBucketsResponse'a yüklenir.

var
  oRequest: TsgcGRPCStorageListBucketsRequest;
  oResponse: TsgcGRPCResponse;
  oBuckets: TsgcGRPCStorageListBucketsResponse;
  i: Integer;
begin
  oRequest := TsgcGRPCStorageListBucketsRequest.Create;
  try
    oRequest.Parent := 'projects/' + ProjectId;
    oRequest.PageSize := 100;

    oResponse := GRPC.Call('google.storage.v2.Storage', 'ListBuckets',
      oRequest.ToBytes);
  finally
    oRequest.Free;
  end;

  if oResponse.StatusCode = grpcOK then
  begin
    oBuckets := TsgcGRPCStorageListBucketsResponse.Create;
    try
      oBuckets.LoadFromBytes(oResponse.Data);
      for i := 0 to oBuckets.BucketCount - 1 do
        Memo1.Lines.Add(oBuckets.Bucket(i).Name + ' (location: ' +
          oBuckets.Bucket(i).Location + ')');
    finally
      oBuckets.Free;
    end;
  end;
end;

Bir bucket oluşturma

Bir bucket oluşturmak, TsgcGRPCStorageCreateBucketRequest ile aynı deseni izler. Üst projeyi, yeni bucket kimliğini ve bucket kaynağına sahip olan projeyi ayarlayın, ardından CreateBucket'i çağırın. Yanıt, oluşturulan TsgcGRPCStorageBucket'ı taşır.

var
  oRequest: TsgcGRPCStorageCreateBucketRequest;
  oResponse: TsgcGRPCResponse;
begin
  oRequest := TsgcGRPCStorageCreateBucketRequest.Create;
  try
    oRequest.Parent := 'projects/' + ProjectId;
    oRequest.BucketId := 'my-new-bucket';
    oRequest.Bucket.Project := 'projects/' + ProjectId;

    oResponse := GRPC.Call('google.storage.v2.Storage', 'CreateBucket',
      oRequest.ToBytes);
  finally
    oRequest.Free;
  end;
end;

Bir bucket'taki nesneleri listeleme

Bir bucket'taki nesneleri listelemek, TsgcGRPCStorageListObjectsRequest kullanır. Üst, projects/_/buckets/<bucket> biçiminde bucket kaynak adıdır. Yanıt, her nesnenin adını, boyutunu ve içerik türünü verir ve klasör benzeri bir hiyerarşide gezinmek için isteğe bağlı olarak Prefix ve Delimiter ayarlayabilirsiniz.

var
  oRequest: TsgcGRPCStorageListObjectsRequest;
  oResponse: TsgcGRPCResponse;
  oObjects: TsgcGRPCStorageListObjectsResponse;
  i: Integer;
begin
  oRequest := TsgcGRPCStorageListObjectsRequest.Create;
  try
    oRequest.Parent := 'projects/_/buckets/' + BucketName;
    oRequest.PageSize := 100;

    oResponse := GRPC.Call('google.storage.v2.Storage', 'ListObjects',
      oRequest.ToBytes);
  finally
    oRequest.Free;
  end;

  if oResponse.StatusCode = grpcOK then
  begin
    oObjects := TsgcGRPCStorageListObjectsResponse.Create;
    try
      oObjects.LoadFromBytes(oResponse.Data);
      for i := 0 to oObjects.ObjectCount - 1 do
        Memo1.Lines.Add(oObjects.Object_(i).Name + ' (size: ' +
          IntToStr(oObjects.Object_(i).Size) + ', type: ' +
          oObjects.Object_(i).ContentType + ')');
    finally
      oObjects.Free;
    end;
  end;
end;

Nesne verilerini okuma ve yazma

Bucket ve nesne meta verilerinin ötesinde, birim nesne yüklerini de kapsar. TsgcGRPCStorageReadObjectRequest, aralıklı indirmeler için isteğe bağlı ReadOffset ve ReadLimit ile bir nesneden baytları geri okur ve eşleşen yanıt ham Data baytlarını sunar. TsgcGRPCStorageWriteObjectRequest, nesne içeriğini parçalar halinde yükler: ilk parça için WriteObjectSpec kaynağını ayarlayın, artan WriteOffset değerlerinde Data gönderin ve son parçada FinishWrite'ı işaretleyin. Her mesaj ToBytes ve LoadFromBytes aracılığıyla serileştiğinden, ister küçük bir dosyayı tek bir çağrıda yükleyin ister büyük bir nesneyi parçalar halinde akıtın, aynı türlü sınıflar çalışır.

Sayfalama ve hata işleme

Liste yanıtları, daha fazla sonuç mevcut olduğunda bir NextPageToken döndürür. Onu bir sonraki isteğin PageToken'ına kopyalayın ve büyük bucket'lar veya uzun nesne listelerinde sayfa sayfa ilerlemek için tekrar çağırın. Hata tarafında, her TsgcGRPCResponse türlü bir StatusCode taşır, bu nedenle grpcOK olmayan bir sonuç, hatalı veya eksik bir belirteç için grpcUNAUTHENTICATED'tan eksik bir bucket için grpcNOT_FOUND'a kadar tam olarak neyin yanlış gittiğini söyler. Asenkron iş için, OnGRPCResponse, OnGRPCError ve OnGRPCException aynı bilgiyi olaylar aracılığıyla iletir.

Kullanılabilirlik

Türlü Google Cloud Storage gRPC istemcisi, sgcWebSockets Enterprise sürümünün bir parçasıdır. Kimlik doğrulama, bucket'ları listeleme ve oluşturma ile nesneleri listelemeyi kapsayan eksiksiz, çalıştırılmaya hazır bir örnek Demos\21.GRPC\15.Cloud_Storage içinde yer alır. Tam referans, gRPC Client ürün sayfasında bulunur.

Sorularınız veya geri bildirimleriniz mi var? Bize ulaşın. Kodu yazan kişilerden bir yanıt alacaksınız.