Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1908, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Windows Azure: interagire con il Cloud Storage da Visual Basic 2010 - prima parte

Con questo post vorrei iniziare una serie di trattazioni inerenti la possibilità di interagire, esclusivamente da codice Visual Basic 2010, con lo spazio di memorizzazione on-line (Cloud Storage) messo a disposizione dalla piattaforma di Windows Azure. Non voglio dilungarmi su cosa sia Windows Azure e su come funzioni lo storage (se non qualche cenno necessario), visto che ci sono trattazioni di gran lunga più dettagliate delle mie. Se volete un'infarinatura su Azure e i suoi servizi, potete scaricare le slide di Renato Marzaro presentate in occasione del nostro evento a Roma lo scorso novembre.

Cosa dò per scontato

Chiaramente il fatto che abbiate un account su Windows Azure e che abbiate creato il vostro Cloud Storage. Se vi servono informazioni in merito, potete dare un'occhiata alla MSDN Library.

Scopo del gioco

Lo scopo di questa serie di post è mostrare come sia possibile memorizzare e leggere i propri file nella parte del Cloud Storage chiamata Blob Storage. Lo faremo utilizzando le nuove API che troviamo a disposizione nel Windows Azure SDK 1.3, che quindi è necessario scaricare ed installare. Inoltre, daremo un approccio molto "client" alla cosa. Normalmente esempi in merito si trovano (oltre che solo in C#) per dimostrare l'accesso allo storage da applicazioni Silverlight. Ma siccome non esiste solo il Web, vedremo un qualcosa di diverso.

Da dove partiamo e dove vogliamo arrivare

Tempo fa ho pubblicato un progetto su CodePlex, chiamato Azure Blob Studio 2011, che consiste in un client WPF ma anche in un'estensione per Visual Studio 2010 che consentono di interagire con il proprio storage per memorizzare o scaricare file, organizzati in cartelle. All'interno di quel progetto, per il quale è disponibile tutto il codice VB, ho implementato una classe che rende fruibili, in modo un pochino diverso e forse migliore (a mio avviso), la maggior parte degli oggetti esposti dalle API per lo storage di Windows Azure. L'obiettivo che quindi ci prefissiamo è ricostruire quella classe chiamata BlobService per capire come usare codice managed verso lo storage. La serie sarà costituita da tre, massimo quattro post. Se non avete tempo di aspettare o semplicemente siete curiosi o volete una linea guida, è conveniente scaricare il codice. Impareremo quindi a creare cartelle, rimuoverle, elencarle, a caricare, scaricare ed eliminare file.

Overview del Cloud Storage

Quando attiviamo un abbonamento a Windows Azure (incluso quello MSDN con i relativi benefit) ci viene messo a disposizione uno spazio di memorizzazione dati chiamato Cloud Storage. Tale spazio è, in sostanza, un insieme di quattro servizi:

  • Blob: in questo spazio possiamo archiviare dati binari, tipicamente immagini, video, documenti; file, in altre parole
  • Table: qui possiamo memorizzare dati in forma tabulare, secondo la ben nota logica colonne/campi. Non ci sono le relazioni in questo tipo di storage, ma la scalabilità è molto alta
  • Queue: questo servizio permette lo scambio di messaggi tra ruoli (Web e Worker) che compongono un'applicazione Web per  Windows Azure
  • Drive: come il nome lascia intendere, si tratta di hard disk virtuali formattati in NTFS che permettono caricamento/lettura di informazioni da parte delle applicazioni Web che girano su Azure

Maggiori dettagli potete trovarli in questo post di Mario Fontana, Evangelist di Microsoft Italia. A noi interessa il Blob Storage per diversi motivi, il primo dei quali è che è lo spazio che ha maggiormente senso anche in applicazioni client. Perchè? Beh, l'esempio che vi faccio è semplice: ho i miei documenti Word, le mie fatture in PDF, altri file che voglio mettere al sicuro nel mio spazio sul cloud e voglio farmi un banale client in WPF, Windows Forms, Console addirittura, per gestirli senza dover per forza lavorare lato Web (anche perché magari non ho modo di deployare seriamente un'applicazione Silverlight).

Programmabilità

Il Cloud Storage può essere raggiunto dagli sviluppatori con due tipiche modalità:

  • approccio REST, quindi scambio di informazioni tramite Http
  • API managed, usando librerie messe a disposizione da Windows Azure SDK 1.3

Noi utilizzeremo la seconda modalità in Visual Studio 2010. Per cui scarichiamo e installiamo l'SDK. Una volta installato, localizziamo la libreria chiamata Microsoft.WindowsAzure.StorageClient.dll all'interno della cartella C:\Programmi\Windows Azure SDK\v1.3\Ref. Ci tornerà utile tra pochissimo.

Fundamentals

No, questi ve li spiego nel codice.. è più divertente :-)

Iniziamo: CloudStorageAccount & CloudBlobClient

Apriamo Visual Studio 2010 e creiamo un nuovo progetto di tipo Class Library per Visual Basic 2010. Rinominiamo la classe principale in BlobService. Quando il progetto è creato, aggiungiamo un riferimento all'assembly Microsoft.WindowsAzure.StorageClient.dll sopra citato. Ora, di primo acchitto due cose ci interessano:

  • ottenere le credenziali di accesso al proprio spazio di storage
  • ottenere un riferimento managed allo storage stesso

La classe CloudStorageAccount, del namespace Microsoft.WindowsAzure, è il nostro primo contatto con lo storage e ci permette di definire le credenziali di accesso. Come sapete, le credenziali sono costituite dalla coppia Account Name e Shared Key. Il primo lo avete stabilito quando avete creato lo storage, il secondo è generato da Azure e potete recuperarlo nel portale di sviluppo, nella sezione dedicata allo storage. Il riferimento allo storage, invece, è rappresentato da una classe chiamata CloudBlobClient.

A livello di classe, quindi, iniziamo con l'aggiungere due dichiarazioni di questo tipo:

Public Class BlobService

    Private AccountInfo As CloudStorageAccount
    Private blobStorage As CloudBlobClient

La classe CloudStorageAccount fornisce diversi metodi per gestire le credenziali. In primo luogo, la classe ci permette di stabilire che vogliamo accedere allo storage locale di sviluppo, richiamandone la proprietà DevelopmentStorageAccount. Se invece vogliamo accedere allo storage online, possiamo generalmente utilizzare il metodo FromConfigurationSettings, nel caso in cui le credenziali risiedano nel file di configurazione dell'applicazione, oppure il metodo Parse (o TryParse) che invece analizza una stringa contenente le credenziali e la trasforma in un'istanza di CloudStorageAccount.

Poiché la nostra classe costituirà un modo semplificato ma univoco di accedere allo storage, possiamo fare questa distinzione offrendo due overload del costruttore, assumendo che, per ragioni di privacy, le credenziali di accesso allo storage online non siano memorizzate nel file di configurazione, bensì siano hard-coded:

    Public Sub New(ByVal accountName As StringByVal sharedKey As String)
        If String.IsNullOrEmpty(accountName) Or String.IsNullOrEmpty(sharedKey) Then
            Throw New ArgumentNullException()
        End If

        Me.AccountInfo = CloudStorageAccount.Parse("DefaultEndpointsProtocol=http;AccountName=" + accountName + ";AccountKey=" + sharedKey)
        blobStorage = AccountInfo.CreateCloudBlobClient()
    End Sub

    Public Sub New()
        'Use the dev account
        Me.AccountInfo = CloudStorageAccount.DevelopmentStorageAccount
        blobStorage = AccountInfo.CreateCloudBlobClient()
    End Sub

Come vedete, la stringa contenente le credenziali non ha forma libera ma deve rispettare alcuni punti fissi come l'indicazione del protocollo di end point e i due valori AccountName/AccountKey. Qualora invece volessi utilizzare il solo storage di sviluppo locale, non faccio altro che assegnare l'istanza col valore di DevelopmentStorageAccount che è prefissato.

Una volta che abbiamo l'istanza dell'account possiamo invocare il metodo di istanza CreateCloudBlobClient, che restituisce un tipo CloudBlobClient, per ottenere un riferimento managed allo storage, indipendentemente dalla sua locazione (on-line o locale).

Questo è fondamentale, perché l'oggetto CloudBlobClient così ottenuto mette a disposizione quanto necessario per accedere a container e blob. Ora la domanda che vi starete facendo è: si, ma se uno mette le credenziali errate come faccio a capirlo?

La risposta è relativamente semplice: il controllo delle credenziali non è automatico sull'istanza di CloudStorageAccount, quindi in teoria si possono immettere credenziali invalide. Il trucco è invocare un qualunque metodo (come ad esempio uno di quelli che elenca i container disponibili): se l'invocazione restituisce una StorageClientException, le credenziali non sono valide.

Non lo faccio ora perché prima dovrei spiegarvi i metodi per lavorare sui container, ma successivamente implementeremo questo tipo di controllo.

Lavorare con i Container

Il concetto di Container nel cloud storage è assimilabile al concetto di cartella su disco. Un container può contenere blob e altri container. La classe CloudBlobClient mette a disposizione diversi metodi per lavorare con i container, ma a fattor comune gli step sono:

  1. tento di ottenere un riferimento al container tramite il metodo GetContainerReference
  2. se non esiste, ho la possibilità di creare il container e di ottenere così il riferimento
  3. se esiste, ottengo il riferimento e basta

Il riferimento al container ci serve per poter gestire successivamente i blob ed è rappresentato dalla classe CloudBlobContainer. Giusto per semplificare l'approccio, cominciamo con l'ottenere l'elenco dei container disponibili sullo storage. Scriviamo codice che invochi il metodo di istanza ListContainers della classe CloubBlobClient:

    Public Overridable Function ListContainers() As IEnumerable(Of CloudBlobContainer)
        Try
            Dim result = blobStorage.ListContainers
            Return result

        Catch ex As Exception
            Throw
        End Try
    End Function

Essenzialmente questo metodo funge da wrapper, ma era necessario in una classe di "servizio" come questa. ListContainers restituisce IEnumerable(Of CloubBlobContainer) e ciascun elemento di questo insieme rappresenta un container, con le sue proprietà che vedremo meglio tra poco. Andando al contrario, vediamo come si elimina una cartella:

    Public Sub DeleteContainer(ByVal ContainerName As String)
        Dim container = blobStorage.GetContainerReference(ContainerName)
        container.Delete()
    End Sub

In pratica si ottiene il suo riferimento e si invoca il metodo di istanza Delete (è bene ovviamente verificare che il riferimento restituito non sia nullo, altrimenti non c'è da cancellare nulla). Passiamo ora a vedere come sia possibile creare un nuovo container. Consideriamo il seguente metodo:

    Public Overridable Sub CreateContainer(ByVal ContainerName As StringByVal IsPublic As Boolean)

        Try
            Dim container = blobStorage.GetContainerReference(ContainerName)
            container.CreateIfNotExist()

            If IsPublic = True Then
                container.SetPermissions(New BlobContainerPermissions With {.PublicAccess = BlobContainerPublicAccessType.Container})
            Else
                container.SetPermissions(New BlobContainerPermissions With {.PublicAccess = BlobContainerPublicAccessType.Off})

            End If

        Catch ex As StorageServerException
            Throw New StorageServerException
        Catch ex As Exception
            Throw New Exception(ex.InnerException.Message)
        End Try

    End Sub

Il codice:

  1. cerca di ottenere il riferimento al container
  2. se non lo trova, lo crea (CreateIfNotExists)
  3. assegna i permessi di accesso al container

Per permessi di accesso intendiamo la possibilità di rendere pubblico il contenuto del container oppure privato, che significa solo al proprietario dell'account che accede. Per farlo si invoca il metodo SetPermissions della classe CloudBlobContainer che riceve, come argomento, un'istanza della classe BlobContainerPermissions. Questa espone una proprietà chiamata PublicAccess, che va assegnata con un valore dell'enumerazione BlobContainerPublicAccess, come Off (privata) o Container (pubblica). A questo punto il container viene creato nello storage.

Se successivamente volessi ottenere un riferimento a tale container mi basterebbe scrivere:

Dim container = blobStorage.GetContainerReference(ContainerName)

Ora dovrebbe essere anche più chiara la modalità con cui è possibile testare la validità delle credenziali di accesso: invoco semplicemente ListContainer all'interno del costruttore, dopo l'ottenimento dell'istanza di CloudStorageAccount, e controllo che non restituisca una StorageClientException.

Fine della puntata

La prima parte finisce qui, dopo aver visto come accedere allo storage e gestire container. Nel prossimo post vedremo qualcosa di più interessante, ossia la gestione dei blob in modalità asincrona.

Alessandro

Print | posted on mercoledì 12 gennaio 2011 16:18 | Filed Under [ Visual Basic Windows Azure and SQL Azure ]

Powered by:
Powered By Subtext Powered By ASP.NET