Operazioni di Gridwich per Archiviazione di Azure

Archiviazione di Azure

Gridwich Archiviazione di Azure Service, Gridwich.SagaParticipants.Storage.AzureStorage, fornisce operazioni blob e contenitori per gli account Archiviazione di Azure configurati per Gridwich. Le operazioni di archiviazione di esempio sono Create BLOB, Delete container, Copy BLOB o Change storage tier( Modifica livello di archiviazione).

Gridwich richiede che i meccanismi di archiviazione funzionino sia per i BLOB in blocchi che per i contenitori Archiviazione di Azure. Con classi distinte e operazioni del servizio di archiviazione per BLOB e contenitori, non c'è ambiguità se una determinata operazione di archiviazione è correlata a un BLOB o a un contenitore. Questo articolo si applica sia ai BLOB che ai contenitori, tranne dove indicato.

Gridwich espone la maggior parte delle operazioni di archiviazione a sistemi esterni all'interno del partecipante della Storage.AzureStorage saga. Altri partecipanti della saga usano il servizio di archiviazione per attività come la copia di BLOB tra contenitori o account diversi quando configurano flussi di lavoro di codifica.

Questo articolo descrive in che modo Gridwich Archiviazione di Azure Service soddisfa i requisiti della soluzione e si integra con meccanismi come i gestori eventi. I collegamenti puntano al codice sorgente corrispondente, che contiene commenti più estesi su contenitori, classi e meccanismi.

ARCHIVIAZIONE DI AZURE SDK

Gridwich usa classi di Archiviazione di Azure SDK per interagire con Archiviazione di Azure, invece di creare richieste REST. All'interno del provider di archiviazione, le classi BLOBBaseClient e BlobContainerClient dell'SDK gestiscono le richieste di archiviazione.

Queste classi client SDK attualmente consentono solo l'accesso indiretto alle due intestazioni HTTP Gridwich deve modificare, x-ms-client-request-id per il contesto dell'operazione e ETag per la versione dell'oggetto.

In Gridwich una coppia di classi provider distribuisce la funzionalità BlobBaseClientProvider e BlobContainerClientProvider in unità denominate maniche. Per informazioni dettagliate sulle maniche, vedere Maniche di archiviazione.

Il diagramma seguente illustra la struttura delle classi SDK e Gridwich e il modo in cui le istanze sono correlate tra loro. Le frecce indicano "ha un riferimento a".

Diagramma che mostra le relazioni tra le istanze dell'oggetto client tra le classi di Storage SDK.

Criteri della pipeline

Impostare l'hook per modificare le intestazioni HTTP come istanza dei criteri della pipeline quando si crea l'istanza client. È possibile impostare questo criterio solo in fase di creazione dell'istanza client e non è possibile modificare il criterio. Il codice del provider di archiviazione che usa il client deve essere in grado di modificare i valori di intestazione durante l'esecuzione. La sfida consiste nel fare in modo che il provider di archiviazione e la pipeline interagiscono in modo pulito.

Per i criteri della pipeline gridwich, vedere la classe BlobClientPipelinePolicy .

Memorizzazione nella cache del servizio di archiviazione

L'impostazione della connessione TCP e l'autenticazione creano sovraccarico quando un'istanza dell'oggetto client SDK invia la prima richiesta a Archiviazione di Azure. Più chiamate allo stesso BLOB in una richiesta di sistema esterna, ad esempio Recupera metadati, quindi Elimina BLOB, complicano l'overhead.

Per ridurre il sovraccarico, Gridwich gestisce una cache di un'istanza client per ogni BLOB o contenitore di archiviazione, a seconda delle classi SDK usate dal contesto dell'operazione. Gridwich mantiene questa istanza client e può usare l'istanza per più operazioni di Archiviazione di Azure sullo stesso BLOB o contenitore per la durata di una richiesta di sistema esterna.

Le classi client fornite da Azure SDK richiedono che le istanze dell'oggetto client SDK siano specifiche di un singolo BLOB o contenitore in fase di creazione. Anche le istanze non sono sicure per l'uso simultaneo in thread diversi. Poiché un contesto dell'operazione rappresenta una singola richiesta, Gridwich basa la memorizzazione nella cache sulla combinazione di blob o nome del contenitore con il contesto dell'operazione.

Questo riutilizzo dell'istanza, combinato con la struttura client Archiviazione di Azure SDK, richiede codice di supporto aggiuntivo per bilanciare l'efficienza e la chiarezza del codice.

Argomento contesto

Quasi tutte le operazioni del servizio di archiviazione gridwich richiedono un argomento di contesto speciale di tipo StorageClientProviderContext. Questo argomento di contesto soddisfa i requisiti seguenti:

  • Fornisce al sistema esterno risposte, che includono il valore del contesto di operazione univoco basato su JSON per richiesta specificato dal sistema esterno nella richiesta Gridwich. Per altre informazioni, vedere Contesto dell'operazione.

  • Consente ai chiamanti del servizio di archiviazione come i gestori eventi gridwich di controllare quali risposte sono visibili al sistema esterno. Questo controllo impedisce al servizio di inondare il sistema esterno con eventi di notifica irrilevanti. Per altre informazioni, vedere Disattivazione del contesto.

  • È conforme alle convenzioni Archiviazione di Azure per garantire richieste e risposte coerenti in un ambiente che consenta una combinazione di lettori e writer paralleli. Ad esempio, supporta il rilevamento ETag. Per altre informazioni, vedere ETag.

Contesto di archiviazione

Il contesto per i tipi di archiviazione BLOB e contenitori è StorageClientProviderContext, simile al seguente:

    string  ClientRequestID { get; }
    JObject ClientRequestIdAsJObject { get; }
    bool    IsMuted { get; set; }
    string  ETag { get; set; }
    bool    TrackingETag { get; set; }

Le prime due proprietà sono rappresentazioni diverse del contesto dell'operazione usato per inizializzare l'istanza StorageClientProviderContext . La classe ha vari costruttori, incluso un costruttore di copia. Altri metodi includono ResetTo, per consentire la duplicazione dello stato sul posto e un metodo statico CreateSafe per garantire che le inizialiizzazioni problematiche non generino eccezioni.

La classe contiene anche una gestione speciale per la creazione di contesti basati su GUID e stringhe vuote. I gestori di notifica Archiviazione di Azure per BLOB Creati ed Eliminati, che elaborano anche le notifiche derivanti da agenti esterni, richiedono il modulo GUID.

Disattivazione del contesto

La IsMuted proprietà controlla se l'applicazione prevede che il servizio pubblicherà nuovamente le notifiche risultanti al chiamante, ad esempio nel sistema esterno. In un'operazione disattivata, il servizio non pubblica eventi risultanti.

Un esempio è rappresentato da copie BLOB eseguite da un codificatore per disporre i BLOB in Archiviazione di Azure come input per un'attività di codifica. Il sistema esterno non è preoccupato per questi dettagli, ma solo sullo stato del processo di codifica e dove può recuperare gli output codificati. Per riflettere questi problemi, il codificatore:

  1. Crea un contesto di archiviazione non disattivato in base al contesto dell'operazione di richiesta, ad esempio ctxNotMuted.

  2. Crea un contesto di archiviazione disattivato, ad esempio ctxMuted, usando il costruttore di copia della classe di contesto o creando una nuova istanza. Entrambe le opzioni avranno lo stesso valore del contesto dell'operazione.

  3. Specifica ctxMuted per le operazioni di archiviazione coinvolte nella configurazione per la codifica. Il sistema esterno non visualizza alcuna indicazione di queste operazioni in corso.

  4. Specifica il contesto per le operazioni di archiviazione che riflettono il ctxNotMuted completamento della codifica, ad esempio la copia di un file di output in un contenitore di destinazione. I gestori gridwich pubblicano gli eventi di notifica Archiviazione di Azure risultanti nel sistema esterno.

Il chiamante controlla la visibilità finale delle operazioni. Sia le operazioni disattivate che le operazioni non disattivate sono basate su un valore equivalente operationContext . Lo scopo della disattivazione del contesto è semplificare l'esecuzione della diagnosi dei problemi dai log di traccia eventi, perché è possibile visualizzare le operazioni di archiviazione correlate a una richiesta, indipendentemente dallo stato di disattivazione dell'operazione.

ResponseBaseDTO ha una proprietà DoNotPublishbooleana , che utilizza l'invio di eventi per determinare la decisione finale sulla pubblicazione. L'invio di eventi, a sua volta, imposta la DoNotPublish proprietà in base alla IsMuted proprietà del contesto.

Il servizio trasmette l'impostazione di disattivazione a Archiviazione di Azure, che imposta quindi l'oggetto clientRequestId negli eventi di notifica di archiviazione che presenta ai due gestori gridwich, Created e Deleted. Questi due gestori sono impostati DoNotPublish in modo da riflettere la disattivazione richiesta dal chiamante.

ETag per la coerenza di destinazione

