Nei primi snippet abbiamo visto come creare un progetto Windows Azure ovvero una applicazione che può essere ospitata su un Web Role all'interno del sistema operativo cloud. Abbiamo testato l'applicazione in locale tramite il Windows Azure Compute Emulator e abbiamo poi effettuato il deployment su una istanza tramite il portale.
In questo snippet vedremo come memorizzare dei file sotto forma di blob su Windows Azure Storage Account.
La prima operazione da compiere è ottenere una subscription dal portale di Windows Azure. Fra le varie subscription disponibili ne possiamo trovare alcune grauite che consentono di provare le nostre applicazioni sulla piattaforma senza pagare alculché a patto di non sforare i limiti indicati.
Tramite la subscription "Windows Azure Trial" introdotta anche nello snippet precedente, è possibile ottenere gratuitamente 500 MB di spazio di storage e 10.000 transazioni da effettuare nel mese.
In pratica possiamo appoggiare 500MB di blob (o dati in tabelle o messaggi in coda: affronteremo questi argomenti nei prossimi snippet) sullo Storage Account senza pagare un centesimo e testare la nostra applicazione effettuando 10.000 operazioni gratuite sullo storage al mese. Ogni accesso allo storage, ad esempio per leggere un file, per ottenere l'elenco dei file, per cancellare un file, rappresenta una transazione che viene computata nel sistema di billing. Se non sforiamo le transazioni incluse nella subscription vedremo, a fine mese, un conto a 0 (zero) Euro.
Possiamo accedere allo Storage Account, il servizio legato alla nostra subscription di gestione dello storage, anche se la nostra applicazione non è installata su Windows Azure: le richieste di accesso, infatti, si effettuano via REST/HTTP. Qualunque client sia in grado di comporre una richiesta HTTP può, security permettendo, utilizzare il servizio.
Ogni Storage Account consente, ad oggi, di memorizzare 100 TB (100 terabyte!) che, nativamente sono replicati su altri due nodi della piattaforma garantendo caratteristiche di scalabilità e fault-tolerance decisamente elevate.
Per attivare il servizio, dal portale, è sufficiente scegliere la sezione Storage Accounts e poi premere il pulsante New Storage Account nella toolbar in alto:
Il mini-wizard consente di scegliere la subscription a cui legare lo Storage Account, la regione in cui posizionare i dati e il prefisso per l'URL che concorre a formare l'indirizzo .core.windows.net
. Prima di proseguire facciamo due considerazioni:
- È possbile definire un affinity group ovvero un gruppo di nodi che vivranno nello stesso data center per tenere vicini i dati rispetto all'applicazione Windows Azure che li utilizza. Si ottiene un benefico in termini di performance in quanto si abbassano i tempi di latenza e un beneficio in termini di costi in quanto il traffico intra-datacenter non viene computato.
- È importante scegliere un nome univoco globalmente in quanto rappresenta il prefisso DNS che viene configurato in automatico dal sistema operativo. È poi possibile, nei casi in cui ha senso, far puntare un proprio alias DNS su questo indirizzo.
Scelto il nome e la regione (o l'affinity group) è sufficiente premere il tasto Create per ottenere uno spazio di 100 TB dove memorizzare i nostri file.
Ogni Storage Account riceve una coppia di chiavi che il nostro codice deve utilizzare per effettuare richieste al servizio. Il meccanismo di firma si basa su queste chiavi simmetriche che sono generate durante la creazione dello Storage Account: sono due chiavi simmetriche utilizzabili in alternativa per autenticare le richieste; sono due per poterne rigenerarne una senza fermare i client che nel frattempo possono utilizzare l'altra.
Nell'immagine seguente si nota lo Storage Account appena creato con i dettagli su URL creati, nome dell'account creato, regione in cui è stato appoggiato e, in alto, le due chiavi di accesso che possono essere visualizzate premendo il pulsante View.
Per poter memorizzare un file nello spazio destinato ai blob è sufficiente effettuare una richiesta REST/HTTP di tipo PUT
verso l'indirizzo ricevuto.
È anche possibile creare diversi container all'interno del nostro account: questa operazione si effettua sempre inviando una richiesta HTTP di tipo PUT. Ogni richiesta deve contenere un hash di una delle due chiavi di accesso ricevute per essere autenticata.
Per evitare di scrivere il codice che lavora a livello REST/HTTP è disponibile una libreria per l'ambiente .NET, così come per Java o PHP, che incapsula i dettagli di "basso" livello fornendo metodi molto semplici come ad esempio ListBlobs
per richiedere l'elenco dei blob all'interno di uno storage account o di un path interno allo storage account, UploadBlob
per aggiungere un blob e così via.
La libreria .NET utilizza una classe CloudStorageAccount che, leggendo il file di configurazione (ServiceConfiguration.cscfg
in una applicazione Windows Azure, o i classici .config
di .NET per applicazioni on-premises), si preoccupa di tutti i dettagli di comunicazione verso gli URL utilizzando le chiavi di accesso.
Windows Azure Management Tool
È disponbile inoltre uno strumento che sfrutta queste librerie per accedere al servizio e fornire una interfaccia di gestione e controllo dello storage. Si tratta del Windows Azure Management Tool, simile ad un Windows Explorer per la piattaforma Windows Azure, anche se, per adesso non è uno strumento "ufficiale".
MMC consente di connettersi allo Storage Account semplicemente scegliendo New Connection
dopo aver scelto Storage Explorer
dal TreeView di sinistra: è sufficiente inserire il nome dell'account creato e una delle due chiavi ricevute durante al momento della creazione in quanto la libreria StorageClient
si preoccupa, come vedremo anche più avanti dei dettagli.
Una volta configurata la connessione è possibile aprire l'albero al di sotto della voce Storage Explorer e lavorare con lo "spazio disco" ricevuto.
È possibile creare container all'interno di uno Storage Account per suddividere i blob e, all'interno di ciascuno di essi, ulteriori suddivisioni per organizzare al meglio il nostro "nuovo file system". Un container non è semplicemente una directory in quanto:
- Un container definisce la prima barriera sulla sicurezza: in container può essere pubblico consentendo la lettura senza l'utilizzo della chiave di accesso e scrittura con chiave di accesso oppure privato in cui entrambe le operazioni devono essere autenticate
- Un container rappresenta uno scope anche per la ricerca: è possibile infatti lanciare query all'interno di un container a prescindere dall'organizzazione interna del container stesso
Dallo strumento è possibile creare un container in modo molto semplice:
Il container "foto" sarà accessibile con richieste HTTP verso l'indirizzo:
https://thinkaheadstorageaccount.blob.core.windows.net
le operazioni di upload, download e cancellazione si possono effettuare direttamente dalla management console:
Facendo un refresh del container si ottiene l'elenco dei blob: è importante ricordare che questa operazione implica la costruzione di una richiesta HTTP verso il container del nostro Storage Account per richiedere la lista dei blob che, viene restituita dal servizio.
Visto che abbiamo creato un container pubblico possiamo effettuare una richiesta REST sull'URI dell'immagine che abbiamo inserito nel container. Dal menu a destra è possibile effettuare il download del blob per salvarlo in locale (GET) così come cancellare il file (DELETE).
È anche possibile effettuare View in Browser per aprire il browser di default e richiedere direttamente il blob. Il path completo è:
http://thinkaheadstorageaccount.blob.core.windows.net/foto/banner2011-180x150.gif
Visto che il container è pubblico è possibile utilizzare questo path anche da tag <img>
all'interno di pagine web.
Dal codice .NET, utilizzando la libreria StorageClient
, queste operazioni sono altrettando semplici. Ad esempio, il codice seguente richiede l'elenco degli Url dei blob nel container foto da una applicazione Windows on-premises, effettuando il binding del risultato su una griglia:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
namespace _03_Blob_WinForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
CloudStorageAccount account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["DataConnectionString"]);
// Creo wrapper per client
CloudBlobClient blobClient = account.CreateCloudBlobClient();
// Ottengo un riferimento al container
CloudBlobContainer container = blobClient.GetContainerReference("foto");
// Binding tradizionale
dataGridView1.DataSource = container.ListBlobs().Select((b) => b.Uri).ToList();
}
}
}
Il parametro DataConnectionString
è stato scritto nel classico file app.config
.
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="DataConnectionString" value="DefaultEndpointsProtocol=https;AccountName=thinkaheadstorageaccount;AccountKey=qQbZZMXayokpurNQ8lSnLKjMA.....gMZ+jBjg7l3"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
Il risultato, non certo accattivante, ma che dimostra l'utilizzo del servizio da una "vecchia" applicazione Windows Forms è il seguente: