Google Cloud Storage is Google's object-opslagdienst. Data leeft in buckets, en elke bucket bevat objecten (bestanden) die je uploadt, opsomt, leest en verwijdert. De meeste Delphi-code bereikt het via de JSON REST-API, maar de opslagdienst biedt ook een gRPC-API die Protocol Buffers spreekt over HTTP/2. sgcWebSockets Enterprise levert een getypeerde Cloud Storage gRPC-client gebouwd op TsgcGRPCClient, zodat je buckets en objecten kunt aansturen vanuit Delphi en C++Builder zonder enige externe runtime of gegenereerde stubs.
Hoe het werkt
De gRPC Storage-API bevindt zich op storage.googleapis.com:443 en spreekt de google.storage.v2.Storage-service. sgcWebSockets levert al een complete HTTP/2-stack, dus de getypeerde client draait bovenop een TsgcHTTP2Client-transport met TLS ingeschakeld. TsgcGRPCClient doet de gRPC-framing, headers en timeout-afhandeling, opent de HTTP/2-stream, en parset de response en trailers terug naar een TsgcGRPCResponse.
De getypeerde laag zit in de sgcGRPC_Google_Storage-unit. Hij geeft je request- en response-klassen zoals TsgcGRPCStorageListBucketsRequest, TsgcGRPCStorageListObjectsResponse en TsgcGRPCStorageBucket die zichzelf serialiseren naar en van Protocol Buffers. Je stelt getypeerde eigenschappen in, roept ToBytes aan om de request-payload te krijgen, verstuurt het met Call, en laadt het antwoord met LoadFromBytes. Geen protobuf-compiler, geen handgeschreven veld-tags.
Authenticatie gebruikt een Google-service-account. De client ondertekent een JSON Web Token vanuit de service-account-sleutel en presenteert het als een Bearer-token in de gRPC authorization-metadata, wat de standaardmanier is waarop Google Cloud server-naar-server-calls autoriseert.
De transport opzetten
Een gRPC-kanaal is gewoon een HTTP/2-verbinding. Richt een TsgcHTTP2Client op het storage-endpoint met TLS aan, koppel het vervolgens aan TsgcGRPCClient en selecteer het binaire Protocol Buffers-contenttype.
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;
Authenticeren met een service-account
Laad de service-account-JSON-sleutel, configureer een JWT ondertekend voor het storage-endpoint, en plaats het resulterende token in DefaultMetadata zodat het bij elke call meereist. De zelfondertekende service-account-JWT is audience-gebonden, dus het API_Endpoint moet wijzen naar storage.googleapis.com om het token te laten accepteren.
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;
Buckets opsommen
Om de buckets in een project op te sommen, vul je een TsgcGRPCStorageListBucketsRequest met het project als Parent, serialiseer je het, en doe je een unaire Call naar de ListBuckets-methode. De antwoordbytes laden rechtstreeks in een TsgcGRPCStorageListBucketsResponse, die elke bucket met zijn naam en locatie blootlegt.
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;
Een bucket aanmaken
Een bucket aanmaken volgt hetzelfde patroon met TsgcGRPCStorageCreateBucketRequest. Stel het parent-project in, de nieuwe bucket-id, en het project dat de bucket-resource bezit, en roep vervolgens CreateBucket aan. De response bevat de aangemaakte TsgcGRPCStorageBucket.
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;
Objecten in een bucket opsommen
Het opsommen van de objecten in een bucket gebruikt TsgcGRPCStorageListObjectsRequest. De parent is de bucket-resourcenaam, in de vorm projects/_/buckets/<bucket>. De response geeft je de naam, grootte en het contenttype van elk object, en je kunt optioneel Prefix en Delimiter instellen om door een mapachtige hiërarchie te lopen.
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;
Objectdata lezen en schrijven
Naast bucket- en objectmetadata dekt de unit ook objectpayloads. TsgcGRPCStorageReadObjectRequest leest bytes terug uit een object, met optionele ReadOffset en ReadLimit voor downloads met bereik, en de bijbehorende response legt de ruwe Data-bytes bloot. TsgcGRPCStorageWriteObjectRequest uploadt objectinhoud in chunks: stel de WriteObjectSpec-resource in voor de eerste chunk, push Data bij oplopende WriteOffset-waarden, en markeer FinishWrite op de laatste chunk. Omdat elk bericht serialiseert via ToBytes en LoadFromBytes, werken dezelfde getypeerde klassen of je nu een klein bestand in één call uploadt of een groot object in stukken streamt.
Paginering en foutafhandeling
De lijst-responses retourneren een NextPageToken wanneer er meer resultaten beschikbaar zijn. Kopieer het naar de PageToken van de volgende request en roep opnieuw aan om door grote buckets of lange objectlijsten te bladeren. Aan de foutkant draagt elke TsgcGRPCResponse een getypeerde StatusCode, dus een niet-grpcOK-resultaat vertelt je precies wat er misging, van grpcUNAUTHENTICATED voor een verkeerd of ontbrekend token tot grpcNOT_FOUND voor een ontbrekende bucket. Voor asynchroon werk leveren OnGRPCResponse, OnGRPCError en OnGRPCException dezelfde informatie via gebeurtenissen.
Beschikbaarheid
De getypeerde Google Cloud Storage gRPC-client maakt deel uit van de sgcWebSockets Enterprise-editie. Een compleet, kant-en-klaar voorbeeld staat in Demos\21.GRPC\15.Cloud_Storage, dat authenticatie, het opsommen en aanmaken van buckets, en het opsommen van objecten dekt. De volledige referentie staat op de productpagina van de gRPC Client.
Vragen of feedback? Neem contact op. Je krijgt antwoord van de mensen die de code hebben geschreven.