Archiviazione di Azure usa l'intestazione HTTP ETag per le sequenze di richiesta che devono avere coerenza di destinazione. Un esempio consiste nel garantire che un BLOB non sia cambiato tra le operazioni di recupero dei metadati e di archiviazione dei metadati di aggiornamento.

Per allinearsi all'utilizzo HTTP standard, questa intestazione ha un valore opaco la cui interpretazione è che se il valore dell'intestazione cambia, l'oggetto sottostante è stato modificato. Se una richiesta invia il valore corrente ETag per l'oggetto e non corrisponde al valore corrente del servizio ETag di archiviazione, la richiesta ha immediatamente esito negativo. Se la richiesta non include un ETag valore, Archiviazione di Azure ignora tale controllo e non blocca la richiesta.

ETag nel servizio di archiviazione

Per Gridwich, ETag è un dettaglio interno tra il servizio di archiviazione gridwich e Archiviazione di Azure. Nessun altro codice deve essere a conoscenza di ETag. Il servizio di archiviazione usa per ETag sequenze come get blob metadata, delete blob operations for processing a BlobDelete Event request. L'uso ETag di garantisce che l'operazione Elimina BLOB sia destinata esattamente alla stessa versione del BLOB dell'operazione Recupera metadati .

Per usare ETag per l'esempio precedente:

  1. Inviare la richiesta Get Metadata con un valore vuoto ETag.
  2. Salvare il ETag valore dalla risposta.
  3. Aggiungere il valore salvato ETag alla richiesta Elimina BLOB .

Se i due ETag valori sono diversi, l'operazione di eliminazione non riesce. L'errore implica che un'altra operazione ha modificato il BLOB tra i passaggi 2 e 3. Ripetere il processo dal passaggio 1.

ETag è un parametro di costruttori e una proprietà stringa della classe StorageClientProviderContext. Solo l'oggetto BlobClientPipelinePolicy specifico di Gridwich modifica il ETag valore.

Uso di ETag per il controllo

La TrackingETag proprietà controlla se inviare il ETag valore alla richiesta successiva. Il valore true indica che il servizio invia un oggetto ETag se disponibile.

Una richiesta Archiviazione di Azure con un ETag valore che non corrisponde al BLOB oggetto o al contenitore genera un errore nell'operazione. Questo errore è per progettazione, perché ETag è il modo HTTP standard di esprimere "la versione esatta di destinazione della richiesta". Le richieste possono includere la TrackingETag proprietà per dichiarare che deve ETags corrispondere o non includere la TrackingETag proprietà per indicare che i ETag valori non sono importanti.

La pipeline recupera sempre un ETag valore da un'operazione Archiviazione di Azure se presente in tale risposta REST. La pipeline aggiorna sempre la proprietà di contesto ETag , se possibile, a partire dall'ultima operazione. Il TrackingETag flag controlla solo se la richiesta successiva dalla stessa istanza client invia il valore della ETag proprietà . Se il ETag valore è null o vuoto, la richiesta corrente non imposta alcun valore HTTP ETag , indipendentemente dal valore di TrackingETag.

Maniche di archiviazione

Gridwich richiede che i meccanismi di archiviazione funzionino sia per Archiviazione di Azure i BLOB in blocchi che per i contenitori. Esistono classi distinte e operazioni del servizio di archiviazione per BLOB e contenitori, quindi non c'è ambiguità sul fatto che una determinata operazione di archiviazione sia correlata a un BLOB o a un contenitore.

Una coppia di classi provider, una per i BLOB e una per i contenitori, erogare i due set di funzionalità in unità denominate maniche. Le maniche contengono istanze di classi helper di archiviazione che fanno parte di Azure SDK. L'inizializzazione del servizio di archiviazione crea i provider e li rende direttamente disponibili ai metodi del servizio di archiviazione.

Struttura a maniche

La manica è un contenitore per l'istanza dell'oggetto client SDK e un contesto di archiviazione. Le funzioni del provider di archiviazione fanno riferimento alla manica tramite le due proprietà Client e Context. Esiste un tipo di maniche per i BLOB e un altro per i contenitori, che hanno Client rispettivamente proprietà di tipoBlobBaseClient e BlobContainerClient.

La struttura generale delle maniche per i BLOB è simile alla seguente:

    BlobBaseClient Client { get; }
    BlobServiceClient Service { get; }
    StorageClientProviderContext Context { get; }

La Service proprietà sulla manica è una comodità. Alcune delle operazioni finali correlate al codificatore che usano la classe BLOBServiceClient SDK richiedono chiavi dell'account di archiviazione. Questo requisito ha portato all'aggiunta di un'istanza client del servizio ai due tipi di maniche esistenti, anziché produrre un provider separato.

Utilizzo delle maniche

I provider di archiviazione client distribuisce le istanze di manica. Il codice del servizio di archiviazione è simile alla sequenza di codice con annotazioni seguente, con i tipi evidenziati per maggiore chiarezza:

    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
        . . .
    }
  1. Gridwich popola automaticamente il contesto dell'operazione nel contesto della manica alla riga A. TrackingETag il valore predefinito è false.
  2. Dopo la riga B, sleeve.Context contiene l'oggetto dalla ETag riga A e mantiene lo stesso ClientRequestID valore.
  3. La riga C invia sia il ETag valore dalla riga B che dall'oggetto ClientRequestId.
  4. Dopo la riga C, il contesto ha un nuovo ETag valore, come restituito nella Delete() risposta.
  5. La riga D non invia un ETag valore alla richiesta per AnotherOperation().
  6. Dopo la riga D, il contesto ha un nuovo ETag valore, come restituito nella AnotherOperation() risposta.

Il servizio di archiviazione è attualmente impostato come Transient nella configurazione di inserimento delle dipendenze, il che implica che la memorizzazione nella cache basata su maniche è basata su richiesta. Per altre informazioni, vedere Servizio di archiviazione e inserimento delle dipendenze.

Alternative al servizio di archiviazione

Le sezioni seguenti descrivono approcci alternativi che non fanno parte della soluzione di archiviazione di Gridwich corrente.

Classe Gridwich AzureStorageManagement

Insieme al membro della manica Service , che è un'istanza della classe BlobServiceClient di Azure SDK, Gridwich ha anche la classe AzureStorageManagement . Il metodo del servizio GetConnectionStringForAccount di archiviazione e il metodo di codifica Telerek usano tale classe per ottenere le chiavi dell'account GetStoreByNameAsync di archiviazione. La classe è attualmente basata sul framework Fluent. Le aggiunte alla classe SDK BlobServiceClient dovrebbero infine sostituire questa classe, consentendo un recupero delle informazioni più incentrato rispetto all'ampia varietà nell'interfaccia Fluent IAzure.

Nascondere i criteri della pipeline tramite la sottoclasse

La sottoclasse dei tipi di client SDK aggiunge due proprietà semplici al client, una per ogni valore di intestazione HTTP, per nascondere completamente l'interazione con i criteri della pipeline. Tuttavia, a causa di un bug Moq profondo, non è possibile creare unit test tramite mock per questi tipi derivati. Gridwich usa Moq, quindi non ha usato questo approccio di sottoclasse.

Il bug Moq si riferisce alla gestione errata della sottoclasse tra assembly in presenza di funzioni virtuali con ambito interno. Le classi client SDK usano funzioni virtuali con ambito interno che coinvolgono tipi di ambito interno invisibili ai normali utenti esterni. Quando Moq tenta di creare una mock della sottoclasse, che si trova in uno degli assembly gridwich, non riesce in fase di esecuzione del test perché non riesce a trovare le macchine virtuali con ambito interno nelle classi client DELL'SDK da cui derivano le classi Gridwich. Non esiste alcuna soluzione alternativa senza modifiche nella generazione del proxy Moq Castle.

Inserimento di dipendenze e servizio di archiviazione

Gridwich registra attualmente il servizio di archiviazione come Transient servizio di inserimento delle dipendenze. Ovvero, ogni volta che viene richiesto l'inserimento delle dipendenze per il servizio, viene creata una nuova istanza. Il codice corrente dovrebbe funzionare correttamente anche se la registrazione cambia in Scoped, implicando un'istanza per richiesta, ad esempio la richiesta del sistema esterno.

Tuttavia, si verificano problemi se la registrazione cambia in Singleton, un'istanza nell'app per le funzioni gridwich. Il meccanismo di memorizzazione nella cache gridwich per maniche e intervalli di byte di dati non distingue tra richieste diverse. Inoltre, il modello di cache non è un estratto, quindi Gridwich non rimuove l'istanza dalla cache mentre è in uso. Poiché le classi client SDK non sono necessariamente thread-safe, il coordinamento richiederebbe molte modifiche.

Per questi motivi, non modificare il servizio di archiviazione di Gridwich, così come è, alla registrazione dell'inserimento Singleton delle dipendenze. Gridwich segue questa regola nella registrazione dell'inserimento delle dipendenze e include uno unit test, CheckThatStorageServiceIsNotASingleton, per applicarla.

Passaggi successivi

Documentazione sui prodotti:

Moduli di Microsoft Learn: