Gridwich Azure Storage Service, Gridwich.SagaParticipants.Storage.AzureStorage, biedt blob- en containerbewerkingen voor Azure Storage-accounts die zijn geconfigureerd voor Gridwich. Voorbeelden van opslagbewerkingen zijn Blob maken, Container verwijderen, Blob kopiëren of Opslaglaag wijzigen.
Gridwich vereist dat de opslagmechanismen werken voor zowel Azure Storage-blok-blobs als containers. Met afzonderlijke klassen en opslagservicebewerkingen voor blobs en containers is er geen dubbelzinnigheid over of een bepaalde opslagbewerking betrekking heeft op een blob of een container. Dit artikel is van toepassing op zowel blobs als containers, behalve waar vermeld.
Gridwich maakt de meeste opslagbewerkingen beschikbaar voor externe systemen binnen de Storage.AzureStorage
saga-deelnemer. Andere saga-deelnemers gebruiken de opslagservice voor taken zoals het kopiëren van blobs tussen verschillende containers of accounts wanneer ze coderingswerkstromen instellen.
In dit artikel wordt beschreven hoe de Gridwich Azure Storage-service voldoet aan de oplossingsvereisten en kan worden geïntegreerd met mechanismen zoals gebeurtenis-handlers. Koppelingen verwijzen naar de bijbehorende broncode, die uitgebreider commentaar bevat over de containers, klassen en mechanismen.
Azure Storage SDK
Gridwich maakt gebruik van klassen van de Azure Storage SDK om te communiceren met Azure Storage, in plaats van HAND-aanvragen te maken. Binnen de opslagprovider beheren de klassen SDK BlobBaseClient en BlobContainerClient opslagaanvragen.
Deze SDK-clientklassen bieden momenteel alleen indirecte toegang tot de twee HTTP-headers Gridwich die moet worden bewerkt, x-ms-client-request-id
voor de bewerkingscontext en ETag
voor objectversie.
In Gridwich dispenses een paar providerklassen BlobBaseClientProvider en BlobContainerClientProvider functionaliteit in eenheden genaamd sleeves. Zie Opslagmouwen voor meer informatie over mouwen.
In het volgende diagram ziet u de structuur van de SDK- en Gridwich-klassen en hoe exemplaren zich met elkaar verhouden. De pijlen geven aan 'heeft een verwijzing naar'.
Pijplijnbeleid
U stelt de hook in om de HTTP-headers te bewerken als een exemplaar van een pijplijnbeleid wanneer u het clientexemplaren maakt. U kunt dit beleid alleen instellen tijdens het maken van het clientexemplaren en u kunt het beleid niet wijzigen. De code van de opslagprovider met behulp van de client moet de headerwaarden kunnen bewerken tijdens de uitvoering. De uitdaging is om de opslagprovider en pijplijn schoon te laten werken.
Zie de klasse BlobClientPipelinePolicy voor het gridwich-pijplijnbeleid.
Opslagservice opslaan in cache
De instelling en verificatie van TCP-verbindingen maken overhead wanneer een EXEMPLAAR van een SDK-clientobject de eerste aanvraag naar Azure Storage verzendt. Meerdere aanroepen naar dezelfde blob in een externe systeemaanvraag, bijvoorbeeld Metagegevens ophalen, vervolgens Blob verwijderen, de overhead optellen.
Om overhead te beperken, onderhoudt Gridwich een cache van één clientexemplaren voor elke opslagblob of container, afhankelijk van de SDK-klassen die door de context van de bewerking worden gebruikt. Gridwich behoudt dit clientexemplaren en kan het exemplaar gebruiken voor meerdere Azure Storage-bewerkingen op dezelfde blob of container voor de duur van een externe systeemaanvraag.
Voor de door Azure SDK geleverde clientklassen moeten SDK-clientobjectexemplaren specifiek zijn voor één blob of container tijdens het maken. De exemplaren zijn ook niet gegarandeerd veilig voor gelijktijdig gebruik op verschillende threads. Aangezien een bewerkingscontext één aanvraag vertegenwoordigt, baseert Gridwich caching op de combinatie van blob- of containernaam met bewerkingscontext.
Voor dit exemplaar is in combinatie met de Clientstructuur van de Azure Storage SDK aanvullende ondersteuningscode vereist om de efficiëntie en de duidelijkheid van code te verdelen.
Contextargument
Bijna alle Gridwich Storage Service-bewerkingen vereisen een speciaal contextargument van het type StorageClientProviderContext. Dit contextargument voldoet aan de volgende vereisten:
Biedt het externe systeem antwoorden, waaronder de unieke JSON-bewerkingscontextwaarde per aanvraag die door het externe systeem is opgegeven in de Gridwich-aanvraag. Zie De context van de bewerking voor meer informatie.
Hiermee kunnen bellers van de Storage-service, zoals Gridwich-gebeurtenishandlers, bepalen welke antwoorden zichtbaar zijn voor het externe systeem. Met dit besturingselement voorkomt u dat de service het externe systeem overspoelt met irrelevante meldingsevenementen. Zie Context dempen voor meer informatie.
Voldoet aan Azure Storage-conventies om coherente aanvragen en antwoorden in een omgeving te garanderen die een combinatie van parallelle lezers en schrijvers mogelijk maakt. Ondersteunt bijvoorbeeld ETag-tracering. Zie ETags voor meer informatie.
Opslagcontext
De context voor zowel de blob- als containeropslagtypen is de StorageClientProviderContext, die er als volgt uitziet:
string ClientRequestID { get; }
JObject ClientRequestIdAsJObject { get; }
bool IsMuted { get; set; }
string ETag { get; set; }
bool TrackingETag { get; set; }
De eerste twee eigenschappen zijn verschillende weergaven van de bewerkingscontext die is gebruikt voor het initialiseren van het StorageClientProviderContext-exemplaar . De klasse heeft verschillende constructors, waaronder een kopieerconstructor. Aanvullende methoden zijn onder andere ResetTo
het toestaan van in-place statusduplicatie en een statische CreateSafe
methode om ervoor te zorgen dat problematische initialisaties geen uitzonderingen genereren.
De klasse bevat ook speciale verwerking voor het maken van contexten op basis van GUID's en lege tekenreeksen. Voor de Azure Storage-meldingshandlers voor blob gemaakt en verwijderd, die ook meldingen verwerken die afkomstig zijn van externe agents, is het GUID-formulier vereist.
Context dempen
De IsMuted
eigenschap bepaalt of de toepassing verwacht dat de service resulterende meldingen weer naar de aanroeper publiceert, bijvoorbeeld naar het externe systeem. In een gedempte bewerking publiceert de service geen resulterende gebeurtenissen.
Een voorbeeld hiervan zijn blobkopieën die door een encoder worden uitgevoerd om blobs in Azure Storage als invoer voor een coderingstaak te rangschikken. Het externe systeem maakt zich geen zorgen over deze details, maar alleen over de status van de coderingstaak en waar de gecodeerde uitvoer kan worden opgehaald. Om deze problemen weer te geven, gebruikt u de encoder:
Hiermee maakt u bijvoorbeeld een niet-gedempte opslagcontext op basis van de aanvraagbewerkingscontext
ctxNotMuted
.Hiermee maakt u een gedempte opslagcontext, bijvoorbeeld
ctxMuted
met behulp van de constructor voor het kopiëren van contextklassen of het maken van een nieuw exemplaar. Beide opties hebben dezelfde waarde voor de bewerkingscontext.Hiermee geeft u
ctxMuted
op voor opslagbewerkingen die betrokken zijn bij de installatie voor codering. Het externe systeem ziet geen indicatie van deze bewerkingen.Hiermee geeft u de
ctxNotMuted
context op voor opslagbewerkingen die de voltooiing van de codering weerspiegelen, bijvoorbeeld het kopiëren van een uitvoerbestand naar een doelcontainer. Gridwich-handlers publiceren de resulterende Azure Storage-meldings gebeurtenissen naar het externe systeem.
De beller bepaalt de ultieme zichtbaarheid van bewerkingen. Zowel gedempte als niet-gedempte bewerkingen zijn gebaseerd op een equivalente operationContext
waarde. Het doel van het dempen van contexten is om het gemakkelijker te maken om een diagnose van problemen uit te voeren vanuit logboeken voor gebeurtenistracering, omdat het mogelijk is om de opslagbewerkingen te zien die betrekking hebben op een aanvraag, ongeacht de status van het dempen van bewerkingen.
De ResponseBaseDTO heeft een booleaanse eigenschap DoNotPublish
, die gebeurtenisverzending gebruikt om de definitieve beslissing te bepalen over het publiceren. Gebeurtenisverzending stelt DoNotPublish
de eigenschap op zijn beurt in op basis van de IsMuted
eigenschap van de context.
De service verzendt de dempingsinstelling naar Azure Storage, waarmee de clientRequestId
gebeurtenissen voor opslagmeldingen worden ingesteld die worden gepresenteerd aan de twee Gridwich-handlers, Gemaakt en Verwijderd. Deze twee handlers zijn ingesteld DoNotPublish
om de door de aanroeper aangevraagde demping weer te geven.
ETags voor doelconsistentie
Azure Storage maakt gebruik van de HTTP-header ETag
voor aanvraagreeksen die de doelconsistentie moeten hebben. Een voorbeeld is om ervoor te zorgen dat een blob niet is gewijzigd tussen het ophalen van metagegevens en het bijwerken van metagegevensopslagbewerkingen .
Deze header heeft een ondoorzichtige waarde waarvan de interpretatie is dat als de headerwaarde verandert, het onderliggende object ook is gewijzigd om het te laten overeenkomen met het standaard HTTP-gebruik. Als een aanvraag de huidige ETag
waarde voor het object verzendt en deze niet overeenkomt met de huidige opslagservicewaarde ETag
, mislukt de aanvraag onmiddellijk. Als de aanvraag geen waarde bevat ETag
, slaat Azure Storage die controle over en blokkeert de aanvraag niet.
ETags in de opslagservice
Voor Gridwich is het ETag
een interne details tussen de Gridwich Storage-service en Azure Storage. Er hoeft geen andere code op de hoogte te zijn van de ETag
. De Opslagservice gebruikt de ETag
for-reeksen, zoals de metagegevens van de blob ophalen, blobbewerkingen verwijderen voor het verwerken van een BlobDelete Event
aanvraag. Als u de ETag
bewerking Blob verwijderen gebruikt, is deze exact dezelfde versie van de blob als de bewerking Metagegevens ophalen.
Ga als volgt te werk om het ETag
voor het voorgaande voorbeeld te gebruiken:
- Verzend de aanvraag Metagegevens ophalen met een lege
ETag
aanvraag. - Sla de
ETag
waarde op uit het antwoord. - Voeg de opgeslagen
ETag
waarde toe aan de aanvraag Blob verwijderen.
Als de twee ETag
waarden verschillen, mislukt de verwijderbewerking. De fout impliceert dat een andere bewerking de blob tussen stap 2 en 3 heeft gewijzigd. Herhaal het proces uit stap 1.
ETag
is een parameter van constructors en een tekenreekseigenschap van de klasse StorageClientProviderContext. Alleen de Gridwich-specifieke BlobClientPipelinePolicy bewerkt de ETag
waarde.
ETag-gebruik beheren
De TrackingETag
eigenschap bepaalt of de ETag
waarde voor de volgende aanvraag moet worden verzonden. De waarde true
betekent dat de service een ETag
if-waarde verzendt als deze beschikbaar is.
Een Azure Storage-aanvraag met een ETag
waarde die niet overeenkomt met de onderwerp-blob of container, resulteert in een mislukte bewerking. Deze fout is standaard, omdat ETag
dit de standaard HTTP-manier is om 'de exacte versie van de aanvraag die op de aanvraag is gericht' uit te drukken. Aanvragen kunnen de TrackingETag
eigenschap bevatten om aan te geven dat de ETags
eigenschap moet overeenkomen of niet de TrackingETag
eigenschap bevatten om aan te geven dat de ETag
waarden niet van belang zijn.
De pijplijn haalt altijd een ETag
waarde op uit een Azure Storage-bewerking als deze aanwezig is in dat REST-antwoord. De pijplijn werkt altijd de contexteigenschap ETag
bij, indien mogelijk, vanaf de laatste bewerking. De TrackingETag
vlag bepaalt alleen of de volgende aanvraag van hetzelfde clientexemplaren de waarde van de ETag
eigenschap verzendt. Als de ETag
waarde null of leeg is, wordt met de huidige aanvraag geen HTTP-waarde ETag
ingesteld, ongeacht de waarde van TrackingETag
.
Opbergmouwen
Gridwich vereist dat de opslagmechanismen werken voor zowel Azure Storage-blok-blobs als containers. Er zijn verschillende klassen en opslagservicebewerkingen voor blobs en containers, dus er is geen dubbelzinnigheid over of een bepaalde opslagbewerking betrekking heeft op een blob of een container.
Een paar providerklassen, één voor blobs en één voor containers, dispenseer de twee sets functionaliteit in eenheden die mouwen worden genoemd. Sleeves bevatten exemplaren van opslaghulpklassen die deel uitmaken van de Azure SDK. Als u de opslagservice initialiseert, worden de providers gemaakt en worden deze rechtstreeks beschikbaar gemaakt voor opslagservicemethoden.
Mouwstructuur
De hoes is een container voor het SDK Client-objectexemplaren en een opslagcontext. De functies van de opslagprovider verwijzen via de twee eigenschappen Client
en Context
. Er is een mouwtype voor blobs en een andere voor containers, die eigenschappen van het type BlobBaseClient
en BlobContainerClient
, respectievelijk, hebben.Client
De algemene mouwstructuur voor blobs ziet er als volgt uit:
BlobBaseClient Client { get; }
BlobServiceClient Service { get; }
StorageClientProviderContext Context { get; }
Het Service
pand op de hoes is een gemak. Voor sommige van de laatste coderingsprogrammabewerkingen die gebruikmaken van de SDK BlobServiceClient-klasse zijn opslagaccountreferenties vereist. Deze vereiste heeft geleid tot het toevoegen van een serviceclientexemplaren aan de twee bestaande mouwtypen in plaats van een afzonderlijke provider te produceren.
Gebruik van mouwen
De clientopslagproviders dispense sleeve-exemplaren. De code van de opslagservice ziet er ongeveer uit als de volgende geannoteerde codereeks, met typen die voor de duidelijkheid zijn gespeld:
public bool DeleteBlob(Uri sourceUri, StorageClientProviderContext context)
{
. . .
StorageBlobClientSleeve sleeve = _blobBaseClientProvider.GetBlobBaseClientForUri(sourceUri, context); // Line A
BlobProperties propsIncludingMetadata = sleeve.Client.GetProperties(); // Line B
sleeve.Context.TrackingETag = true; // Send ETag from GetProperties()
var wasDeleted = sleeve.Client.DeleteBlob(); // Line C
sleeve.Context.TrackingETag = false;
var someResult = sleeve.Client.AnotherOperation(); // Line D
. . .
}
- Gridwich vult de bewerkingscontext automatisch in de mouwcontext op regel A.
TrackingETag
is standaard ingesteld op false. - Na regel B bevat
sleeve.Context
u deETag
van regel A en behoudt u dezelfdeClientRequestID
waarde. - Regel C verzendt zowel de
ETag
waarde van regel B als deClientRequestId
. - Na regel C heeft de context een nieuwe
ETag
waarde, zoals wordt geretourneerd in hetDelete()
antwoord. - Regel D verzendt
ETag
geen waarde in de aanvraag voorAnotherOperation()
. - Na regel D heeft de context een nieuwe
ETag
waarde, zoals wordt geretourneerd in hetAnotherOperation()
antwoord.
De opslagservice is momenteel ingesteld als Transient
in de configuratie van afhankelijkheidsinjectie, wat impliceert dat de cache op basis van de mouwen per aanvraag is. Zie Opslagservice en afhankelijkheidsinjectie voor meer informatie.
Alternatieven voor Storage Service
In de volgende secties worden alternatieve benaderingen beschreven die geen deel uitmaken van de huidige Gridwich-opslagoplossing.
Het pijplijnbeleid verbergen via subklassen
Met subklassen van de SDK-clienttypen worden twee eenvoudige eigenschappen toegevoegd aan de client, één voor elke HTTP-headerwaarde, om de interactie met het pijplijnbeleid volledig te verbergen. Maar vanwege een diepe Moq-fout is het niet mogelijk om eenheidstests te maken via mock
deze afgeleide typen. Gridwich gebruikt Moq, dus deze methode voor subklassen is niet gebruikt.
De Moq-fout heeft betrekking op het verkeerdhanden van subklassen voor meerdere assembly's in aanwezigheid van virtuele functies binnen het bereik. De SDK-clientklassen maken gebruik van virtuele functies binnen het bereik met interne bereiktypen die onzichtbaar zijn voor normale externe gebruikers. Wanneer Moq probeert een mock
van de subklassen te maken, die zich in een van de Gridwich-assembly's bevindt, mislukt deze tijdens de testuitvoering omdat de interne bereik-virtuals niet kunnen worden gevonden in de SDK-clientklassen waaruit de Gridwich-klassen worden afgeleid. Er is geen tijdelijke oplossing zonder wijzigingen in de proxygeneratie van Moq Castle.
Opslagservice en afhankelijkheidsinjectie
Gridwich registreert de Opslagservice momenteel als een Transient
afhankelijkheidsinjectieservice. Dat wil gezegd, telkens wanneer afhankelijkheidsinjectie wordt gevraagd voor de service, wordt er een nieuw exemplaar gemaakt. De huidige code moet ook correct werken als de registratie wordt gewijzigd Scoped
, wat betekent dat er één exemplaar per aanvraag wordt gebruikt, bijvoorbeeld de aanvraag van het externe systeem.
Er zijn echter problemen als de registratie wordt gewijzigd Singleton
in, één exemplaar in de Gridwich Function-app. Het Gridwich-cachingmechanisme voor mouwen en gegevens bytebereiken maakt vervolgens geen onderscheid tussen verschillende aanvragen. Het cachemodel is ook geen uitcheckmodel, dus Gridwich verwijdert het exemplaar niet uit de cache terwijl het in gebruik is. Omdat de SDK-clientklassen niet gegarandeerd thread-veilig zijn, zou coördinatie veel wijzigingen vereisen.
Wijzig om deze redenen de Gridwich Storage-service niet in Singleton
registratie van afhankelijkheidsinjectie. Gridwich volgt deze regel in registratie van afhankelijkheidsinjectie en bevat een eenheidstest, CheckThatStorageServiceIsNotASingleton, om deze af te dwingen.
Volgende stappen
Productdocumentatie:
Microsoft Learn-modules: