“The green is going better, isnt’it?”

For the past few days, I’ve been working on a presentation for a meeting scheduled for next week. To highlight some aspects I have prepared some graphics to be included in the slides.

While I was busy drawing a red band to highlight the differences between trends before and after a certain date, my son who was silently watching me over my shoulder started asking me questions. So, avoiding going too far into the complexity of the topics, I explained the graphs and how they told us how we were working. In particular, he was struck by a CFD that, after a certain date, changed its slope due to an action that allowed the throughput to increase.

Today he called me and, after showing me some bricks on a piece of furniture, he said: “See? The green is going better, isn’t it?”.

This small event is yet another confirmation of my belief: data visualization is a very effective way to understand facts and convey messages. It is for this reason that we use boards to represent the updated workflow state, gather data and produce graphs that describe the progress of work. These artifacts help us to understand the reality in which we move, highlight relationships, show changes, tell us a story so that, once interpreted, allows us to act and move towards continuous improvements.

Pubblicato in Project management | Lascia un commento

E’​ il momento delle visioni condivise e dell’innovazione

L’emergenza del Coronavirus ha dato inizio a una serie di cambiamenti nelle abitudini delle persone creando nuove necessità. Allo stesso momento le modifiche delle normative e la profonda alterazione degli ambiti di mercato hanno impattato sulle aziende, facendo emergere sia problematiche che nuove strategie. Nascono così necessità di nuovi strumenti, adeguati alle sfide da affrontare.

In questo scenario le aziende che si occupano di tecnologia hanno un duplice ruolo. Da un lato possono offrire gli strumenti necessari alle aziende per affrontare le trasformazioni in atto, contribuendo attivamente in un rilancio dell’economia. Dall’altro possono cogliere l’opportunità di coprire le nuove esigenze che emergono dalla trasformazione della nostra quotidianità.

Affinchè questo possa essere realizzato, secondo il mio punto di vista, sono necessari due ingredienti:

  • la presenza di spirito di innovazione ed energia nelle aziende;
  • la capacità di identificare nuovi ambiti di servizio/mercato, verificare le iniziative e ridurre i rischi, attraverso un processo sperimentale ed incrementale.

Visioni condivise

Esprimere il concetto di visione non è semplice. Una visione non è un’idea. E’ qualcosa di più profondo. Va al di la dei risultati e degli scopi, che sono solo l’indicazione astratta di una direzione. Una visione è una destinazione specifica, l’immagine di un futuro a cui si aspira, è qualcosa di concreto. Ad esempio: “creare le tecnologie per conquistare lo spazio” è uno scopo, mentre quando John Fitzgerald Kennedy disse “Abbiamo scelto di andare sulla Luna in questo decennio” dipinse una visione.

Ognuno di noi sviluppa delle visioni, ed è ben cosciente della distanza che hanno dalla realtà. Può essere causa di scoraggiamento, ma è proprio la distanza della visione a spingerci ad agire, e questo fa delle visioni una grande fonte di energia.

Sono certo che l’esperienza condivisa della pandemia e del lockdown è anche fonte di ispirazione per visioni personali positive. Di queste, le visioni che vanno al di la del nostro perimetro familiare sono particolarmente preziose, soprattutto se si creano le condizioni per una convergenza. Attraverso il dialogo si può arrivare a una visione condivisa e, quando questo accade, quella di una azienda può coincidere con quelle delle persone che ne fanno parte. Questo consente alle persone e alle aziende di esprimere il massimo potenziale: l’impegno di ognuno non nasce dall’omologazione, ma dalla coscienza di essere co-creatori di una nuova realtà a cui tutti si tiene.

Sperimentazione

La visione condivisa può contribuire a far emergere il pensiero laterale e ispirare l’apprendimento e l’innovazione. In questo modo le visioni si trasformano in potenziali prodotti e servizi, che vanno proposti a un mercato particolarmente instabile. Le condizioni di business durante la pandemia si sono rivelate estremamente variabili, cambia la mobilità delle persone, cambiano le normative, nascono e spariscono focolai di infezione… Oggi più che mai è necessario un approccio adattivo, realizzando prodotti e servizi in modo progressivo e misurandone continuamente risultati ed efficacia. E’ il momento del Ciclo di Deming, a ogni piano e iniziativa deve seguire una verifica e un adattamento.

Questo approccio va usato anche per la validazione delle iniziative, prima ancora di iniziare effettivamente a realizzarle. Ad esempio, utilizzando il Design Sprint è possibile testare i prototipi del prodotto o del servizio in cinque giorni. Un Design Sprint consente di definire le priorità e identificare una serie di soluzioni. Eletta una soluzione, ne viene realizzato un prototipo realistico da testare con un campione dei clienti di riferimento. Il risultato del test consente di apprendere informazioni vitali sull’efficacia della soluzione e determinare le azioni strategiche da eseguire come passo successivo.

Per chi volesse approfondire, sul sito thesprintbook.com è disponibile la “Remote Design Sprint Guide” che suggerisce come poter procedere a un Design Sprint rispettando i requisiti di distanziamento sociale.

Opportunità

Qualche giorno fa ho avuto la possibilità di osservare la mappa mentale “Ripple effects of the Low Touch Economy” prodotta da Board of Innovation.

E’ un lavoro notevole che riassume molti degli effetti causati dalla pandemia e ne rappresenta in modo efficace le correlazioni. Ho cercato di focalizzarmi sugli effetti che possono essere gestiti creando un adeguato supporto tecnologico o che rappresentano opportunità di innovazione. Non sono pochi.

In questo periodo di stravolgimento sociale le opportunità di innovazione non andrebbero intese solo come occasioni di evoluzione tecnologica e rilancio economico, ma anche di crescita sociale ed etica. Ci sono molti ambiti in cui è possibile lavorare, provo a elencarvene qualcuno, ma vi invito a provare anche voi questo esercizio. La pandemia può essere affrontata con uno spirito positivo e lungimirante.

Una vita contactless

Le maggiori precauzioni dal punto di vista igienico scoraggiano i contatti tra persone e con gli oggetti condivisi. Nasce la necessità di cambiare il mostro modo di fare le cose, utilizzando sempre di più approcci che limitano il contatto. La risposta a queste nuove esigenze è già in atto, con soluzioni che, ad esempio, fanno leva sul riconoscimento del viso (o dell’iride) e sull’interazione con display olografici.

Un nuovo modo di concepire la sanità

La necessità di limitare l’esposizione ai virus ha disincentivato l’accesso agli ospedali. Questo da un lato ha portato a un incremento di pazienti con diagnosi tardive e dall’altro ha creato la necessità di nuove soluzioni e-health, di terapia remota e di monitoraggio dei soggetti a rischio. In questi ambiti c’è sicuramente molto da fare.

In ambito aziendale, la crescente attenzione all’igiene e alla prevenzione, da origine alla necessità di varchi di sicurezza sanitaria e sistemi discreti per il monitoraggio delle temperature corporee. Anche in questo caso ci sono molte necessità da coprire, anche nell’ambito dei servizi pubblici.

Turismo locale

Le restrizioni sui viaggi stanno alterando profondamente il mercato del turismo e incentiveranno forme di turismo locale. Si avrà un rinnovato interesse sulle offerte in aree rurali e naturalistiche, a svantaggio delle mete in ambito cittadino. La riduzione dei contatti farà si che il viaggio sia concepito in una sfera più familiare o, comunque, ridotta alla cerchia più ristretta delle amicizie. Tutto questo richiede che gli strumenti di promozione turistica e di organizzazione dei viaggi vadano ripensati ed adeguati.

Un nuovo approccio alla mobilità

Il distanziamento sociale ha già disincentivato l’utilizzo dei mezzi di trasporto pubblico, costringendo a una riduzione dell’offerta delle infrastrutture di trasporto. La conseguenza è una maggiore diffusione di modalità di trasporto individuale e maggiore interesse per le soluzioni di micromobilità. Questo implicherà delle opportunità di potenziamento dei sistemi si trasporto condiviso ma anche, viste le precauzioni di carattere igienico-sanitario, una revisione del modello di offerta.

Nuove esperienze di acquisto

L’interazione tra dipendenti e clienti è già vista come un rischio. Questo farà acquisire maggior interesse verso le value chain con interazione minimale facendo aumentare la necessità di automazione del retail. L’esperienza di acquisto sarà rivista alla luce della necessità di distanziamento sociale, e il commercio elettronico evolverà con l’automazione del delivery. Nuove modalità di acquisto per le fasce più anziane della popolazione o su appuntamento saranno sempre più comuni e dovranno essere indirizzate con soluzioni mirate.

Conclusioni

I cambiamenti legati alla pandemia, nonostante gli impatti negativi dal punto di vista sociale ed economico, rappresentano anche opportunità di innovazione. Le aziende che si occupano di tecnologia hanno un ruolo strategico e possono contribuire in modo significativo sia al rilancio economico che a uno slancio nella crescita tecnologica, soprattutto se hanno spirito di innovazione e riescono ad attingere pienamente al potenziale umano di cui dispongono.

L’evoluzione continua della pandemia e delle condizioni di mercato richiederà la validazione delle iniziative con strumenti sia efficaci che economici, e renderà essenziale l’uso di strategie adattive con cicli di ispezione e adattamento.

Il cambiamento delle abitudini e dell’assetto sociale farà nascere nuovi prodotti e servizi e, per consentire il rispetto delle precauzioni igieniche e di distanziamento sociale, darà luogo alla trasformazione di quelli attuali. Questo può dare uno slancio all’innovazione e rappresentare un’opportunità di crescita etica e sociale.

Secondo voi quali in quale modo le aziende dei comparti tecnologici potranno assistere le altre nella ripresa economica? Quali immaginate possano essere le innovazioni che nasceranno a seguito della pandemia?

Pubblicato in Cloud computing | Lascia un commento

L’epidemia di Coronavirus in una visione di sistema

In questi giorni riflettevo sulla situazione del Coronavirus e, in particolare, su come il tempo di incubazione causi un notevole ritardo tra ciò che facciamo per ostacolarlo e l’effetto reale delle nostre azioni. Riflettevo anche sulla “fase di negazione” che, tutte, ma proprio tutte, le nazioni hanno fino ad ora attraversato prima di aggredire seriamente il problema.

In systems thinking mi hanno sempre affascinato gli archetipi. Gli archetipi sono una sorta di alfabeto che consente di descrivere sistemi complessi combinando insieme strutture fondamentali e per le quali corrisponde un principio di gestione ottimale. E’ un po’ come l’applicazione dei pattern architetturali nell’ingegneria del software, ma per descrivere una realtà già esistente.

Ciò che sta accadendo con il COVID19 può essere rappresentato nel linguaggio degli archetipi. Le loro rappresentazioni elementari rendono evidente la natura delle cose, i comportamenti delle persone e suggeriscono quali potrebbero essere le azioni corrette da perseguire.

L’arrivo del virus e la negazione

Di fronte all’arrivo del pericolo grave dell’epidemia la prima reazione che abbiamo osservato in tutti i paesi è stata quella di applicare una soluzione non definitiva, sintomatica, che va dal non affrontare il problema (vedi la teoria dell’immunità di gregge di Johnson) all’azione blanda (limitazione di alcuni voli in Italia). Le ragioni di questa inerzia sono molteplici (per un approfondimento suggerisco questo articolo di Hardward Business Review), ma sicuramente ha influito il potenziale impatto sulla nostra vita sociale ed economica di una azione radicale. Quello che è accaduto è un esempio da manuale dell’archetipo “Shifting the burden”:

Il sistema della diffusione del virus è controllato da due processi che tendono all’equilibrio, uno prevede l’applicazione di una soluzione fondamentale e l’altro di una soluzione sintomatica. La soluzione fondamentale consiste nell’applicazione di rigorose iniziative di distanziamento sociale, costose anche dal punto di vista economico, che hanno un effetto reale ritardato. La soluzione sintomatica, invece, ha un’apparente efficacia immediata ma presenta l’effetto collaterale di contribuire all’espansione del problema e di indebolire la capacità di risposta con una soluzione fondamentale. La perdita di tempo nell’applicazione delle iniziative di distanziamento sociale implica un aumento silente delle persone in incubazione ed asintomatiche e la diffusione ulteriore dell’epidemia. La diffusione dell’epidemia ha un impatto sul sistema sanitario che inizia a perdere la sua capacità di risposta. Il risultato è una possibile ulteriore diffusione delle infezioni, che limitano ulteriormente la capacità di reazione. Una sorta di “fuga termica” che, di fatto, riduce progressivamente la capacità di affrontare il problema.

Nonostante il notevole costo economico e l’apparente inefficacia iniziale, il modo migliore per afforntare questo archetipo consiste nel focalizzarsi sulla soluzione fondamentale, usando (se proprio è necessario) la soluzione sintomatica solo come un metodo per recuperare tempo per organizzare una azione realmente risolutiva.

La reazione

Fortunatamente la presa di coscenza del problema, nonostante gli impatti sui sistemi sanitari (e qui non posso non fare una carezza ai nostri amici spagnoli), ha dato luogo a reazioni corrette. Si è creata una nuova condizione, anch’essa descrivibile con un archetipo elementare noto come “Limits to growth”:

Come noto il contatto tra le persone ha un diretto contributo sulla diffusione del virus e provoca una crescita esponenziale dei casi. Per limitare la diffusione delle infezioni gli stati hanno applicato delle norme di distanziamento sociale. Il distanziamento sociale ha un costo significativo, sia in termini economici che emotivi, ed è applicato sotto la spinta della coscienza del pericolo e delle pressioni governative (sanzioni).

La mente umana non è capace di gestire bene realtà in cui il rapporto di causa ed effetto non è strettamente relazionato nel tempo e nello spazio e questo implica un pericolo di cui è bene che tutti prendano coscienza. In un sistema con queste caratteristiche la limitazione della crescita è strettamente legata alla pressione sulla condizione limitante.

Al rallentamento della diffusione del virus si presenterà naturalmente la tendenza a mollare la presa. Noi, sia come governi che come singole persone, spinti dalla rassicurazione dei dati, dal peso economico e desiderosi di ammorbidire una condizione emotivamente dolorosa, cercheremo di trovare un compromesso.

Questo è molto pericoloso.

La necessaria perseveranza

Il comportamento dell’epidemia è descritto da un archetipo noto come “Balancing process with delay”.

Le condizioni di diffusione dell’epidemia sono contrastate dalle iniziative di distanziamento sociale che, però, hanno un effetto ritardato sul problema. Questo archetipo richiede un principio di gestione ben noto, che cito testualmente dal libro La quinta disciplina di Peter Senge:

“In a sluggish system, aggressiveness produces instability. Either be patient or make the system more responsive.”

La natura del virus non consente di abbreviare il ritardo tra un intervento e il suo effetto, per cui è necessario esercitare la nostra pazienza. Di fronte a un’apparente rientro della crisi dovremo perseverare e attendere un po’ più a lungo di quanto l’intuito possa suggerire. E’ quasi paradossale, ma persistere nel distanziamento sociale è l’unico modo per ritornare velocemente ai nostri affetti e alla nostra quotidianità.

Pubblicato in Cloud computing | Lascia un commento

“Flight, EECOM. Try SCE to Aux”

14 novembre 1969, ore 16:22 UTC

Il razzo Saturn V della missione Apollo 12, immediatamente successiva a quella che portò l’uomo per la prima volta sulla Luna, inizia a sollevarsi dalla rampa di lancio. Il cielo sul Kennedy Space Center a Cape Canaveral è molto nuvoloso. Piove e durante l’ascesa i venti raggiungono velocità fino a 280 km/h.

36 secondi dal lancio

Un lampo brillante, uno scossone. Tre celle a combustibie si disconnettono dal bus di alimentazione e i 75 ampere necessari alla navetta sono prelevati dalle batterie. Gli specialisti del Controllo Missione iniziano a ricevere dati telemetrici confusi. I tre astronauti si rendono subito conto di avere un grosso problema e passano alla modalità “Abort Mode I-Bravo” preparandosi ad un eventuale annullamento della missione.

52 secondi dal lancio

Un nuovo scossone. La piattaforma di guida smette di funzionare. Un secondo fulmine colpisce il veicolo e fa perdere le informazioni sull’orientamento del razzo. Fortunatamente, in questa fase del volo, il sistema di guida è utilizzato dall’equipaggio per monitorare l’ascesa senza controllare attivamente il veicolo. Il Controllo Missione continua a ricevere dati telemetrici illeggibili.

1 minuto e 36 secondi dal lancio

John Aaron è il controllore di volo incaricato come Electrical, environmental and consumables manager (EECOM). Osserva i dati della telemetria, ancora confusi.

Suggerisce al direttore di volo di alimentare il SCE (Signal Conditioning Equipment) con il sistema ausiliario.

“Flight, EECOM. Try SCE to Aux”

Nei suoi dati alterati, Aaron ha riconosciuto uno schema. Un anno prima, per pura coincidenza, Aaron era in Mission Control durante una simulazione della piattaforma di lancio. E quella notte, ricordò, aveva brevemente notato sullo schermo una serie simile di dati incomprensibili. Si rese conto che la squadra che gestiva i sistemi aveva brevemente interrotto l’alimentazione della capsula.

La variazione di tensione aveva prodotto un malfunzionamento sul dispositivo SCE, responsabile del condizionamento dei segnali grezzi dai sensori in modo che le informazioni potessero essere visualizzate sugli strumenti e trasmesse a Houston. Commutando in modalità di alimentazione ausiliaria — Aux — il SCE avrebbe ripreso a funzionare e gli strumenti sarebbero tornati online. A quel punto, le celle a combustibile potrebbero essere ricollegate al bus di alimentazione.

“Try FCE to Auxiliary. What the hell is that?”

Aaron dovette ripetere il suo suggerimento al direttore di volo perchè il SCE era un componente oscuro ai più. Gli stessi astronauti nella navetta non identificarono al volo l’interruttore, come avrebbero fatto per la maggior parte degli altri comandi.

1 minuto e 50 secondi dal lancio

Con il SCE sull’alimentazione ausiliaria la telemetria riprende a funzionare correttamente. Le tre celle a combustibile sono di nuovo on line, i sistemi del veicolo gradualmente riprendono a funzionare. La missione è salva.

La curiosità di John Aaron

Alcune settimane dopo il suo pensionamento, John Aaron venne intervistato da uno storico della Nasa. Raccontò che quando notò una strana firma dei dati durante la simulazione di lancio in una notte del 1968, la sua “naturale curiosità” lo portò a capire meglio perché fosse accaduto. Si trovò di fronte alla stranezza di una telemetria con dati illeggibili (non tutti a zero come si sarebbe aspettato) e cercò di capire il perchè. Fu un’iniziativa personale, mossa dal desiderio di comprendere e di imparare, che ha salvato i costi e potenzialmente le vite legate alla missione.

Adesso diremmo che John Aaron ha percorso l'”extra mile”, approfondendo di sua iniziativa la funzionalità di un componente sconosciuto.

Extra mile e cultura aziendale

Secondo Peter Senge, un’azienda può sopravvivere se diventa una “learning organization”. Un’organizzazione in cui

  • le persone espandono continuamente la loro capacità di creare i risultati che desiderano
  • i risultati sono coerenti con una visione collettiva
  • sono alimentati nuovi ed espansivi schemi di pensiero
  • l’aspirazione collettiva viene liberata e le persone imparano continuamente come apprendere insieme.

Mi piace pensare che l’iniziativa di Aaron abbia avuto origine nella cultura e nella visione condivisa in quel periodo storico. Il personale coinvolto nelle missioni Apollo era il più capace sulla piazza e stava, letteralmente, costruendo una nuova tecnologia. Tutti stavano creando qualcosa di nuovo, puntando all’obbiettivo comune di eccellere nella corsa allo Spazio.

In queste condizioni, con questo livello di coinvolgimento, è naturale che le organizzazioni ottengano più di quanto si aspettano. Percorrere l'”extra mile” non è una cosa che può essere richiesta. Non è uno straordinario. E’ entusiasmo e coinvolgimento, e solo la giusta cultura aziendale può far si che si manifesti in modo spontaneo.

Pubblicato in Agile | Lascia un commento

4 aprile: Inizio sprint 1

Sono solito scrivere i miei appunti su carta e non butto mai via le mie vecchie agende. Ho sempre pensato siano utili, soprattutto quando sono ben “stagionate”, perchè riescono a rappresentare in modo oggettivo i cambiamenti e le evoluzioni rispetto al momento in cui sono state utilizzate.

Qualche giorno fa, senza una ragione particolare, ho pescato un’agenda dalla libreria e ho iniziato a sfogliarla. Pian piano mi ha evocato ricordi lontani, le esperienze condivise con i colleghi, i clienti e le sfide. All’improvviso, ecco il 4 aprile con una nota importante: Inizio Sprint 1.

Ricordo molto bene quel giorno. E’ stato un passaggio cruciale nella mia esperienza lavorativa e nella mia formazione personale. Dopo aver tanto letto e raccontato di approcci agili, si iniziava a dare corpo alle idee. Era una sfida: tutte le teorie di cui ero venuto a conoscenza fino ad allora reggeranno il confronto con la realtà?

Quel primo esperimento fu un successo, anche grazie alle persone eccezionali che mi circondavano, e sancì l’inizio di una agile transformation. Di fronte a questa pietra miliare non potevo non fermarmi a riflettere…

Le condizioni per la massima espressione del potenziale

“Bisogna aver cura delle persone”- E’ una frase che ho sentito dire tante volte. Tutti riconoscono come vera questa affermazione. E’ una considerazione ovvia, ma solo in apparenza. Ho sentito persone affermarla con forza, ma agire inconsapevolmente in modo distruttivo, così come ho visto persone sostenere al meglio i propri collaboratori, senza neanche rendersene conto. Non credo ci sia un unico approccio corretto, le variabili in gioco sono molteplici. Ci sono, però, delle condizioni che consentono di esprimerci al meglio e, per quanto possibile, è sempre neccesario crearle o mantenerle.

Secondo la mia opinione, un approccio che danneggia gravemente la qualità dei risultati e il clima lavorativo è quello in cui le persone sono viste come puri esecutori. E’ una visione tayloriana, lontana dalla realtà di oggi, soprattutto in ambiti in cui la competenza e la specializzazione è elevata. La pura esecuzione di compiti trasforma il rapporto lavorativo in una transazione economica: l’azienda mi paga in cambio del lavoro che mi è stato indicato di fare. La perdita di valore è evidente. L’ingegnosità, l’entusiasmo e il contributo in termini di diversità di visione e pensiero è il vero contributo che ognuno di noi porta all’organizzazione per cui lavora.

Uscire da questo modo di lavorare a volte è complicato. Richiede la piena fiducia nelle persone con cui si lavora (non è sempre necessario?) e, soprattutto, richiede la reale delega di alcune responsabilità.

Il gruppo come unità produttiva

Spesso consideriamo come artefici del risultato le singole persone nel gruppo di lavoro. In realtà è molto più efficace intendere l’intero gruppo, il team, come unità produttiva. Pensiamo per un attimo al modello delle task force. Una task force è un gruppo di persone che lavora a un obiettivo chiaro e a breve scadenza. Il gruppo si organizza in modo autonomo, in base alle condizioni del momento, per raggiungere al meglio lo scopo da raggiungere. Tutti contribuiscono al successo, mettendo a frutto i propri talenti. Ogni componente del gruppo è sia protagonista che responsabile del risultato.

Il modello della task force è usato in condizioni di emergenza perchè è efficace, ed è efficace perchè consente la massima espressione di tutti. In generale se il gruppo possiede:

  • Un obbiettivo chiaro e condiviso
  • Competenze trasversali
  • Un numero di componenti limitato
  • La responsabilità completa e collegiale del risultato, per tempi, costi e qualità
  • La libertà organizzativa nel raggiungimento del risultato, mantenendo un approccio che punta all’eccellenza

è probabile che otterrà il risultato in modo ottimale.

L’efficienza e la quantità di lavoro in gioco

Un gruppo di lavoro efficiente non è compresso in deadline “subite” o in attività dai ritmi affannati. L’efficienza, ancora una volta, si ottiene consentendo alle persone di esprimersi al meglio. Ciò significa lasciare il gruppo libero di stimare l’effort delle sue attività, di influenzare la scelta di cosa è possibile ottenere in un certo tempo e avere la possibilità di lavorare senza interruzioni. Inoltre, e questo è anche più importante, se il gruppo misura la propria capacità produttiva e ambisce a un miglioramento continuo, avendo la facoltà di modificare le condizioni o gli strumenti di lavoro, può massimizzare spontaneamente la propria efficienza.

Il bisogno di crescere

Se avere un team che riesce a ottenere buoni risultati è importante, ambire all’eccellenza in ogni aspetto è la cultura vincente. Tutti noi abbiamo bisogno di una spinta evolutiva, che consente di mettersi in gioco e apprendere. Anche dai propri errori. Uno strumento eccezionale in questo senso è l’autocritica. Avere la facoltà e la completa libertà di criticare il proprio operato consente di capire come migliorarsi, e garantisce all’organizzazione di reagire naturalmente alle mutazioni del contesto in cui lavora. E’ un viaggio che ambisce a una meta ideale e che si muove asintoticamente in quella direzione.

L’illusione del buon senso

Creare le condizioni ottimali per la massima espressione del potenziale sembra una pura questione di buon senso. E questo è un problema perchè porta all’approssimazione. Anch’io in passato ho creduto che il buon senso fosse non solo necessario ma anche sufficiente a consentire le condizioni ideali di lavoro. Mi sbagliavo. E’ necessaria l’applicazione di un metodo formale e di tanto studio. Il buon senso è un falso consigliere perchè da una errata sensazione di padronanza del contesto o della situazione. Per dirne una, il buon senso direbbe di non toccare il codice che funziona, ma le buone pratiche prevedono il refactoring…

Spesso, quando iniziano ad affiorare i dubbi siamo sulla buona strada. Vuol dire che davvero si sta procedendo verso una maggiore presa di coscienza delle cose.

Pubblicato in Agile | Lascia un commento

Planning poker: il metodo Delphi al servizio di Scrum

Il problema

Immaginate di prepararvi per uno Sprint Planning Meeting: l’efficacia della pianificazione dipenderà, tra le altre cose, dalla qualità della stima dell’effort per ogni backlog item. La stima può essere effettuata discutendo insieme sui dettagli dell’attività e arrivando ad un valore condiviso ma questo percorso, apparentemente tranquillo, è pieno di trappole.
Ogni membro del team può avere una percezione differente dell’entità del lavoro necessaria e, nonostante questo, si può affidare al parere di un collega più esperiente, che ha inserito la storia nel product backlog dopo una telefonata col cliente o, semplicemente, non si  esprime perchè non è sufficientemente coinvolto.  Il risultato è che in una discussione “tradizionale” si possono perdere delle informazioni che, seppur presenti nel gruppo, non contribuiscono al processo decisionale.

Esistono dei metodi formali per approcciare il processo decisionale in modo ottimale e questi, aldilà delle valutazioni scientifiche, partono da un concetto ben noto: “due teste sanno più cose di una sola”. In un team ci sono tante teste, vediamo quindi come sfruttarle bene!

Il metodo

Il planning poker è una metodologia per la stima dell’effort necessario per portare a completamento una attività. Ogni partecipante al processo di stima è in possesso di una serie di carte simili a quelle da gioco (di cui il nome) rappresentanti la scala numerica della serie di Fibonacci o una sua approssimazione (ad.es: 0, 1/2, 1, 2, 3, 5, 8, 13, 20, 40, 100). Presentato l’argomento, ognuno sceglie una singola carta con valore adeguato alla propria stima personale e la depone sul tavolo coperta. Non appena tutti hanno fatto la propria scelta, le carte vengono scoperte contemporaneamente. Se i valori sul tavolo sono discordanti, viene avviata una discussione volta a identificare le ragioni delle differenze. Esaurita la discussione viene effettuata una nuova selezione delle carte, analogamente a quanto fatto inizialmente. Il processo viene ripetuto fino a quando non si ha una convergenza su un valore condiviso.

Il planning poker, molto diffuso tra gli utilizzatori di processi agili di sviluppo software, è  una applicazione del metodo Delphi messo a punto dalla RAND Corporation negli anni ’50 ed oggetto di studi e approfondimenti successivi. Il metodo Delphi è caratterizzato da:

  • Anonimità dell’opinione
  • Feedback controllato in un processo iterativo
  • Analisi della risposta statistica del gruppo

L’anonimità dell’opinione è richiesta per limitare l’effetto della presenza di individui dominanti nel processo decisionale. Il loro effetto è tipicamente quello di annullare il contributo di alcuni partecipanti, che adeguano la loro posizione sulla base dell’autorevolezza di qualcun’altro. Ciò riduce l’efficacia del processo: una divergenza iniziale è sempre un contributo alla qualità della decisione finale. Nel planning poker ciò è ottenuto presentando le stime contemporaneamente, a garanzia dell’autonomia della decisione dei partecipanti.

La revisione dei risultati di ogni interazione rappresenta il feedback controllato sul processo decisionale. La divergenza di opinioni può nascere, oltre che dal diverso grado di esperienza dei partecipanti, anche dalla sottovalutazione (o sopravvalutazione) della complessità dell’argomento o da una comprensione differente dello scope dell’attività oggetto di discussione. La discussione avviata alla fine di ogni iterazione permette lo scambio di informazioni tra i partecipanti col risultato di una definizione più precisa dei contorni dell’argomento discusso e una migliore valutazione delle implicazioni nascoste. L’effetto è che ad ogni iterazione si ha una sempre più definita convergenza verso un valore condiviso.

Il metodo Delphi, e quindi anche il planning poker, in virtù dello scambio di informazioni  e del valore attribuito al contributo di ogni partecipante, permette non solo di mantenere la discussione stimolante e interessante per tutti ma anche di rassicurare il gruppo sulla qualità delle decisioni assunte. Infatti, l’uso di una procedura sistematica e formale, attribuisce oggettività ai risultati.

Una nota sulle carte

L’utilizzo della serie numerica di Fibonacci o un suo adattamento non è casuale. E’ una garanzia ulteriore della qualità della stima effettuata: la sequenza numerica ha numeri progressivamente più distanti al crescere del loro valore, il che equivale a dire che più tempo  immagino di impiegare per portare a termine il lavoro, maggiore sarà l’imprecisione della stima. Ciò porta naturalmente alla frammentazione delle storie sul product backlog troppo ad alto livello in un insieme di storie minori che portano comunque un valore tangibile.
Oltre alle carte numeriche possono essere presenti due carte aggiuntive: una col punto interrogativo ed una con una tazza da caffè.
La prima indica che non si è in grado di fare nessuna stima. Se viene usata da uno o più  partecipanti significa che l’argomento di discussione non è ben definito o è troppo vasto: va chiarito o frammentato.
La carta con la tazza di caffè, che credo sia stata aggiunta da Crisp, rappresenta un concetto semplice: pausa! Questa carta è più efficace se, a dispetto delle regole, ci si mette d’accordo per avere la convergenza di opinione!

Se voleste approfondire la conoscenza del metodo Delphi, vi suggerisco The Delphi Method – An Experimental Study of Group Opinion, liberamente scaricabile dal sito della RAND Corporation.  Se invece siete alla ricerca delle carte da planning poker, vi raccomando un mazzo come quello che ho fotografato. Potete acquistarlo da Crisp a soli 6.38 euro+IVA, spedizione inclusa.

Pubblicato in Agile, Project management | Contrassegnato , , , , , , , | 2 commenti

Windows Azure Web Role in PHP

Windows Azure non è solo per chi sviluppa soluzioni utilizzando Visual Studio ed i framework .NET. Infatti, è possibile creare ed erogare dei cloud service anche utilizzando Java, Ruby o PHP. In questo post vedremo quanto è semplice usare PHP per muovere i primi passi su Windows Azure.

Per seguire questo tutorial è necessario predisporre  Eclipse per lavorare su Windows Azure. Maggiori dettagli sui prerequisiti e sulla preparazione dell’ambiente di sviluppo sono disponibili nel post Anatomia e sviluppo di una soluzione cloud per Windows Azure. Inoltre, sebbene faccia riferimento all’utilizzo di Visual Studio, è consigliabile dare una lettura ai due post della serie Hello Web Role! per familiarizzare con i web role e gli storage service.

Un po’ di teoria

Windows Azure supporta il modulo FastCGI di Internet Information Server 7.0 consentendo la realizzazione di web role che eseguono applicazioni scritte in linguaggi interpretati o in codice nativo. Per creare un web role che esegue una applicazione FastCGI è necessario innanzitutto verificare che l’impostazione  del flag enableNativeCodeExecution sul file ServiceDefinition.csdef sia true (è il valore di default sugli ultimi SDK):

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="Simple"
xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WebRole" enableNativeCodeExecution="true">
    <ConfigurationSettings>
    </ConfigurationSettings>
    <InputEndpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </InputEndpoints>
  </WebRole>
</ServiceDefinition>

Inoltre è necessario includere il file opzionale web.roleConfig sulla radice del progetto. In questo file va specificato il percorso assoluto all’interprete o all’applicazione in codice nativo. Per specificare il percorso assoluto viene utilizzata la variabile d’ambiente %RoleRoot%. Questa ritorna il percorso assoluto alla radice dell’albero di directory in cui è in esecuzione il web role (dove sono presenti i file web.config e web.roleConfig). Un esempio di file web.roleConfig è:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.webServer>
    <fastCgi>
      <application fullPath="%RoleRoot%\approot\php\php.exe"/>
    </fastCgi>
    </system.webServer>
</configuration>

Un handler specifica quale risorsa di IIS gestisce la risposta per un certo tipo di richiesta. Configurando opportunamente l’handler è possibile indicare che sarà l’interprete PHP a gestire le richieste al server che fanno riferimento a file con estensione php. Tutte le richieste che collimano con il filtro path sulla definizione dell’handler verranno girate a php.exe (vedi MSDN). La configurazione degli handler viene effettuata nell’elemento handlers dell’elemento system.webServer sul file web.config, come segue:

<system.webServer>
…
  <handlers>
  …
    <add name="PHP via FastCGI" path="*.php" verb="*"
        modules="FastCgiModule"
        scriptProcessor="%RoleRoot%\approot\php\php-cgi.exe"
        resourceType="Unspecified" />
  </handlers>
</system.webServer>

Affinchè il role funzioni correttamente è necessario includere l’interprete nel progetto. Questo sarà compatibile con Windows Azure solo se è possibile effettuarne il deployment attraverso un semplice xcopy. La posizione dell’interprete deve combaciare con quella specificata con l’attributo fullPath dell’elemento application nel file webRole.config.

Sviluppare il web role con Eclipse

Muoverei primi passi verso lo sviluppo di un web role in PHP con Eclipse è estremamente facile. Vedremo infatti che la procedura guidata per la creazione del progetto permette di selezionare le feature da utilizzare e genera dei file php con degli esempi d’uso molto utili. Apriamo Eclipse, lanciamo la procedura guidata per la creazione di un nuovo progetto Windows Azure PHP Project e inseriamo il nome:

Windows Azure PHP ProjectPHP Azure Project NameAl terzo passo è possibile iniziare la configurazione del web role, a partire dal nome. Il checkbox Enable Windows Azure App Fabric support for this project inserisce nel progetto le classi per l’utilizzo dell’Access Control Service e il Service Bus. Visto il livello introduttivo del tutorial non approfondiremo l’argomento in proposito, ma vi consiglio di dargli un’occhiata. Il tab Data Storage Options permette di abilitare l’utilizzo dei servizi di storage e configurare le credenziali di accesso. Nel nostro caso useremo il development storage. Opzionalmente è possibile configurare anche le credenziali per l’accesso ad un database SQL Azure. Prima del deployment sarà possibile cambiare le impostazioni editando il file ServiceConfiguration.cscfg.

Windows Azure PHP Web RoleIl tab PHP Runtime permette di scegliere tra l’interprete PHP 5.3.4 compreso nel kit di sviluppo o una versione specifica installata sulla macchina.

Windows Azure PHP web role PHP runtimeSu Diagnostics è possibile attivare Windows Azure Diagnostics e specificare lo storage in cui inserire le informazioni diagnostiche, il livello di logging e l’intervallo di trasferimentio dei dati. Su Windows Azure Drives è possibile configurare l’utilizzo di eventuali Drives.

Windows Azure PHP web role diagnosticsCliccando su Finish viene creato il progetto. Le impostazioni di cui abbiamo parlato in precedenza dovrebbero essere già corrette. Dopo aver avviato il Compute Emulator e lo Storage Emulator, clicchiamo sul file index.php e selezioniamo Run/Run As/PHP Windows Azure Page. Dopo alcuni istanti viene aperta la pagina contenente il tipico output della funzione phpinfo() di PHP:

Windows Azure PHP runningIn cima alla pagina possiamo notare due link che permettono di effettuare il test delle operazioni sui blob e sulle table. Come dicevo all’inizio le pagine relative sono generate automaticamente e permettono di comprendere come effettuare delle operazioni sugli storage service. Non esiste un esempio riguardo le code, ma sulla documentazione del Windows Azure SDK for PHP è possibile trovare tutte le informazioni necessarie.

Dando un’occhiata al file BlobSample.php vediamo che innanzi tutto vengono inclusi i riferimenti alle librerie dell’SDK:

/**
 * Add PHP Azure SDK to the PHP include_path. This SDK is avilable in Application Root directory.
 * This can be done by adding following set_include_path statement in
 * every PHP file refering PHP Azure SDK.
 *
 * Alternatively user can update the include_path in PHP.ini file.
 */
set_include_path(get_include_path() . PATH_SEPARATOR . $_SERVER["RoleRoot"] . "\\approot\\");

/**
 * Refer PHP Azure SDK library files for Azure Storage Services Operations
 */
require_once 'Microsoft/WindowsAzure/Storage.php';
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';

All’interno del file Storage.php è definita la classe Microsoft_WindowsAzure_Storage, mentre in Blob.php è definita la classe Microsoft_WindowsAzure_Storage_Blob, che estende la prima.

Proseguendo con la lettura del file BlobSample.php, vediamo che viene creato lo storage client:

  $blobStorageClient = createBlobStorageClient();

  if(!isBlobServiceAccessible($blobStorageClient))
  {
    return;
  }

La funzione createBlobStorageClient() è definita più in basso come segue:

function createBlobStorageClient()
{
  if (azure_getconfig('UseDevelopmentStorage') == 'false')
  {
    $host = Microsoft_WindowsAzure_Storage::URL_CLOUD_BLOB;
    $accountName = azure_getconfig('StorageAccountName');
    $accountKey = azure_getconfig('StorageAccountKey');
    $usePathStyleUri = false;

    $retryPolicy = Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract::retryN(10, 250);

    $blobStorageClient = new Microsoft_WindowsAzure_Storage_Blob(
                                    $host,
                                    $accountName,
                                    $accountKey,
                                    $usePathStyleUri,
                                    $retryPolicy
                                    );
  }
  else
  {
    $blobStorageClient = new Microsoft_WindowsAzure_Storage_Blob();
  }
  return $blobStorageClient;
}

come possiamo vedere, nel caso in cui non venga utilizzato il development storage, vengono recuperate le credenziali e creato il client facendo riferimento a queste ultime. L’oggetto Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract permette di specificare il numero di tentativi e la distanza tra questi (vedi il file Microsoft/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php).  Come è possibile vedere in Storage.php, non specificando le credenziali, il client viene creato per il development storage.
Il passo successivo è quello di recuperare la lista di container usando il metodo listContainers dello storage client. La funzione listContainers($blobStorageClient), definita come segue, stampa i nomi dei container trovati.

function listContainers($blobStorageClient)
{
  echo "<strong>List of Containers:</strong>";
    $containers = $blobStorageClient->listContainers();
    foreach ($containers as $container)
    {
        echo "- $container->Name </br>";
    }
    echo "</br>";
}

Viene creato un nuovo container con un nome unico prefissato dalla string “testcontainer” (ad es. testcontainer4d641216454b0) utilizzando il metodo createContainer dello storage client.

  $containerName = uniqid("testcontainer");
  $result = $blobStorageClient->createContainer($containerName);
  echo "New container with name <strong>'" . $result->Name . "'</strong> is created.";

Dopo aver ristampato la lista dei container, per poter verificare che il container sia stato effettivamente creato, vengono creati due blob con nome differente dall’immagine WindowsAzure.jpg presente nella root del progetto usando il metodo putBlob:

$azureLogoFile = ".\\WindowsAzure.jpg";
$result = $blobStorageClient->putBlob($containerName, 'WindowsAzure.jpg', $azureLogoFile);
echo "New blob with name '<b>" . $result->Name . "'</b> is created. <br/><br/>";

Dopo aver stampato l’URL per il primo blob creato, viene stampata la lista di tutti i blob contenuti nel container usando la funzione listBlobs, costruita intorno al metodo listBlobs dello storage client:

function listBlobs($blobStorageClient, $containerName)
{
    echo "<b>List of blobs in container '" . $containerName . "': </b><br/>";
    $blobs = $blobStorageClient->listBlobs($containerName);
    foreach ($blobs as $blob)
    {
        echo " - $blob->Name " . "<br/>";
    }
    echo "<br/>";
}

A questo punto viene dimostrata la funzionalità di impostazione e lettura dei metadati sui blob con i metodi getBlobMetadata e setBlobMetadata. Vengono impostati i valori ‘createdby’ = ‘PHPAzure’ e ‘FileType’ = ‘jpg’.

/**
* Set metadata on blob "WindowsAzure.jpg" in $containerName container
*/
$blobStorageClient->setBlobMetadata($containerName, 'WindowsAzure.jpg',
array('createdby' => 'PHPAzure', 'FileType' => 'jpg'));
echo "Set metadata for '<b>WindowsAzure.jpg</b>' blob!<br/><br/>";
/**
* Read metadata on blob "WindowsAzure.jpg" in $containerName container
*/
$metaData = $blobStorageClient->getBlobMetadata($containerName, 'WindowsAzure.jpg');
echo "metadata for '<b>WindowsAzure.jpg</b>' blob:<br/>";
var_dump($metaData);
echo "<br/><br/>";

Il metodo getBlob dello storage client permette di effettuare il download del blob su un file temporaneo in locale:

$temp_file_name = tempnam(sys_get_temp_dir(), 'WindowsAzure');
$blobStorageClient->getBlob($containerName, 'WindowsAzure.jpg', $temp_file_name);
echo "Downloaded WindowsAzure.jpg blob to <b>" . $temp_file_name . "</b><br/><br/>";

Per dimostrare le funzionalità relativa all’impostazione del livello di accesso ai container viene impostato quello finora utilizzato come pubblico. Successivamente viene creato un nuovo container e impostato come privato. In esso viene creato un blob e generata una shared signature con validità di 5 minuti:

  /**
   * By default, blob storage containers on Windows Azure are protected from public viewing. If
   * any user on the Internet should have access to a blob container, its ACL can be set to public.
   * Note that this applies to a complete container and not to a single blob!
   */
  $blobStorageClient->setContainerAcl($containerName, Microsoft_WindowsAzure_Storage_Blob::ACL_PUBLIC);
  echo "Made container '$containerName' <b>public!</b> <br/><br/>";

  /**
   * Create shared signature for specified 'WindowsAzure.jpg' blob in private container
   */
  /**
   * First create a private container with uniq name and add 'WindowsAzure.jpg' blob file
   */
  $privateContainerName = uniqid("privatecontainer");
  $result = $blobStorageClient->createContainer($privateContainerName);
  $blobStorageClient->setContainerAcl($privateContainerName, Microsoft_WindowsAzure_Storage_Blob::ACL_PRIVATE);
  $result = $blobStorageClient->putBlob($privateContainerName, 'WindowsAzure.jpg', $azureLogoFile);

  $startTime = time();
  $endTime = $startTime + 5*60;  // Timestamp after 5 minutes

  $sharedSignatureURL = $blobStorageClient->generateSharedAccessUrl(
                $privateContainerName,
                "WindowsAzure.jpg",
            	'b',
            	'r',
            	isoDate($startTime),
            	isoDate($endTime)
          );

  echo "<b>SharedSignature for '$privateContainerName/WindowsAzure.jpg' with 5 minutes validity:</b><br/>" .
    '<a href="' . $sharedSignatureURL . '">' . $sharedSignatureURL . '</a><br/><br/>';

Infine viene cancellato il container pubblico col metodo deleteBlob e verificata l’effettiva cancellazione con il metodo containerExists:

  /**
   * Delete "WindowsAzure.jpg" blob from the $containerName container
   */
  $blobStorageClient->deleteBlob($containerName, 'WindowsAzure2.jpg');
  echo "Deleted blob <b>'WindowsAzure2.jpg'</b> from container <b>'$containerName'</b><br/><br/>";

  /**
   * Check if container exists
   */
  if ($blobStorageClient->containerExists($containerName))
  {
    echo "Container <b>'$containerName'</b> exists<br/><br/>";
  }
  if ($blobStorageClient->containerExists($privateContainerName))
  {
    echo "Container <b>'$privateContainerName'</b> exists<br/><br/>";
  }

Prima di concludere questo post vorrei indicarvi un utilizzo del table storage molto interessante per una applicazione PHP eseguita su Windows Azure. Quando l’applicazione è eseguita su almeno due istanze (a garanzia dello SLA), è necessario che lo stato delle sessioni sia condiviso tra le macchine virtuali. A tale scopo l’SDK per PHP mette a disposizione la classe Microsoft_WindowsAzure_SessionHandler  che permette di utilizzare il Table Storage di Windows Azure come session handler. Maggiori dettagli sono disponibili sulla documentazione del Windows Azure SDK for PHP.  Alla prossima!

Pubblicato in Programmazione, Windows Azure Tutorial | Contrassegnato , , , , , , , , | Lascia un commento

Hello Web Role! – Parte 2: Alla scoperta dello storage service

Nel post precedente abbiamo visto come realizzare la nostra prima soluzione cloud con un web role e come controllare il suo funzionamento utilizzando Windows Azure Diagnostics. In questo post vedremo come è possibile utilizzare lo storage service per memorizzare e pubblicare dati ed informazioni. I web role ed i worker role vengono eseguiti su istanze di macchine virtuali che mettono a disposizione uno spazio per la memorizzazione locale di file (local storage) volatile e quindi non utilizzabile per la memorizzazione persistente di file. Per la memorizzazione stabile di informazioni è possibile usare lo storage service o un database relazionale come SQL Azure.

Gli storage services di Windows Azure forniscono spazio di memorizzazione per dati testuali e binari, messaggi e dati strutturati.

I servizi offerti includono:

  • Il Blob service, per la memorizzazione di file
  • Il Queue service, per la memorizzazione di messaggi in una coda
  • Il Table service, per la memorizzazione di dati in forma strutturata non relazionale
  • I Windows Azure Drives, che permettono il mount di volumi NTFS da parte di una singola istanza

I servizi sono accessibili attraverso API REST che permettono l’accesso da una soluzione in esecuzione su Windows Azure o direttamente da qualunque applicazione in grado di inviare richieste e ricevere risposte HTTP/HTTPS su internet. L’accesso agli storage service avviene attraverso l’account. L’account è il livello più elevato nello spazio dei nomi per l’accesso ai servizi ed è alla base del processo di autenticazione. Nelle API REST l’account è esposto dai servizi come una risorsa.

Il blob service

Il Blob service fornisce lo storage per la memorizzazione di entità come file binari e di testo.Le API REST del blob service espongono due risorse: i container e i blob. Un container è un set di blob e ogni blob appartiene ad un container. Il blob service definisce due tipi di blob: i block blob, ottimizzati per lo streaming, ed i page blob. Questi ultimi sono ottimizzati per le operazioni di lettura e scrittura random, permettendo la scrittura di un range di byte in un blob. Sia ai container che ai blob è possibile associare metadati come coppie nome-valore definiti dall’utente.

Sebbene la struttura sia essenzialmente orizzontale, con i blob contenuti in un container, è possibile creare una struttura gerarchica simile ad un file system. I nomi dei blob possono contenere la codifica della gerarchia usando un separatore del percorso configurabile. Ad esempio i nomi di blob Gruppo/Blob1 e Gruppo/Blob2 implicano una organizzazione gerarchica virtuale. Ad agevolare questo genere di approccio, le API espongono dei metodi che permettono la navigazione delle gerarchie in modo simile a come siamo soliti fare sui file system consentendo, ad esempio, il recupero dei blob appartenenti ad un gruppo. Sull’MSDN è disponibile la reference delle API del blob service.

Il queue service

Il queue service fornisce un sistema affidabile per lo scambio di messaggi all’interno di un servizio e tra servizi differenti. Le API REST del queue service espongono due risorse: code e messaggi. Le code supportano la definizione di metadati come coppie nome-valore. Ogni account può contenere un numero illimitato di code di messaggi con nome univoco. Ogni coda può contenere un numero illimitato di messaggi con dimensione massima pari a 8 KB.

Quando un messaggio viene letto dalla coda, viene reso invisibile agli altri consumatori per un certo periodo di tempo. Se il messaggio non viene cancellato entro la scadenza dell’intervallo, viene ripristinata la sua visibilità in modo da permettere ad un altro consumatore di processarlo. Per approfondire l’argomento sulle code, la reference sulle API del queue service disponibile sull’MSDN è un ottimo inizio.

Il table service

Il table service fornisce uno storage strutturato sotto forma di tabelle che supporta le API REST ed è compatibile con le API REST di ADO.NET Data Services. All’interno dello storage account è possibile creare tabelle con nome univoco, all’interno delle quali vengono memorizzate informazioni come entità. Le entità sono collezioni di proprietà con i relativi valori, in modo similare ad una riga. Le tabelle sono partizionate al fine di supportare il load balancing tra i nodi e ogni tabella ha la prima proprietà utilizzata come chiave (partition key) per identificare la partizione a cui appartiene. La seconda proprietà identifica la riga (row key) che identifica un’identità all’interno della partizione. La combinazione tra la partition key e la row key forma la primary key che identifica l’entità in modo univoco all’interno della tabella. La tabella non impone nessuno schema, di conseguenza è lo sviluppatore a implementare e imporre lo schema lato client. Come per gli altri servizi, anche le API del table service sono ben descritte in una sezione dell’MSDN.

Al lavoro!

Adesso che abbiamo fatto amicizia con gli storage service, riprenderemo il progetto del post precedente e vedremo come è possibile effettuare l’upload di un file sul local storage e la sua successiva memorizzazione sullo storage service. Parallelamente, memorizzeremo un messaggio che notifica l’avvenuto upload.

Come prima cosa assicuriamoci della correttezza della configurazione del local storage sul web role:

Annotiamo il nome del local storage, utilizzato per l’acquisizione della risorsa. Apriamo la pagina default.aspx ed inseriamo un campo fileupload ed un pulsante. Per evitare confusione lasciamo i nomi predefiniti. Andiamo sull’handler del click e inseriamo il codice per l’upload sul local storage:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.WindowsAzure.ServiceRuntime;
using System.IO;

namespace WebRole1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            LocalResource LocalStorage =
                  RoleEnvironment.GetLocalResource("LocalStorage1");
            if (FileUpload1.FileContent.Length > 0){
                FileUpload1.SaveAs(
                      LocalStorage.RootPath + FileUpload1.FileName);
            }
        }
    }
}

Utilizzando il metodo RoleEnvironment.GetLocalResource(“LocalStorage1”) (vedi MSDN) otteniamo l’accesso all’oggetto LocalResource che contiene i dettagli sul local storage LocalStorage1: Name, MaximumSizeInMegabytes e RootPath. Quest’ultimo contiene il percorso fisico alla directory assegnata al local storage, che utilizzeremo per salvare il file.

Lanciamo il progetto ed effettuiamo l’upload di un file. Se apriamo il l’interfaccia utente del Compute Emulator possiamo verificare l’effettivo upload. Basta cliccare col tasto destro sull’istanza (se sono due potremmo dover ritentare con l’altra) e scegliere “Open local store”. I file del LocalStorage1 sono contenuti in \directory\LocalStorage1.

Prima di passare alla scrittura del codice relativo alle operazioni sullo storage service, è necessario impostare il settaggio relativo alla stringa di connessione all’account. Nel nostro caso useremo il development storage e aggiungeremo, immediatamente sotto la stringa di connessione impostata per la memorizzazione dei dati diagnostici, la voce “BlobConnectionString” di tipo connection string con valore “UseDevelopmentStorage=true”.
Per maggiori informazioni sulla configurazione delle stringhe di connessione, c’è una sezione ad hoc sull’MSDN.

Riprendiamo l’handler dell’evento click di Button1 e iniziamo a scrivere il codice che ci permetterà di copiare il file su un blob. Per prima cosa è necessario creare un oggetto CloudStorageAccount inizializzato utilizzando la stringa di connessione che abbiamo inserito in precedenza. Per recuperarne il valore utilizziamo la classe RoleEnvironment che permette l’accesso all’ambiente di esecuzione del role e che abbiamo già utilizzato per avere accesso al local storage (vedi MSDN).
Adesso, disponendo dell’oggetto CloudStorageAccount e quindi l’indirizzo dell’endpoint Blob e delle credenziali, possiamo inizializzare il CloudBlobClient, l’oggetto che rappresenta il client di accesso al blob service:

CloudStorageAccount Storage = CloudStorageAccount.Parse(
RoleEnvironment.GetConfigurationSettingValue("BlobConnectionString"));
CloudBlobClient Client =
     new CloudBlobClient(Storage.BlobEndpoint, Storage.Credentials);

A questo punto possiamo passare alla definizione del container utilizzando il metodo GetContainerReference. E’ bene ricordare che il nome dei container deve eseguire le regole  per qualunque nome DNS valido:

  1. Il nome deve iniziare per lettera o numero e contenere solo lettere, numeri ed il carattere – (trattino).
  2. Il carattere – deve tassativamente essere preceduto e seguito da una lettera o da un numero.
  3. Tutte le lettere del nome devono essere minuscole.
  4. Il nome deve avere una lunghezza compresa tra 3 e 63 caratteri.

Il metodo SetPermissions permette di impostare il livello di accesso al container. Nel nostro caso il container non ha restrizioni d’accesso. Come di consueto, l’MSDN potrà fornirvi maggiori informazioni in proposito. L’ultima operazione da fare sul container è chiamare il metodo CreateIfNotExist, dal nome più che autodescrittivo.

CloudBlobContainer Container = Client.GetContainerReference("uploads");
Container.SetPermissions(new BlobContainerPermissions
 { PublicAccess = BlobContainerPublicAccessType.Container });
Container.CreateIfNotExist();

In modo analogo a come fatto in precedenza per il container, creiamo il riferimento al blob usando il metodo GetBlobReference del container. Come detto in precedenza, ai blob è possibile associare dei metadati sotto forma di coppie nome-valore. In questo caso creeremo il metadato “MIME” contenente il content type del file. Il metodo UploadFile del container ci permette di uploadare il contenuto, creando il blob o sovrascrivendo l’eventuale blob omonimo.

   CloudBlob Blob = Container.GetBlobReference(FileUpload1.FileName);
   Blob.Metadata["MIME"] = FileUpload1.PostedFile.ContentType;
   Blob.UploadFile(LocalStorage.RootPath + FileUpload1.FileName);

A questo punto, con un processo assolutamente analogo, definiamo una coda chiamata “filequeue”. E accodiamo un messaggio contenente il nome del file appena uploadato sul cloud storage. Maggiori informazioni sullla gestione delle code è disponibile in questa pagina dell’MSDN.

   CloudQueueClient QueueClient = Storage.CreateCloudQueueClient();
   CloudQueue Queue = QueueClient.GetQueueReference("filequeue");
   Queue.CreateIfNotExist();
   CloudQueueMessage Message = new CloudQueueMessage(FileUpload1.FileName);
   Queue.AddMessage(Message);

A questo punto non resta che lanciare il progetto e uploadare un file. Giocando con i breakpoint,  il Compute Emulator ed il Server Explorer è possibile vedere il file apparire prima sul local storage e poi sul blob service.

Alla prossima!

Pubblicato in Programmazione, Windows Azure Tutorial | Contrassegnato , , , , , , , , , | Lascia un commento

Hello Web Role! – Sviluppare la prima soluzione per Windows Azure.

Nel post precedente abbiamo visto quali sono i tool necessari per poter iniziare a sviluppare una soluzione per Windows Azure, quali sono gli elementi che la compongono e le funzionalità che i role possono utilizzare. In questo post realizzeremo una semplice soluzione utilizzante un web role e vedremo inseme quali sono le configurazioni ed i meccanismi in gioco.

Iniziamo con il lanciare Visual Studio e cliccare sul link nuovo progetto della pagina iniziale:


Selezionando le template Cloud viene proposto il modello del progetto Windows Azure. Specificando il nome e premendo OK, viene mostrata una finestra che permette di scegliere quali role utilizzare all’interno della soluzione:

La scelta possibile è tra:

  • Web Role ASP.NET
  • Web Role ASP.NET MVC2
  • Web Role Servizio WCF
  • Web Role CGI
  • Worker Role

I primi due permettono di pubblicare un servizio con front end web (nel secondo caso sviluppata usando MVC 2). Il Web Role Servizio WCF, come intuibile dal nome, permette di creare un Web Role preconfigurato per la pubblicazione di un servizio WCF. Il Web Role CGI permette di inserire un progetto per una web application FastCGI che utilizza codice nativo all’interno del Cloud Service. Il Worker Role, come visto nel post precedente, permette di creare un componente eseguito all’esterno del contesto IIS come, ad esempio, un processo per l’esecuzione di task in background. Nel nostro caso ci limiteremo ad inserire solo un web role. Premendo OK il progetto viene creato:

Osservando la soluzione è possibile notare che è composta da due progetti: il WindowsAzureProject1, con lo stesso nome della soluzione, contenente i file di configurazione del servizio e una cartella contenente i role e il progetto web WebRole1,  avente la stessa struttura di una comune web application eccettuata la presenza del file WebRole.cs.

Apriamo questo file:

vediamo che si tratta di una classe derivata dalla classe RoleEntryPoint. Questa classe, utilizzata da Windows Azure per comunicare con le istanze, possiede tre metodi di sicuro interesse:

  • public virtual bool OnStart()
  • public virtual void OnStop()
  • public virtual void Run()

Durante l’esecuzione del metodo OnStart l’istanza viene posta allo stato Busy ed è indisponibile alle richieste ricevute dal load balancer. Questo metodo è utile per effettuare tutte le inizializzazioni necessarie prima dell’avvio del servizio.
Se il metodo OnStart ritorna falso l’istanza viene immediatamente arrestata, in caso contrario viene avviata chiamando il metodo Run. Questo consiste essenzialmente in un thread in esecuzione continua. Nell’implementazione di default il thread va in sleep per un tempo infinito, bloccando il ritorno del metodo.
Il metodo OnStop, chiamato da Windows Azure allo shutdown dell’istanza, viene utilizzato per implementare il codice necessario per gestire l’arresto regolare. Il metodo OnStop deve ritornare entro un certo tempo, in caso contrario Windows Azure interromperà forzatamente l’esecuzione dell’istanza del role.

Come detto in precedenza nel progetto del cloud service è presente una cartella contenente i riferimenti ai role e i due XML file di configurazione ServiceConfiguration.cscfg e ServiceDefinition.csdef. Questi file contengono tutte le impostazioni del servizio e dei role in esso contenuti. Sebbene molte impostazioni siano configurabili solo attraverso la loro modifica  (vedi MSDN), quelle principali possono essere effettuate usando l’interfaccia grafica. Basta fare click con il tasto destro su uno dei role e selezionare Proprietà.


I permessi disponibili per un role dipendono dal livello di trust con cui il role è stato pubblicato. Sono disponibili due livelli di trust: partial trust e full trust. L’impostazione di default prevede l’esecuzione in full trust. Maggiori informazioni sul livello di trust sono disponibili sugli articoli dell’MSDN Hosting Web and Worker Roles Under Full Trust e Windows Azure Partial Trust Policy Reference.

Nella sezione Instances è possibile impostare il numero di istanze utilizzate dal role e la tipologia di virtual machine su cui devono essere eseguite. Al fine di rientrare nello SLA di Windows Azure, che prevede una disponibilità del compute service del 99.95%, è necessario attivare almeno due istanze per role.
Le dimensioni disponibili per le macchine virtuali sono:

Virtual Machine CPU Cores RAM Local Storage
ExtraSmall Shared 768 MB 20 GB
Small 1 1.75 GB 225 GB
Large 4 7 GB 1000 GB
ExtraLarge 8 14 GB 2040 GB

Per controllare il funzionamento dei role eseguiti in full trust (e valutare l’opportunità di scalare in alto o in basso) è possibile utilizzare Windows Azure Diagnostics che permette di campionare informazioni dai performance counters e memorizzarle sul cloud storage.
La voce di configurazione Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString contiene la stringa di connessione al cloud storage utilizzato a questo scopo o la stringa “UseDevelopmentStorage=true”, indicante l’utilizzo del Development Storage del kit di sviluppo.
Per configurare la raccolta dei dati andiamo sul metodo OnStart() della classe vista in precedenza e inseriamo il codice seguente:

In seguito all’avvio del progetto avremo modo di vedere che ci permetterà di monitorare il livello di occupazione di CPU per le istanze del web role campionando i valori ogni 10 secondi e memorizzando i valori sulla tabella WADPerformanceCountersTable del Development Storage ogni minuto. Maggiori dettagli sull’utilizzo di Windows Azure Diagnostics è disponibile sull’MSDN.

Come visto in precedenza, ogni istanza del web role può utilizzare uno spazio di storage locale la cui dimensione varia a secondo del tipo di virtual machine selezionata. Questo spazio può essere configurato, definendo delle risorse cui viene attribuito un nome e una dimensione, attraverso le impostazioni relative.

E’ bene ricordare che il local storage è da considerarsi volatile anche se non viene impostato per la cancellazione in caso di riciclo del role e pertanto va utilizzato solo per la memorizzazione di file temporanei.

E’ giunto il momento di avviare il nostro primo progetto ma, prima di lanciare il debug, vi consiglio di cliccare col tasto destro sul logo di Windows Azure sull’area di notifica (il Windows Azure Simulation Monitor) e selezionare Show Compute Emulator UI. In questo modo avrete modo di vedere l’effetto del deployment e, cliccando sulle singole istanze del web role, il susseguirsi degli eventi che portano all’avvio.

Ad avvio completato, viene lanciato il browser e caricata la pagina Default.aspx del web role. Il primo passo verso le nuvole è fatto, adesso non vi resta che dare un’occhiata ai dati diagnostici sul Development Storage utilizzando il Server Explorer di Visual Studio. Alla prossima!

Pubblicato in Programmazione, Windows Azure Tutorial | Contrassegnato , , , , , , , , | Lascia un commento

Anatomia e sviluppo di una soluzione cloud per Windows Azure

In questo post, che immagino come l’inizio di una serie con lo scopo di aiutare a muovere i primi passi nell’utilizzo di Windows Azure e SQL Azure, vedremo in dettaglio come è fatto un cloud service e cosa è necessario per iniziare a sviluppare. Nei prossimi post approfondiremo la conoscenza delle varie caratteristiche della piattaforma Azure e realizzeremo dei piccoli  progetti che ne illustrano l’utilizzo.

Anatomia di un cloud service di Windows Azure

Un’applicazione progettata per essere eseguita su Windows Azure è composta da un insieme di componenti scalabili (roles) e dai file di configurazione XML che configurano e definiscono il servizio.
Attualmente Windows Azure supporta tre tipologie di roles:

  • Web Role
    Un web role è un role eseguito all’interno di IIS che permette la programmazione di web applications,  dei front-end web based e di servizi SOAP/WCF in modo semplice e immediato. La sua struttura deriva direttamente da quella di una normale web application .NET.
  • Worker Role
    E’ il role utile per la gestione di processi in background, asincroni, con lunghi tempi di esecuzione o con esecuzione intermittente. Può essere anche utilizzato per realizzare servizi applicativi che non richiedono una user interface. I worker role possono essere in ascolto su una coda o ospitare un servizio TCP. A differenza dei web role, i worker role non sono eseguiti nel contesto di IIS ma sono degli eseguibili autonomi.
  • VM Role
    Il VM Role è un tipo speciale di role. Non è un’applicazione da eseguire su una macchina virtuale, ma la macchina virtuale stessa. Permette la massima libertà nel controllo del suo funzionamento ed è una buona soluzione per l’esecuzione su Windows Azure di applicazioni legacy: basta creare un disco immagine VHD di un sistema Windows Server 2008 R2 per il deployment.

Le tre tipologie di role possono essere combinate liberamente all’interno di un cloud service. Ogni istanza dei role (in genere ce ne sono almeno due, per garantire lo SLA) viene eseguita utilizzando una macchina virtuale con potenza di calcolo e spazio di storage locale configurabile tra Extra Small, Small, Medium, Large ed Extra Large. Lo storage locale, utilizzabile per il processamento di file temporanei, è volatile. Per la memorizzazione di dati e files si utilizzano gli storage services o database SQL Azure.
Gli storage services di Windows Azure, che forniscono le funzionalità per la  memorizzazione di dati binari, testi e dati strutturati comprendono:

  • Blob service (dati binari e testi)
  • Queue service (code di messaggi)
  • Table service (storage strutturato non relazionale)
  • Windows Azure drives (volumi NTFS)

SQL Azure Database è la piattaforma database relazionale cloud-based basata sulla tecnologia SQL Server. Usando SQL Azure è possibile utilizzare database relazionali sul cloud con le caratteristiche di alta disponibilità, scalabilità e sicurezza offerte da un data center distribuito.

I role possono inoltre utilizzare le funzionalità esposte dalla Windows Azure AppFabric:

  • AppFabric Service Bus
    Un servizio che esegue il relay bidirezionale sicuro di messaggi tra qualsiasi web service, indipendentemente dalla tipologia di dispositivo, computer o server che lo ospita e dal fatto che si trovi dietro un firewall o che venga utilizzato un NAT.
  • AppFabric Access Control
    E’ un servizio interoperabile che fornisce soluzioni di autenticazione ed autorizzazione federata claim-based per qualunque risorsa, indipendentemente dalla tipologia di dispositivo, computer o server che lo ospita.

Nei prossimi post, dopo aver mosso i primi passi, avremo modo di vedere il funzionamento degli storage service, di SQL Azure e delle funzionalità dell’App Fabric con degli esempi concreti.

I tool di sviluppo

Per iniziare a sviluppare per Windows Azure non è necessario disporre di un account sulla piattaforma di Microsoft. E’ possibile realizzare un progetto e lanciarlo in un ambiente simulato di sviluppo (Development Fabric) che consente la messa a punto della soluzione senza dover incorrere in costi aggiuntivi.
I principali ambienti di sviluppo per Windows Azure, a secondo se si vuole sviluppare utilizzando il framework .NET, Java o PHP, sono Visual Studio ed Eclipse.

Requisiti per lo sviluppo sul framework .NET

Requisiti per lo sviluppo in Java e PHP:

Adesso che abbiamo predisposto la macchina di sviluppo, nel prossimo post realizzeremo il primo progetto.

Pubblicato in Programmazione, Windows Azure Tutorial | Contrassegnato , , , , , , , , , , , , | Lascia un commento

La definizione del NIST e le offerte di cloud computing

Il NIST, l’istituto statunitense degli standard e della tecnologia derivato dal vecchio National Bureau of Standards, ha dato una definizione formale al cloud computing:

“Il cloud computing è un modello abilitante un accesso comodo ed on-demand ad un pool condiviso di risorse di calcolo configurabili che possono essere velocemente ottenute e rilasciate con minimo sforzo di gestione ed una limitata interazione con il fornitore di servizi.”

A questa definizione iniziale sono associate cinque caratteristiche essenziali:

  • Self service ed on-demand
    L’utilizzatore del servizio può richiedere ed utilizzare le risorse di calcolo e di storage secondo le sue necessità, senza richiedere nessuna interazione umana con il fornitore di servizi.
  • Accesso di rete aderente agli standard
    Le capacità fornite dal servizio sono disponibili sulla rete e disponibili attraverso meccanismi standard che permettono l’utilizzo ad applicazioni eseguite su piattaforme eterogenee.
  • Resource pooling
    Le risorse del fornitore di servizio sono raggruppate allo scopo di servire gli utilizzatori attraverso un modello di erogazione multi-tenant. Le risorse fisiche e virtuali sono assegnate dinamicamente secondo le esigenze degli utilizzatori. Questi ultimi non hanno visibilità dell’effettiva posizione fisica delle risorse utilizzate se non con un livello di astrazione molto elevato (nazione, stato o al massimo datacenter).
  • Elasticità
    Le risorse possono essere fornite in modo elastico, veloce e, a volte, automatico permettendo una veloce scalabilità verso l’alto e verso il basso. L’utilizzatore, potendo acquistare l’uso di risorse in qualsiasi quantità ed in qualunque momento, ha la percezione di una disponibilità potenzialmente infinita.
  • Costo commisurato all’effettivo utilizzo
    I sistemi cloud controllano ed ottimizzano automaticamente l’uso delle risorse facendo leva sulla capacità di misura dell’uso delle tipologie di servizio (es. storage, computing time, banda). L’utilizzo delle risorse può essere monitorato e controllato in modo trasparente per il fornitore di servizio e l’utilizzatore.

La definizione del NIST contiene anche una descrizione dei possibili modelli di servizio (SaaS, PaaS e IaaS) e dei modelli di deployment (private cloud, community cloud, public cloud ed hybrid cloud).

In questo post vorrei focalizzare l’attenzione sulla definizione dei cloud computing e delle caratteristiche che il NIST ritene, giustamente, essenziali. In questo momento esistono sul mercato delle offerte che, sebbene siano proposte come cloud computing in realtà sono solo delle applicazioni molto avanzate di virtualizzazione.

Sono tre le caratteristiche essenziali a dettare la differenza maggiore tra una offerta di cloud computing reale e quelle di virtualizzazione avanzata, sia dal punto di vista tecnologico che da quello strategico:

  • La possibilità di riconfigurare le risorse in modo semplice e veloce, senza richiedere interventi umani dal lato del fornitore di servizi.
  • La possibilità di modificare le caratteristiche del servizio e di scalare verso l’alto e verso il basso in modo elastico (dove per elastico intendo anche la possibilità di una variazione anche continua, di ora in ora).
  • La possibilità di pagare sulla base dell’effettivo utilizzo delle risorse.

Se queste caratteristiche sono assenti, l’offerta impone dei vincoli temporali (es. costi del servizio su base mensile) e le operazioni di attivazione, upgrade o downgrade del servizio, a causa della necessità di un intervento umano, non sono immediate. Il risultato è che l’infrastruttura di erogazione non può più seguire le necessità dell’utilizzatore esponendolo potenzialmente a costi operativi superiori rispetto ad una offerta di cloud computing reale.

C’è da dire che implementare queste caratteristiche su un servizio a grande scala è particolarmente complesso e richiede del tempo. Probabilmente alcune offerte di virtualizzazione avanzata pian piano si allineeranno alle caratteristiche di un reale servizio di cloud computing ma, nel frattempo, è bene stare attenti a cosa si acquista. Il termine cloud computing è di gran moda ed il marketing delle aziende non può non cedere alla tentazione di offrire come tale qualcosa di solo vagamente simile.

Pubblicato in Cloud computing | Contrassegnato , , , , | 2 commenti

Un mese con Windows Phone 7

In occasione dello SMAU 2010 ho avuto modo di vedere in anteprima il primo telefono Windows Phone 7 lanciato sul mercato italiano: l’LG Optimus 7.

LG Optimus 7

Una settimana dopo ne avevamo preso uno per effettuare i test dell’applicazione per WebSignage su cui stavamo lavorando, prima della pubblicazione sul marketplace :-).

Ho utilizzato molti dispositivi mobili con il sistema operativo Microsoft, sin dal Pocket PC 2000. Nel tempo il sistema operativo ed i dispositivi sono evoluti diventando più potenti, più pratici e affidabili, ma l’approccio è sempre stato un po’ “figlio del desktop”. Un adattamento di Windows (aggiungerei CE) ad uno scenario d’uso ed una categoria di utenti differente.

Quello che colpisce subito di Windows Phone 7 è l’interfaccia utente radicalmente diversa dai suoi predecessori. Il concetto di finestra è sparito e le applicazioni sembrano muoversi  in un ambiente vagamente tridimensionale, con sfondi e testi che escono fuori dallo spazio visibile sul display. L’interfaccia, molto reattiva, è arricchita da animazioni eleganti ma discrete. Tutto è molto intuitivo e immediato. Le configurazioni, come ad esempio quelle delle caselle di posta, per la prima volta hanno perso tutto il tecnicismo diventando semplicissime e alla portata di tutti. La varietà delle applicazioni disponibili, in particolare quelle gratuite, è ancora limitata ma decine di nuove applicazioni sono pubblicate ogni giorno.

Ho utilizzato il telefono in modo molto intensivo per più di un mese e, a parte l’autonomia della batteria (colpa mia) e la sensibilità del GPS un po limitata (probabilmente colpa di LG), non ho avuto problemi particolari. Windows Phone 7 ha dimostrato di essere un sistema operativo affidabile, nonostante la sua giovinezza. Manca il supporto per il copia e incolla, il tethering e il trasferimento di file tramite Bluetooth ma confido nel prossimo aggiornamento annunciato per l’inizio del 2011.

Cosa mi è piaciuto

  • L’ergonomicità della nuova interfaccia utente.
  • La fortissima integrazione con i social network e Facebook in particolare.
  • La gestione unificata dei calendari dei vari account. Era una cosa che desideravo!
  • I comandi vocali, molto ben progettati, non sbagliano un colpo neanche in presenza di rumori di fondo. Sono utilissimi quando si usa l’auricolare.
  • Internet Explorer 7.5 è un buon browser che garantisce una buona esperienza di navigazione anche su siti complessi e non progettati per essere visualizzati su un dispositivo mobile.

Cosa non mi è piaciuto

  • Sebbene sia molto “social” e permetta di condividere facilmente testi e fotografie, la condivisione dei video è praticamente impossibile se non tirando fuori il file con Zune.
  • Se il marketplace si blocca e chiude non è più possibile avviare ne lui ne l’hub Musica e video. Si deve riavviare il telefono. Un difetto di gioventù che si evidenzia solo se la connessione UMTS è davvero scadente e cade al momento sbagliato. Solo per gli sfortunati!
    EDIT: dopo qualche mese e un bel po di applicazioni in più sul marketplace la situazione è decisamente peggiorata. E’ difficile usare il marketplace un po’ più a lungo senza arrivare al blocco. Oggi (10 marzo 2011) ho effettuato l’aggiornamento del sistema operativo di Febbraio senza problemi. Speriamo che il vero aggiornamento, previsto per la seconda metà del mese, risolva il difetto…
  • L’assenza di Flash. Più che altro perchè a volte diventa un po’ complicato vedere pagine con video YouTube embedded.
  • La dipendenza da Zune per il trasferimento di musica e video, un po’ come per  l’iPhone che dipende da iTunes. Sarebbe bello vedere il telefono come disco USB.
  • L’impossibilità a trasferire file col Bluetooth.
  • L’assenza del copia e incolla.
Pubblicato in Information Technology | Contrassegnato , , , | Lascia un commento

Real World SQL Azure: il case study di Microsoft Corporate su Web Signage

Dopo una lunga intervista telefonica ed una rapida revisione che ha coinvolto il team di prodotto SQL Azure, lo scorso 22 novembre è stato pubblicato da Microsoft il case study sull’esperienza di Edisonweb con Windows Azure e SQL Azure.

Partendo dall’erogazione del servizio Web Signage, in questo documento vengono evidenziati i vantaggi tecnologici, strategici ed economici derivanti dall’adozione delle tecnologie di cloud computing. In particolar modo si evidenziano due aspetti che potrebbero essere di sicuro interesse per chi vuole avvicinarsi al cloud: i vantaggi economici derivanti dalla smaterializzazione dell’infrastruttura IT e dal modello pay-per-use e i vantaggi strategici che facilitano l’espansione sui mercati internazionali.

Il passaggio da una struttura on premises ad una cloud based permette di abbattere radicalmente i costi di gestione e di mantenimento dell’infrastruttura necessaria all’erogazione dei servizi. In particolare, oltre ai costi relativi all’acquisto di hardware e di licenze, vengono rimossi tutti quegli oneri ricorrenti legati all’utilizzo dei datacenter (power, cooling, supervisione sistemistica, affitto rack space ecc..) a tutto vantaggio della competitività sul mercato.

Per l’erogazione efficiente di servizi su scala mondiale, è necessaria l’identificazione di datacenter in diversi Stati e la creazione di accordi con le Telco locali. Il risultato è una infrastruttura distribuita, difficile da gestire e poco unitaria. Windows Azure permette di definire l’affinità dei servizi ad una regione geografica e, attraverso la Content Delivery Network, consente la distribuzione di contenuti su scala mondiale in modo semplice e performante. In un periodo in cui l’espansione sui mercati internazionali è sempre più importante (se non vitale), il supporto tecnologico fornito dai servizi Microsoft è una autentica manna dal cielo.

Sul sito Microsoft Case Studies è possibile leggere l’abstract o scaricare l’intero documento del case study in formato Word, mentre sul blog MSDN SQL Azure Team Blog è disponibile un estratto dell’intervista.

Buona lettura!

Pubblicato in Cloud computing | Contrassegnato , , , , , , , , , | Lascia un commento

Windows Azure: Web Signage tra i case study italiani allo SMAU 2010

Durante lo SMAU 2010, Microsoft ha organizzato la sua presenza in grande stile organizzando degli eventi tematici trasmessi in streaming su Internet. Lo studio televisivo, realizzato con pareti trasparenti e con monitor esterni, permette ai visitatori della fiera di assistere alle discussioni durante le riprese. Tra i quattro eventi previsti, nella mattina di venerdì 22 ottobre, si è tenuto quello su Windows Azure presentato da Riccardo Sponza e Mario Fontana. L’agenda dell’evento ha previsto una serie di interessanti interventi di che hanno spaziato da argomenti tecnici e hands-on-labs a considerazioni commerciali e strategiche sulle opportunità di business derivanti dall’adozione di una piattaforma cloud.

I benefici e le opportunità che scaturiscono dall’adozione di Windows Azure sono stati testimoniati dalla presentazione di quattro case study tutti italiani: Web Signage di Edisonweb, CV Manager di SoftJam, aKite di Bedin Shop Systems e Amanuens di Threeplicate. Le applicazioni presentate sono state create per segmenti di mercato molto differenti, sono state migrate sul cloud o progettate sin dall’inizio per essere utilizzate su Windows Azure e utilizzano le tecnologie disponibili in modo differente. Nel loro insieme rappresentano quattro prospettive tanto diverse quanto interessanti sui vantaggi e le opportunità nate dall’uso dei cloud services di Microsoft.

Come CTO di Edisonweb sono stato invitato a condividere la nostra esperienza con Windows Azure e SQL Azure nell’erogazione del servizio Web Signage per la gestione di reti di digital signage e della comunicazione di prossimità in generale. Il mercato del digital signage è abbastanza giovane, soprattutto in Italia, le reti sono tipicamente in espansione, continua e veloce, e puntano a coprire le aree con maggiore frequentazione. Tra queste anche le località turistiche montane e balneari, con attività stagionale. Web Signage è offerto come servizio ed il modello di pricing prevede un canone mensile per ogni computer che esegue i contenuti (player). Il numero di player attivi può essere variato liberamente nel corso dell’anno e le spese relative ai canoni possono seguire l’andamento del business. Per erogare in modo ottimale i propri servizi, a fronte di un investimento iniziale significativo, Edisonweb si è dotata di una infrastruttura tecnologica in datacenter. Inoltre, l’infrastruttura richiede una supervisione e manutenzione continua, generando costi ricorrenti e utilizzando risorse umane altrimenti disponibili per il core business: lo sviluppo di software.

L’adozione di Windows Azure ha comportato molteplici vantaggi:

  • I costi infrastrutturali, privi di una componente iniziale di investimento, sono commisurati all’utilizzo effettivo e, di conseguenza, seguono in modo preciso le fluttuazioni generate dal modello flessibile di licensing.
  • I costi di Windows Azure e di SQL Azure sono molto più bassi rispetto a quelli ricorrenti dell’infrastruttura on premises.
  • L’erogazione del servizio sui mercati internazionali non richiede accordi con le TELCO locali o l’identificazione di datacenter adeguati. Utilizzando l’affinità dei servizi ed i nodi della Content Delivery Network è possibile distribuire il servizio in modo ottimale, indipendentemente dalla distribuzione geografica dei player.

Riassumendo, l’adozione dei servizi della piattaforma Windows Azure permette una più facile aggressione dei mercati internazionali, una maggiore competitività e una migliore produttività.

Per chi fosse interessato a riascoltare il mio intervento, è disponibile la registrazione su You Tube:

Chi parteciperà al TechDaysWPC 2010 potrà avere il modo di approfondire l’argomento con me di persona: sono stato invitato da Mario Fontana a presentare in modo un po più articolato Web Signage durante lo speech “Architecting Windows Azure Solutions:Italian Scenarios”, martedì 23 Novembre, sala Blu.

Pubblicato in Cloud computing | Contrassegnato , , , , | 2 commenti

Scrum: tempi e costi

Adottando la metodologia di sviluppo SCRUM gli obiettivi di progetto vengono raccolti nel Product Backlog, continuamente aggiornato e alimentato da tutti gli stakeholder. L’obiettivo generale del progetto è definito ma i dettagli possono cambiare al mutare delle condizioni di mercato e delle strategie del cliente per ottenere il massimo del valore.
Si pongono quindi due problemi:

  • come definire e rispettare una data di rilascio condivisa con il cliente?
  • come definire una strategia di controllo dei costi a fronte della variabilità delle specifiche?

Un primo passo è quello di definire un piano iniziale con una data di rilascio condivisa. Questo piano verrà aggiornato con il susseguirsi degli Sprint, ma permette di definire una scadenza sulla base dei requisiti iniziali. Questi vengono raccolti e, se necessario, discussi con il cliente al fine di comprendere al meglio i benefici di business correlati alle richieste ricevute.

I requisiti (User Story) vengono inseriti, ordinati per priorità, nel Product Backlog e sottoposti ad un processo di stima. La stima non viene effettuata sulla base di una valutazione del tempo e delle modalità di implementazione, ma per confronti successivi rispetto ad un requisito di riferimento. In questa fase, infatti, non è stata ancora effettuata un’analisi.
Tra le User story nel Product Backlog ne viene selezionata una minore, ma non la più piccola, e viene attribuito un valore Story Point di tre. Questo valore è un numero puro, senza nessun riferimento al numero di ore di lavoro necessarie. Fissato questo punto di riferimento, il team attribuisce il valore degli Story Point alle altre attività. In questo modo un’attività con una complessità doppia rispetto a quella di riferimento avrà un valore pari a 6 o una, davvero molto complessa, un valore pari a 100.
La valutazione del numero di Story Point non sempre è immediata e pertanto esistono varie metodologie per agevolare la stima. Una tra queste è il cosiddetto Planning Poker.

Completata la stima degli Story Points è necessario valutare la “capacità produttiva” del team di sviluppo. E’ necessario misurare la cosiddetta Velocity, ovvero il numero di Story point che il team può completare in un singolo Sprint. E’ chiaro che, conoscendo questo valore, è possibile conoscere il tempo necessario per realizzare tutte le User Story nel Product Backlog: Tempo di completamento = Totale Story Point/Velocity * Durata Sprint. Non si tratta di una stima ma di una misura.
Studi dimostrano che per avere una misura del valore di Velocity di un team è tipicamente necessaria l’esecuzione di tre Sprint. Il valore di Velocity è costante se vengono mantenute invariate le tecnologie, l’ambiente di lavoro e la composizione del team. E’ quindi possibile che si disponga già di questo valore. In caso contrario, per un progetto di sufficienti dimensioni, potrebbe essere addirittura conveniente realizzare tre Sprint da una settimana per avere una misura di questo valore.

A questo punto abbiamo una indicazione del tempo di realizzazione, condivisibile con il cliente. Ma i cambiamenti in corsa avranno un impatto sul tempo di completamento del progetto? Le variazioni ai requisiti iniziali come incideranno sui costi? A queste domande risponde il contratto sottoscritto con il cliente. Esistono, infatti delle tipologie di contratto che permettono una gestione chiara dei costi, anche in contesti caratterizzati da variabilità come quelli in cui vengono applicate metodologie agili di sviluppo. A titolo di esempio ne citerò alcuni:

Per tempo e materiali
E’ un classico. Il cliente paga per il tempo di sviluppo richiesto e, di conseguenza si assume anche il rischio di eventuali scelte errate che aumentano la durata del lavoro. L’ambito del progetto non è definito a priori e il progetto viene chiuso appena il cliente raggiunge i suoi obiettivi o decide di non voler spendere di più.

Per tempo e materiali con tetto di spesa
E’ simile al precedente, ma un tetto di spesa limita il rischio finanziario per il cliente. Ovviamente, essendoci un limite di budget, è fondamentale che ci sia una collaborazione tra fornitore e cliente affinché quest’ultimo ottenga il massimo del valore per il suo business rispettando il limite di budget.

Profitto fisso
Permette di condividere il rischio: se il progetto viene chiuso in anticipo il cliente paga di meno ed il fornitore ottiene il profitto per quel periodo, se il progetto supera la data di consegna prevista o se viene superato il budget massimo concordato, il fornitore lavora a prezzo di costo.

“Money for Nothing, Changes for Free”
Il modello di base è per tempo e materiali, con una data di rilascio prevista. Durante il processo di sviluppo, vengono realizzate le funzionalità in ordine di valore per il cliente. Ad un certo punto quest’ultimo può valutare sufficiente il valore ottenuto e decidere di non proseguire con lo sviluppo. In questo caso il cliente deve versare una fee di cancellazione pari al profitto mancante per il fornitore (money for nothing). Le funzionalità non implementate possono essere sostituite con altre con un numero di story point uguale (changes for free). Le funzionalità aggiuntive comportano costi aggiuntivi.

Pubblicato in Agile, Project management | Contrassegnato , , , , , | 2 commenti

Sviluppo agile con Scrum

Che caos!
Rileggendo il mio post precedente sul confronto tra l’approccio a cascata e le metodologie di sviluppo agile, mi è sembrato che possa dare una percezione caotica di queste ultime. In realtà, e lo dico per esperienza personale, ci vuole un po’ per comprendere e abbracciare una filosofia che vede il cambiamento non solo come positivo, ma addirittura come fulcro per la creazione di valore. Dopotutto, storicamente, i cambiamenti alle specifiche di un progetto, se possibile, sono stati sempre evitati. Non è vero?

Gestire il cambiamento
E’ possibile imbrigliare il cambiamento in una serie di processi concettualmente semplici e, utilizzando un approccio ciclico, produrre valore ed informazioni utili al continuo miglioramento dei processi stessi. La parola magica per ottenere tutto questo è Scrum, un modello iterativo ed incrementale per lo sviluppo di progetti, prodotti o applicazioni.
Le richieste provenienti dai clienti, dagli utilizzatori, dal team di sviluppo e, in generale, da tutti gli stakeholder, vengono raccolte e viene redatta una lista ordinata per priorità di caratteristiche per il prodotto (Product Backlog).

La produzione è strutturata in cicli di sviluppo chiamati Sprint di durata costante (tipicamente tra una e quattro settimane) che si susseguono senza soluzione di continuità. Il prodotto dello Sprint è una porzione completa del prodotto finale, una porzione potenzialmente rilasciabile.
All’inizio di ogni Sprint (attraverso lo Sprint Planning Meeting) il team seleziona i task dal Product Backlog e si impegna a completarli all’interno del tempo concesso. Non è possibile allungare lo Sprint per permettere il completamento di un task e a Sprint avviato i task non possono essere più modificati. Se i task dovessero essere completati in anticipo (mostrando un errore di pianificazione), se ne possono selezionare degli altri per occupare il tempo altrimenti inutilizzato.
Durante lo Sprint, ogni mattina il team si incontra (Daily Scrum Meeting) per verificare come procedono i lavori e se ci sono impedimenti. Si tratta di un incontro informale, in piedi, magari accanto alla macchina del caffè, della durata massima di 15 minuti.

Al completamento dello Sprint c’è un incontro (Sprint Review) che coinvolge tutte le figure interessate allo sviluppo del progetto (può partecipare anche il cliente) e mette in atto l’idea chiave in Scrum: “inspect and adapt“. Viene mostrato il lavoro eseguito, che viene approvato secondo criteri condivisi, e discussa l’esecuzione dello Sprint. Tutti sono liberi di porre domande e dare dei suggerimenti innescando un colloquio che permette di trarre benefici dall’esperienza appena conclusa.
Successivamente alla Sprint Review viene avviata la Sprint Retrospective che estende l’applicazione della filosofia di ispezione e adattamento dal prodotto all’intero processo e coinvolge un gruppo più ristretto di persone. E’ una riunione di importanza strategica, che permette di capire cosa sta andando come previsto o cosa necessita di adattamento, nell’intero processo di produzione governato dalla metodologia Scrum. Con quest’ultima riunione lo Sprint è definitivamente concluso e il ciclo si ripete fino al completamento del prodotto.

I ruoli previsti
Scrum prevede tre ruoli:

Il Product Owner
Il Product Owner è responsabile della massimizzazione del ROI del progetto attraverso la gestione del Product Backlog, la lista di feature per il prodotto ordinata secondo una priorità dettata dal valore. Il concetto di valore è preso in senso lato, può essere dettato dalla necessità di soddisfare un cliente importante, realizzare degli obiettivi strategici o mettere in atto dei miglioramenti.
Le metodologie agili incentivano lo scambio diretto di informazioni, riducendo il numero di intermediari. E’ provato, infatti, che al crescere del numero di “handoff” il livello di qualità delle informazioni scambiate si abbassa. Questa è una delle motivazioni per cui i ruoli sono così pochi. Si ha così che, nel caso di un prodotto commerciale, il ruolo del Product Owner assomiglia a quello del classico Product Marketing Manager, con la differenza che esso interagisce direttamente con il Team, proponendo gli obiettivi. Il Team avrà così una percezione precisa, “di prima mano” dei risultati da perseguire. Il Product Owner, infine, ha la possibilità di accettare o rifiutare il risultato del lavoro del Team, sulla base di una “Definition of done” condivisa da tutti.

Il Team
Il Team, formato da 5-7 persone, è multi-funzionale (nel senso che contiene in se tutte le competenze necessarie per completare il lavoro) e in grado di autogestirsi. Sceglie i task da completare in uno Sprint insieme al Product Owner e decide in autonomia come procedere per rispettare l’impegno in modo puntuale e preciso. Il Team, oltre a occuparsi dello sviluppo, fornisce dei suggerimenti al Product Owner su come rendere il prodotto migliore alimentando il Product Backlog.

Lo ScrumMaster
Lo ScrumMaster aiuta il gruppo ad applicare Scrum, realizzare valore e garantire il successo. Scrum è in grado di evidenziare i pericoli e gli impedimenti e lo ScrumMaster si prodiga alla risoluzione delle problematiche che possono interferire con la capacità lavorativa e la produttività del team. Incentiva la cooperazione tra tutti i ruoli e le funzioni coinvolte, rimuovendo impedimenti e proteggendo il team da interferenze esterne. Si assicura, infine, che il processo sia seguito secondo la metodologia, invitando ai meeting.

Perchè mi piace Scrum?
Lascia il Team libero di poter esprimere le sue potenzialità
Lasciare il team libero di gestire il progetto, di prendere iniziative, di proporre soluzioni, anche al di fuori del contesto puramente tecnico, è un modo per lasciare esprimere al meglio le potenzialità dei talenti. Lo sperimento ogni giorno. Scrum permette tutto questo, ponendo allo stesso tempo degli obiettivi precisi, che coincidono con tutte le richieste che producono valore, e richiedendo dei risultati verificabili che migliorano la qualità del prodotto.

E’ efficace
Avere un breve percorso lineare che parte dalle specifiche e arriva a dei prodotti parziali potenzialmente rilasciabili permette di garantire una costante progressione, che si parli di un prodotto commerciale o di una soluzione ad-hoc. Il modello dello Sprint obbliga a creare la qualità nel corso della produzione del prodotto, imponendo test continui.

E’ mosso dalla logica “inspect and adapt”
Scrum permette di evidenziare e risolvere problemi e migliorare, non solo il prodotto, ma anche l’intero processo di produzione. Il risultato è che dopo una fase iniziale di resistenza e una di “caos”, in cui i processi usuali si riorganizzano per adattarsi alla metodologia, si ha un incremento continuo della produttività e della qualità.

Incentiva i feedback
Tutti sono coinvolti. Sono previste occasioni di incontro e di discussione che incentivano i feedback da parte di tutti gli stakeholder, permettendo di contribuire alla realizzazione di un prodotto migliore e al successo dell’organizzazione.

Scrum sta diventando un po la “buzz word” nell’ambito della gestione dei progetti software e sta riscuotendo molto successo. E’ un approccio agile efficace e ridotto all’essenziale e, quindi, è il più semplice da implementare. Se questo post ha suscitato la vostra curiosità, vi invito a fare il passo successivo, approfondendo la conoscenza di questa metodologia. Sono certo che resterete affascinati come me dalla semplicità concettuale e dalle potenzialità.

Pubblicato in Agile, Project management | Contrassegnato , , , , , , , , | Lascia un commento

Database Mail on SQL Azure

As requested by some people, here is the English version of my previous post on Database Mail in Italian.

Among the SQL Server 2008 features not available in SQL Azure, as shown in the MSDN, there is the absence of all those related to SQL Agent.
Database Mail, which lets you send emails from the database engine using some stored procedures in msdb, is one of these.
Creating a mechanism to queue e-mail messages in a SQL Azure database and send them through a worker role is easy, but I would like to go further, making the existing code using Database Mail compatibile with SQL Azure.
In this post we will see how we can change the system stored procedures to make them run on SQL Azure. We will consider only the most common stored procedures. All others, if necessary, may be ported in the same way.

Obtaining the original SQL Server 2008 scripts
Obtain the original code of the stored procedure is quite simple. Just open the msdb database with SSMS, left click on the object you want to change and choose Modify on the context menu. For almost all items it was possible to obtain the code to be modified this way, except for the dbo.get_principal_id and dbo.get_principal_sid functions and the xp_sysmail_format_query extended procedure. The first two have been easily rewritten, while for the extended procedure xp_sysmail_format_query, given the purpose of the post, it was decided to not to proceed. This procedure is used to append to the body or attach a file with the result of a query. If you really need it, you will need to write the code that formats the output of a query as a string representing the output table.

Managing profiles
Messages are sent using profiles, which contain all the account information and the SMTP server address. They also allow for a redundancy mechanism that ensures that your message is sent, no matter if a SMTP is down or your account has expired. Typical operations for the creation of profiles are:

— Creating a Database Mail account
EXECUTE msdb.dbo.sysmail_add_account_sp
@account_name = ‘AdventureWorks2008R2 Public Account’,
@description = ‘Mail account for use by all database users.’,
@email_address = ‘db_users@Adventure-Works.com’,
@replyto_address = ‘danw@Adventure-Works.com’,
@display_name = ‘AdventureWorks2008R2 Automated Mailer’,
@mailserver_name = ‘smtp.Adventure-Works.com’ ;

— Creating a Database Mail profile
EXECUTE msdb.dbo.sysmail_add_profile_sp
@profile_name = ‘AdventureWorks2008R2 Public Profile’,
@description = ‘Profile used for administrative mail.’ ;

— Adding an account to profile
EXECUTE msdb.dbo.sysmail_add_profileaccount_sp
@profile_name = ‘AdventureWorks2008R2 Public Profile’,
@account_name = ‘AdventureWorks2008R2 Public Account’,
@sequence_number =1 ;

— Granting profile access to users
EXECUTE msdb.dbo.sysmail_add_principalprofile_sp
@profile_name = ‘AdventureWorks2008R2 Public Profile’,
@principal_name = ‘public’,
@is_default = 1 ;

Stored procedures involved, along with their dependencies are:

  • sysmail_verify_accountparams_sp
  • sysmail_verify_profile_sp
  • sysmail_verify_account_sp
  • sysmail_verify_principal_sp
  • sysmail_add_profile_sp
  • sysmail_add_profileaccount_sp
  • sysmail_add_principalprofile_sp
  • sysmail_add_account_sp
  • sysmail_create_user_credential_sp

These stored procedures can be created in SQL Azure starting from SQL Server 2008 scripts. In general, for stored procedures not involved in the creation of credentials (sysmail_create_user_credential_sp and sysmail_add_account_sp) requires no changes other than the removal of any explicit reference to the msdb database.
The sysmail_add_account_sp stored procedure stores the username and password as a credential. This mechanism, since is not possible to retrieve the credential secret, it should be changed to allow a worker role to get the password for SMTP authentication.
An easy way is to create a new table for storing the SMTP username and password and change the sysmail_create_user_credential_sp stored procedure in order to use that table instead of server credentials.
The password field needs to be adequately protected, but because of SQL Azure current limitations we can not use the EncryptBy * statements. For sake of simplicity we will store passwords in clear text (The password field has the name “ciphertext” so we don’t forget to protect it).

CREATE TABLE sysmail_account_credential(
credential_id int IDENTITY(1,1) NOT NULL,
username nvarchar(256) NULL,
cyphertext nvarchar(256) NULL,
CONSTRAINT [SYSMAIL_ACCOUNT_CREDENTIALIDMustBeUnique] PRIMARY KEY CLUSTERED
(
credential_id ASC
)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF))

CREATE PROCEDURE [dbo].[sysmail_create_user_credential_sp]
@username nvarchar(128),
@password nvarchar(128),
@credential_id int OUTPUT
AS
— Le porzioni commentate fanno riferimento al codice originale

SET NOCOUNT ON
–DECLARE @rc int
–DECLARE @credential_name UNIQUEIDENTIFIER
DECLARE @credential_name_as_str varchar(40)
–DECLARE @sql NVARCHAR(max)

—- create a GUID as the name for the credential
–SET @credential_name = newid()
SET @credential_name_as_str = convert(varchar(40), @username) –@credential_name)
–SET @sql = N’CREATE CREDENTIAL [‘ + @credential_name_as_str
— + N’] WITH IDENTITY = ‘ + QUOTENAME(@username, ””)
— + N’, SECRET = ‘ + QUOTENAME(ISNULL(@password, N”), ””)

–EXEC @rc = sp_executesql @statement = @sql
–IF(@rc 0)
— RETURN @rc

INSERT INTO dbo.sysmail_account_credential (username,cyphertext) VALUES (@username, @password)

–SELECT @credential_id = credential_id
–FROM sys.credentials
–WHERE name = convert(sysname, @credential_name)

SELECT @credential_id = credential_id FROM dbo.sysmail_account_credential WHERE credential_id = @@IDENTITY

IF(@credential_id IS NULL)
BEGIN
RAISERROR(14616, -1, -1, @credential_name_as_str)
RETURN 1
END

RETURN(0)
GO

The following tables are used by the stored procedures:

  • sysmail_account
  • sysmail_server
  • sysmail_servertype
  • sysmail_profile
  • sysmail_profileaccount
  • sysmail_principalprofile

Again the tables can be created using the scripts generated by SSMS connected to SQL Server 2008. To fix some incompatibilities with SQL Azure we need to remove all references to filegroups and the ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON and PAD_INDEX = OFF options from the scripts.
You can use the stored procedures on SQL Azure as usual, with the exception that they do not reside in the msdb system database but on our user database.

The sp_send_dbmail stored procedure
The stored procedure sp_send_dbmail enqueues a mail message for sending. The message can be either in plain text or HTML and have files in attachment. The body of the message or the attachment may also contain the result of a query.

A glance at the stored procedures’s source code reveals that some changes are needed to make it run on SQL Azure. Firstly it is necessary to comment out the code that checks for the service broker and the ExternalMailQueue queue:

–Check if SSB is enabled in this database
–IF (ISNULL(DATABASEPROPERTYEX(DB_NAME(), N’IsBrokerEnabled’), 0) 1)
–BEGIN
— RAISERROR(14650, 16, 1)
— RETURN 1
–END

–Report error if the mail queue has been stopped.
–sysmail_stop_sp/sysmail_start_sp changes the receive status of the SSB queue
–IF NOT EXISTS (SELECT * FROM sys.service_queues WHERE name = N’ExternalMailQueue’ AND is_receive_enabled = 1)
–BEGIN
— RAISERROR(14641, 16, 1)
— RETURN 1
–END

we also need to remove the call to sp_SendMailQueues

— Create the primary SSB xml maessage
–SET @sendmailxml = ”
— + CONVERT(NVARCHAR(20), @mailitem_id) + N”

— Send the send request on queue.
–EXEC @rc = sp_SendMailQueues @sendmailxml
–IF @rc 0
–BEGIN
— RAISERROR(14627, 16, 1, @rc, ‘send mail’)
— GOTO ErrorHandler;
–END

and, of course, all references to the msdb database.

The original stored procedure calls dbo.sp_validate_user. This stored procedure is used to identify, if not specified, the default profile and checks if the user has rights to use it. At first it, this process is carried out using the information stored in sysmail_principalprofile. If the default profile is not identified, the stored procedure tries a profile lookup based on Windows Group membership. Of course, since we only have SQL authentication, this does not makes sense in SQL Azure and we have to comment out the few lines related.

The security check makes use of the functions dbo.get_principal_id and dbo.get_principal_sid, not present on SQL Azure. The function code is not available, but you can easily write it:

CREATE FUNCTION dbo.get_principal_id (@sid varbinary(85))
RETURNS int
AS
BEGIN
DECLARE @id int
SELECT @id = principal_id FROM sys.database_principals WHERE sid=@sid
RETURN @id
END
GO

CREATE FUNCTION dbo.get_principal_sid (@id int)
RETURNS varbinary(85)
AS
BEGIN
DECLARE @sid varbinary(85)
SELECT @sid = sid FROM sys.database_principals WHERE principal_id=@id
RETURN @sid
END

GO

Through the parameter @file_attachments of sp_send_dbmail you can specify a list of files to be attached to the message. The attachments are specified as a semicolon separated list of absolute file paths. The stored procedure sp_GetAttachmentData, using the extended procedure xp_sysmail_attachment_load, stores the file content in sysmail_attachments_transfer. This mechanism cannot work in SQL Azure, so you must remove the code.
Since the attachment names are stored in sysmail_mailitems they can be used for sending. Of course the files will be on the cloud storage and consequently the file path will be an absolute URL or the container/file name pair of a known storage account.

Also, the stored procedure sp_send_dbmail allows to append to the message body (or as file in attachment) the result of a query. This feature relies on the xp_sysmail_format_query extended procedure, which is called by sp_RunMailQuery. xp_sysmail_format_query deals with query and builds the string that represents the output in tabular format. For sake of simplicity this feature is removed. You can port it to SQL Azure by adding to sp_RunMailQuery the code required to execute the query and format the output table as a string.

The original definition of the stored procedures uses an impersonation as dbo (CREATE PROCEDURE [dbo]. [Sp_send_dbmail] … WITH EXECUTE AS ‘dbo’). SQL Azure does not allow the use of SNAME_SUSER() in impersonation contexts, and since it is used in the code and as a default field value, the WITH EXECUTE AS clause is removed.

Sending an e-mail
The stored procedure sp_send_dbmail relies for its operation on the sysmail_mailitems table. The sent_account_id field is set to the account id of the actually used profile, the sent_status value indicates the message status (1 sent, 2 sending failed, 3 not sent) and sent_date is set to the date and time of message sending.
With a join between sysmail_mailitems, sysmail_profile, sysmail_profileaccount, sysmail_account, sysmail_server and sysmail_account_credential you can retrieve all information needed for sending:

SELECT sysmail_mailitems.recipients, sysmail_mailitems.copy_recipients, sysmail_mailitems.blind_copy_recipients, sysmail_mailitems.subject, sysmail_mailitems.body,
sysmail_mailitems.body_format, sysmail_mailitems.importance, sysmail_mailitems.sensitivity, sysmail_mailitems.file_attachments, sysmail_mailitems.sent_status,
sysmail_account.email_address, sysmail_account.display_name, sysmail_account.replyto_address, sysmail_server.servername, sysmail_server.port,
sysmail_server.username, sysmail_profileaccount.sequence_number, sysmail_account_credential.cyphertext AS [Password]
FROM sysmail_profileaccount INNER JOIN
sysmail_account ON sysmail_profileaccount.account_id = sysmail_account.account_id INNER JOIN
sysmail_mailitems INNER JOIN
sysmail_profile ON sysmail_mailitems.profile_id = sysmail_profile.profile_id ON sysmail_profileaccount.profile_id = sysmail_profile.profile_id INNER JOIN
sysmail_server ON sysmail_account.account_id = sysmail_server.account_id LEFT OUTER JOIN
sysmail_account_credential ON sysmail_server.credential_id = sysmail_account_credential.credential_id
WHERE (sysmail_mailitems.sent_status = 0)
ORDER BY sysmail_profileaccount.sequence_number

The complete script for creating tables and stored procedures can be downloaded here . Of course, before you use this code in a production environment, you should test it thoroughly and add tighter security checks.

To create a worker role for sending messages, you can refer to the excellent MSDN blog posts I Miss You SQL Server Agent: Part 1 and I Miss You SQL Server Agent: Part 2.
The worker role needs to check if there are messages waiting on queue (sent_status = 0) and send them using an SMTP Client, trying with several accounts if needed. After sending the message, it should update the sysmail_mailitems table setting the fields sent_status, sent_date, from_address and reply_to. The values for the latter two are from the actually used account.
As mentioned earlier, the attachment file should be stored on the cloud storage, the worker role transfers it on local storage and instructs the SMTP client accordingly.

I hope I’ve provided some guidance to ease the porting process of your solution on SQL Azure, limiting the need for changes. If you need clarification, you can also contact me directly using the form on “Contatti”.

Pubblicato in Programmazione, Windows Azure Tutorial | Contrassegnato , , , , , , , | 11 commenti

Replicare le funzionalità di Database Mail su SQL Azure

As requested by some people, I published an english version of this post.

Tra le funzionalità di SQL Server 2008 non presenti in SQL Azure, dando un’occhiata all’MSDN, spicca l’assenza delle funzionalità legate a SQL Agent. Tra queste c’è Database Mail, che permette di gestire l’invio di messaggi di posta elettronica direttamente dal database engine, eseguendo una serie di stored procedure in msdb.
Realizzare un meccanismo che accodi i messaggi all’interno di un database SQL Azure e li invii attraverso un worker role è abbastanza semplice, ma vorrei andare oltre, realizzando la compatibilità con il codice già scritto per Database Mail, trasferendo su Azure le sue funzionalità.
In questo post vedremo come è possibile adattare le stored procedure di sistema in modo da farle eseguire su SQL Azure. Considereremo solo le stored procedure più comuni. Le altre, se necessario, potranno essere adattate in modo analogo.

Ricavare il codice originale
Ricavare il codice originale delle stored procedure è piuttosto semplice. Basta andare con SSMS sull’oggetto interessato nel database msdb e scegliere di modificarlo. Per quasi tutti gli oggetti è stato possibile procedere alla modifica del codice in questo modo. Le function dbo.get_principal_id e dbo.get_principal_sid sono state riscritte (ma sono banali), mentre per l’extended procedure xp_sysmail_format_query si è deciso, viste le finalità del post, di non procedere alla replicazione della funzione che permette di allegare o accodare al corpo del messaggio il risultato di una query. Se questa funzionalità è per voi strategica sarà necessario scrivere il codice che formatta l’output di una query in una stringa rappresentante la tabella di output.

Gestione dei profili
I messaggi sono inviati utilizzando i profili, che contengono tutte le informazioni sull’account ed il server SMTP da utilizzare per l’operazione e permettono di realizzare un meccanismo di ridondanza che garantisce l’invio del messaggio. Le operazioni tipiche per la creazione dei profili sono:

— Creazione di un account Database Mail
EXECUTE msdb.dbo.sysmail_add_account_sp
@account_name = ‘AdventureWorks2008R2 Public Account’,
@description = ‘Mail account for use by all database users.’,
@email_address = ‘db_users@Adventure-Works.com’,
@replyto_address = ‘danw@Adventure-Works.com’,
@display_name = ‘AdventureWorks2008R2 Automated Mailer’,
@mailserver_name = ‘smtp.Adventure-Works.com’ ;

— Creazione di un profilo Database Mail
EXECUTE msdb.dbo.sysmail_add_profile_sp
@profile_name = ‘AdventureWorks2008R2 Public Profile’,
@description = ‘Profile used for administrative mail.’ ;

— Aggiunta dell’account nel profilo
EXECUTE msdb.dbo.sysmail_add_profileaccount_sp
@profile_name = ‘AdventureWorks2008R2 Public Profile’,
@account_name = ‘AdventureWorks2008R2 Public Account’,
@sequence_number =1 ;

— Concessione agli utenti dell’accesso al profilo
EXECUTE msdb.dbo.sysmail_add_principalprofile_sp
@profile_name = ‘AdventureWorks2008R2 Public Profile’,
@principal_name = ‘public’,
@is_default = 1 ;

Le stored procedure coinvolte, con le relative dipendenze sono:

  • sysmail_verify_accountparams_sp
  • sysmail_verify_profile_sp
  • sysmail_verify_account_sp
  • sysmail_verify_principal_sp
  • sysmail_add_profile_sp
  • sysmail_add_profileaccount_sp
  • sysmail_add_principalprofile_sp
  • sysmail_add_account_sp
  • sysmail_create_user_credential_sp

Queste stored procedure possono essere create in SQL Azure facilmente, utilizzando degli script estratti dal proprio server SQL 2008. In generale, per le stored procedure non utilizzate nella creazione dell’account e delle relative credenziali (sysmail_create_user_credential_sp e sysmail_add_account_sp), non sono necessarie particolari modifiche, eccettuata la rimozione di qualche riferimento esplicito al database msdb.

La stored procedure sysmail_add_account_sp memorizza la username e la password dell’account come credenziale all’interno del server. Questo meccanismo, non essendo possibile recuperare in un secondo momento il secret della credenziale, va modificato al fine di permettere ad un worker role di ottenere la password per l’autenticazione SMTP.
Il modo più semplice è quello di creare una nuova tabella per la memorizzazione delle credenziali e modificare in modo opportuno la stored procedure sysmail_create_user_credential_sp. Ovviamente le password andranno protette in modo adeguato, ma a causa delle attuali limitazioni di SQL Azure non è possibile utilizzare gli statement EncryptBy*. Per semplicità memorizzeremo le password in chiaro (non rabbrividite, vi prego! Il campo per la password ha come nome “cyphertext” per ricordarvi di proteggerlo.).

CREATE TABLE sysmail_account_credential(
credential_id int IDENTITY(1,1) NOT NULL,
username nvarchar(256) NULL,
cyphertext nvarchar(256) NULL,
CONSTRAINT [SYSMAIL_ACCOUNT_CREDENTIALIDMustBeUnique] PRIMARY KEY CLUSTERED
(
credential_id ASC
)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF))

CREATE PROCEDURE [dbo].[sysmail_create_user_credential_sp]
@username nvarchar(128),
@password nvarchar(128),
@credential_id int OUTPUT
AS
— Le porzioni commentate fanno riferimento al codice originale

SET NOCOUNT ON
–DECLARE @rc int
–DECLARE @credential_name UNIQUEIDENTIFIER
DECLARE @credential_name_as_str varchar(40)
–DECLARE @sql NVARCHAR(max)

—- create a GUID as the name for the credential
–SET @credential_name = newid()
SET @credential_name_as_str = convert(varchar(40), @username) –@credential_name)
–SET @sql = N’CREATE CREDENTIAL [‘ + @credential_name_as_str
— + N’] WITH IDENTITY = ‘ + QUOTENAME(@username, ””)
— + N’, SECRET = ‘ + QUOTENAME(ISNULL(@password, N”), ””)

–EXEC @rc = sp_executesql @statement = @sql
–IF(@rc 0)
— RETURN @rc

INSERT INTO dbo.sysmail_account_credential (username,cyphertext) VALUES (@username, @password)

–SELECT @credential_id = credential_id
–FROM sys.credentials
–WHERE name = convert(sysname, @credential_name)

SELECT @credential_id = credential_id FROM dbo.sysmail_account_credential WHERE credential_id = @@IDENTITY

IF(@credential_id IS NULL)
BEGIN
RAISERROR(14616, -1, -1, @credential_name_as_str)
RETURN 1
END

RETURN(0)
GO

Le stored procedure, a loro volta dipendono dall’esistenza delle seguenti tabelle:

  • sysmail_account
  • sysmail_server
  • sysmail_servertype
  • sysmail_profile
  • sysmail_profileaccount
  • sysmail_principalprofile

Anche in questo caso le tabelle possono essere create utilizzando gli script generati con SSMS connesso al server SQL 2008. Gli script prodotti, per risolvere delle incompatibilità con SQL Azure, vanno modificati rimuovendo i riferimenti ai filegroup e le opzioni ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF.
Fatto questo è possibile utilizzare le stored procedure in modo usuale, con l’unica eccezione che queste non risiederanno nel database di sistema msdb ma sul nostro database utente.

La stored procedure sp_send_dbmail
La stored procedure sp_send_dbmail permette di accodare un messaggio di posta elettronica per l’invio. Il messaggio può essere in formato plain text o HTML e avere dei file in allegato. Il corpo del messaggio o l’allegato può contenere anche il risultato dell’esecuzione di una query.

Scorrendo il sorgente della stored procedure sp_send_dbmail appare evidente che necessita di alcune modifiche per poter essere utilizzata su SQL Azure. Innanzi tutto è necessario commentare il codice relativo alla verifica dello stato del service broker e della coda ExternalMailQueue:

–Check if SSB is enabled in this database
–IF (ISNULL(DATABASEPROPERTYEX(DB_NAME(), N’IsBrokerEnabled’), 0) 1)
–BEGIN
— RAISERROR(14650, 16, 1)
— RETURN 1
–END

–Report error if the mail queue has been stopped.
–sysmail_stop_sp/sysmail_start_sp changes the receive status of the SSB queue
–IF NOT EXISTS (SELECT * FROM sys.service_queues WHERE name = N’ExternalMailQueue’ AND is_receive_enabled = 1)
–BEGIN
— RAISERROR(14641, 16, 1)
— RETURN 1
–END

va inoltre commentata la chiamata a sp_SendMailQueues

— Create the primary SSB xml maessage
–SET @sendmailxml = ”
— + CONVERT(NVARCHAR(20), @mailitem_id) + N”

— Send the send request on queue.
–EXEC @rc = sp_SendMailQueues @sendmailxml
–IF @rc 0
–BEGIN
— RAISERROR(14627, 16, 1, @rc, ‘send mail’)
— GOTO ErrorHandler;
–END

e rimossi i riferimenti espliciti al database msdb.

Nel codice della stored procedure originale vengono effettuate delle chiamate a dbo.sp_validate_user. Questa stored procedure viene utilizzata, nel caso in cui questo non viene specificato, per identificare il profilo di default e per verificare se l’utente ha accesso al profilo. Nel caso in cui una verifica su sysmail_principalprofile non abbia dato risultati, la ricerca e la verifica vengono effettuati nel contesto di un gruppo di utenti del sistema operativo o del dominio. Questi controlli, essendo l’autenticazione SQL l’unica disponibile, vanno commentati.

Per la verifica su sysmail_principalprofile vengono utilizzate le function dbo.get_principal_id e dbo.get_principal_sid, non presenti su SQL Azure. Il codice delle funzioni non è disponibile, ma è possibile riscriverle facilmente:

CREATE FUNCTION dbo.get_principal_id (@sid varbinary(85))
RETURNS int
AS
BEGIN
DECLARE @id int
SELECT @id = principal_id FROM sys.database_principals WHERE sid=@sid
RETURN @id
END
GO

CREATE FUNCTION dbo.get_principal_sid (@id int)
RETURNS varbinary(85)
AS
BEGIN
DECLARE @sid varbinary(85)
SELECT @sid = sid FROM sys.database_principals WHERE principal_id=@id
RETURN @sid
END

GO

Attraverso il parametro @file_attachments di sp_send_dbmail è possibile specificare una lista di file da allegare al messaggio. Gli allegati sono specificati indicando il percorso assoluto al file. La stored procedure sp_GetAttachmentData, usando l’extended procedure xp_sysmail_attachment_load, carica il contenuto del file nella tabella sysmail_attachments_transfer. Questo meccanismo non può funzionare nel contesto di SQL Azure, pertanto è necessario rimuovere il codice relativo.
I nomi degli allegati saranno comunque memorizzati nella tabella sysmail_mailitems e potranno essere utilizzati in seguito per l’invio. Ovviamente i file non saranno nel file system locale dell’istanza SQL Azure, ma sul cloud storage e di conseguenza il percorso del file sarà l’URL assoluta o semplicemente la coppia container/nome file all’interno di uno storage noto a priori.

La stored procedure sp_send_dbmail permette anche di accodare al corpo del messaggio o inserire come allegato il risultato dell’esecuzione di una query. Questa funzionalità si basa sull’extended procedure xp_sysmail_format_query richiamata da sp_RunMailQuery. xp_sysmail_format_query si occupa di eseguire la query e di costruire la stringa che rappresenta l’output in formato tabellare. Per semplicità non ci occuperemo di questa funzione, ma è possibile ricostruire questa caratteristica modificando in modo opportuno sp_RunMailQuery.

Nella definizione della stored procedure originale è prevista l’impersonazione come dbo (CREATE PROCEDURE [dbo].[sp_send_dbmail] … WITH EXECUTE AS ‘dbo’). SQL Azure non permette l’utilizzo di SNAME_SUSER() in un contesto di impersonazione e, visto che questa è utilizzata sia esplicitamente nel codice che come valore di default nelle tabelle, la clausola EXECUTE AS è stata rimossa.

Ricavare le informazioni per l’invio
La stored procedure sp_send_dbmail si appoggia per il suo funzionamento sulla tabella sysmail_mailitems. Il campo sent_account_id viene impostato all’id dell’account del profilo utilizzato effettivamente per l’invio, il campo sent_status indica lo stato del messaggio (1 inviato, 2 invio fallito, 3 non inviato), mentre il campo sent_date viene impostato alla data ed ora di invio.
Con una join tra le tabelle sysmail_mailitems, sysmail_profile, sysmail_profileaccount, sysmail_account, sysmail_server e sysmail_account_credential è possibile recuperare tutte le informazioni necessarie per effettuare l’invio:

SELECT sysmail_mailitems.recipients, sysmail_mailitems.copy_recipients, sysmail_mailitems.blind_copy_recipients, sysmail_mailitems.subject, sysmail_mailitems.body,
sysmail_mailitems.body_format, sysmail_mailitems.importance, sysmail_mailitems.sensitivity, sysmail_mailitems.file_attachments, sysmail_mailitems.sent_status,
sysmail_account.email_address, sysmail_account.display_name, sysmail_account.replyto_address, sysmail_server.servername, sysmail_server.port,
sysmail_server.username, sysmail_profileaccount.sequence_number, sysmail_account_credential.cyphertext AS [Password]
FROM sysmail_profileaccount INNER JOIN
sysmail_account ON sysmail_profileaccount.account_id = sysmail_account.account_id INNER JOIN
sysmail_mailitems INNER JOIN
sysmail_profile ON sysmail_mailitems.profile_id = sysmail_profile.profile_id ON sysmail_profileaccount.profile_id = sysmail_profile.profile_id INNER JOIN
sysmail_server ON sysmail_account.account_id = sysmail_server.account_id LEFT OUTER JOIN
sysmail_account_credential ON sysmail_server.credential_id = sysmail_account_credential.credential_id
WHERE (sysmail_mailitems.sent_status = 0)
ORDER BY sysmail_profileaccount.sequence_number

Lo script completo per la creazione delle tabelle e delle stored procedure può essere scaricato da qui.
Ovviamente, prima di utilizzare le stored procedure in un ambiente di produzione è bene testarle a fondo e, se non viene implementato il meccanismo di esecuzione delle query, aggiungere dei controlli più restrittivi.

Per la creazione di un worker role per l’invio dei messaggi è possibile fare riferimento agli ottimi post del blog MSDN I Miss You SQL Server Agent: Part 1 e I Miss You SQL Server Agent: Part 2.
Il worker role dovrà controllare se esistono dei messaggi in attesa di invio (sent_status=0) e tentare di trasmetterlo con un SMTP Client, eventualmente riprovando con account differenti. Una volta inviato il messaggio dovrebbe aggiornare, sulla tabella sysmail_mailitems, i campi sent_status e sent_date ed inserire i valori corretti nei campi from_address e reply_to sulla base dell’account utilizzato.
Come detto prima i file degli allegati dovrebbero essere custoditi sul cloud storage, ad esempio su un container predefinito. Quest’ultimo potrebbe essere sia pubblico che privato.
Il worker role si occuperebbe di trasferire i file sul local storage e istruire l’SMTP Client ad allegarne il contenuto.

Spero di avervi fornito delle indicazioni utili al porting della vostra soluzione su SQL Azure limitando la necessità di modifiche. Se doveste avere necessità di chiarimenti, potete anche contattarmi direttamente, utilizzando la pagina Contatti.

Pubblicato in Programmazione, Windows Azure Tutorial | Contrassegnato , , , , , , , | 2 commenti

La migrazione di Web Signage su Windows Azure

Edisonweb, l’azienda per cui lavoro come direttore tecnico, ha come prodotto di punta Web Signage: una soluzione SaaS per il digital signage, la gestione di kiosk interattivi, l’audio diffusione ed il marketing di prossimità. Web Signage è una complessa web application sviluppata utilizzando il framework .NET e progettata in modo da poter scalare liberamente verso l’alto. I dati e le configurazioni sono conservati su un database SQL Server. Su questo sono presenti una serie di stored procedure che permettono di nascondere alla web application la complessità delle operazioni sul data store.

Grazie al fatto che Edisonweb è un Microsoft Gold Certified Partner, ho avuto la possibilità di provare e studiare Windows Azure molto prima del suo rilascio. Il cloud computing ha dei vantaggi enormi per l’attività di un ISV, in particolare per quelli che si occupano di segmenti di mercato molto verticali, di conseguenza abbiamo seriamente valutato l’opportunità di migrare l’applicazione sul cloud. Windows Azure ci avrebbe permesso di abbassare i costi d’infrastruttura e di migliorare la nostra offerta verso i mercati esteri, con notevoli vantaggi in termini di competitività. A questo si univa il fatto che non esisteva nessuna soluzione per il digital signage su Azure: se avessimo battuto la concorrenza nella corsa avremmo aggiunto anche una bella freccia al nostro marketing. L’obiettivo era ormai chiaro: dovevamo migrare Web Signage su Windows Azure battendo sul tempo la concorrenza preservando un progetto unitario e mantenendo tutte le caratteristiche della soluzione on premises.

Compatibilità del database
Il primo passo nel processo di migrazione è stato quello della valutazione di potenziali incompatibilità del codice T-SQL utilizzato nel data store con SQL Azure. Il risultato fu che, a parte alcune porzioni di codice in cui veniva utilizzato il costrutto SELECT INTO e i nomi di colonna nella forma schema.tabella.colonna, tutto il codice delle stored procedure era perfettamente funzionante su SQL Azure. Dopo una attività di revisione del codice incriminato eravamo in grado di attivare una sessione applicativa di Web Signage con l’application on premises e il data store sul cloud.

Compatilità dell’applicazione
Web Signage è stato progettato per poter lavorare in una web farm con una serie di front-end server in bilanciamento di carico. L’applicazione è stateless, di conseguenza il fatto di passare da una batteria di server fisici ad una serie di istanze di Web Role e Worker Role non avrebe avuto un impatto particolare.
Nel processo di migrazione è stato, invece, necessario:

  • Rimuovere codice legacy (DLL COM ed interop)
  • Rivedere le porzioni di codice utilizzanti funzioni GDI+
  • Implementare i meccanismi di utilizzo del cloud storage

Web Signage è un progetto basato su Web Automation: il framework role based per la gestione dell’auditing, delle utenze e dei criteri di manipolazione e condivisione degli oggetti sviluppato da Edisonweb. Quando Web Automation fu sviluppato con il framework .NET 1.1 erano stati importate delle porzioni di codice non gestito come COM Interop. Questo codice, mantenuto solo per garantire la backward compatibility, richiede la registrazione di librerie COM e quindi attività per le quali è necessario avere un profilo di amministrazione sul server.
Piuttosto che attuare dei meccanismi di attivazione side-by-side della libreria, visto che il codice legacy è a tutti gli effetti inutilizzato, si è preferito rimuovere gli interop e sostituire le componenti potenzialmente utilizzate con versioni in codice gestito.

Alcuni componenti (per fortuna pochi) utilizzanti funzioni di manipolazione d’immagine di GDI+, se eseguiti in Windows Azure scatenano invariabilmente un’eccezione OutOfMemoryException. E’ un problema tristemente noto.
Web Signage, per sua natura effettua manipolazioni di file multimediali, ma per fortuna il codice non compatibile è limitato ad alcune funzioni specifiche che sono state sostituite con codice WPF.

Web Signage distribuisce ai display i contenuti multimediali che vengono riprodotti da Web Signage Player. In una installazione on premises questi sono contenuti in una SAN visibile dai front-end server. La migrazione a Windows Azure richiede la sostituzione di questo storage condiviso con il cloud storage.
Tutte le operazioni di manipolazione dei file sono effettuate sul local storage di ogni istanza, era quindi necessario implementare dei meccanismi tali da garantire la robustezza del servizio e l’integrità dei dati, mantenendo al tempo stesso la compatibilità con una installazione on premises. A questo scopo è stata creata una classe in grado di gestire in modo trasparente le operazioni sui contenuti, indipendentemente dalla tipologia di installazione.

Il processo di migrazione è stato completato nei tempi pianificati e l’applicazione finale è, a parte una nota accanto il numero di versione, indistinguibile da quella erogata dall’infrastruttura in IDC. Web Signage è stata la prima soluzione professionale per il digital signage in grado di essere eseguita su Windows Azure e tutt’ora è l’unica soluzione disponibile. I vantaggi della presenza nel cloud si sono evidenziati immediatamente dopo il rilascio, con una maggiore visibilità e competitività sui mercati esteri.

Il processo di migrazione, partendo da applicazioni sviluppate sul framework .NET e con del codice di buona qualità, è relativamente veloce e permette l’accesso a benefici significativi. Il mio consiglio è sicuramente quello di valutare seriamente questa opportunità. Se volete intraprendere questa via e desiderate pormi qualche domanda, non esitate a contattarmi.

Se siete curiosi riguardo Web Signage ed in particolare sulla versione per Windows Azure, troverete tutte le informazioni sul sito websignage.eu/it.

Pubblicato in Cloud computing | Contrassegnato , , , , , , , , | 2 commenti

Dal processo a cascata alle metodologie agili di sviluppo

Il processo di produzione di un nuovo software è caratterizzato da una serie di fasi ben identificabili. Il metodo waterfall, o a cascata, è il modo più naturale per gestire le fasi di sviluppo, suddividendo il processo in una sequenza di passi rigidamente unidirezionale:

  • l’identificazione dei requisiti;
  • la progettazione;
  • la realizzazione;
  • i test di funzionamento e conformità ai requisiti;
  • il rilascio;
  • la manutenzione.

Il processo ha la grande attrattiva della semplicità e, grazie alla presenza di milestone precise, suddivide l’esecuzione del progetto in fasi distinte e verificabili. Il metodo waterfall ha avuto una forte diffusione, anche grazie al fatto che nel 1980 è divenuto lo standard per i processi di procurement e sviluppo di software del Dipartimento della Difesa americano (DOD-STD-2167).

In realtà l’elevato controllo garantito dal processo waterfall è puramente illusorio: il processo di creazione di un nuovo software è soggetto a cambiamenti in corsa e il metodo waterfall è rigido e non prevede nessun processo di revisione del progetto o dei requisiti. E’ comune, ad esempio, trovare dei problemi di progetto al momento dell’implementazione o trovarsi di fronte ad un cambiamento dei requisiti del cliente dovuti al naturale approfondimento dei processi originato dallo stesso progetto di sviluppo o a mutate condizioni di mercato.
Ci sono studi che correlano in modo inequivocabile l’utilizzo del metodo waterfall con una riduzione della produttività, aumento dei difetti (e non parliamo solo di bug, ma aderenza alle specifiche reali) e fallimento dei progetti. A fronte di queste considerazioni il Dipartimento della Difesa americano ha sostituito lo standard precedente con il MIL-STD-498, che prevede una gestione iterativa dei progetti di sviluppo. Nonostante questo il metedo waterfall continua ad essere piuttosto diffuso.

Negli anni 90, a fronte della crescente insoddisfazione sui risultati, vennero ricercate metodologie più efficaci. Nacquero una serie di approcci alternativi come Xtreme Programming, Scrum, DSDM, Crystal e FDD. Queste avevano molte caratteristiche comuni e si cercò di identificare un terreno sul quale costruire un approccio unitario. Il risultato fu l’Agile Manifesto, un documento che illustra un nuovo approccio mosso da una scala di valori in contrapposizione con le priorità tipiche della metodologia waterfall:

  • Gli individui e le interazioni sono più importanti dei processi e gli strumenti
  • Il software funzionante è più importante di una documentazione estensiva
  • La collaborazione col cliente è più importante della negoziazione del contratto
  • La risposta al cambiamento è più importante dell’ aderenza al piano di sviluppo

Per l’Agile Manifesto la soddisfazione del cliente è prioritaria e i cambiamenti al progetto, anche in fase avanzata di sviluppo, sono bene accetti. Il progresso del progetto è misurato sulla base della funzionalità raggiunta dal software. Questi obiettivi sono ottenuti con un costante dialogo tra sviluppatori, utenti e figure commerciali e applicando le migliori tecnologie e best practice. Le attività di sviluppo sono snelle e volte all’esaltazione di una semplicità che porta alla riduzione all’essenziale del lavoro svolto.

Di fronte a queste considerazioni, chi non è abituato a questo tipo di approccio non può non restare perplesso: la prima impressione è quella di assenza di controllo.
Facciamo delle considerazioni:

  • Un progetto, per definizione, deve avere un inizio ed una fine.
  • La durata del progetto influenza indirettamente il suo costo
  • Una variazione dei requisiti ha quasi sempre un impatto sui costi
  • La modifica in corsa dei requisiti, specie se tardiva, ha un potenziale impatto sulla qualità

A prima vista sembrerebbe che un processo iterativo di sviluppo mandi a gambe all’aria il tripode del project management…

Il processo di creazione di un software nasce da una necessità formalizzata come una richiesta interna o un contratto. La definizione dell’ambito del progetto chiarisce le finalità ed i limiti dell’attività di sviluppo definendo il campo all’interno del quale si può muovere il nostro processo iterativo senza revisioni dal punto di vista economico o contrattuale. Il processo di sviluppo si muoverà all’interno di questi limiti e, grazie ad una continua collaborazione tra cliente e team di sviluppo viene compreso e realizzato ciò che il cliente desidera realmente. Con lo stesso spirito collaborativo i limiti del progetto possono essere rivisti, ad esempio come conseguenza di un cambiamento degli scenari di mercato del cliente.
Tutti i project manager sanno come ci si deve comportare di fronte ad un progetto oggetto di cambiamenti: procedere per approssimazioni successive, inseguendo finalità in continua mutazione è il modo migliore per andare verso il fallimento. E’ imperativo avere deliverables utilizzabili, anche se solo parzialmente aderenti alle specifiche desiderate.
Le Agile Metodologies rispettano questo criterio realizzando un prodotto potenzialmente utilizzabile ad ogni iterazione e, se durante l’esecuzione di una iterazione di sviluppo appaiono nuove features per il software, queste vengono valutate, ordinate per priorità e accodate per l’iterazione successiva.

Ci si chiederà cosa succede se alla data di consegna non tutte le features sono state implementate. Utilizzando un approccio rigido si accenderebbero le sirene e ci si rimboccherebbero le maniche per mantenere il progetto sotto controllo.
Applicando le metodologie di sviluppo agile, le features sono ordinate in base al valore per il cliente e si accetta la possibilità che non tutte siano implementate per la data di consegna. A prima vista sembra assurdo, ma da una ricerca è emerso che in una applicazione tipica il 20% delle funzioni sono usate raramente ed il 45% non sono mai usate. Di conseguenza se lo sforzo del team di sviluppo è orientato verso quelle funzioni davvero importanti la possibilità che una funzione rimanga non implementata inizia a diventare accettabile. Le funzioni implementate realizzeranno il valore ricercato dal cliente.

Pubblicato in Agile, Project management | Contrassegnato , , , , , , , , | Lascia un commento

La sicurezza in Windows Azure

La piattaforma Windows Azure e la sua infrastruttura di rete è stata progettata per garantire i più elevati livelli di sicurezza, mitigando i possibili e permettendo un potenziale incremento dei livelli di protezione rispetto ad una infrastruttura on premises.
Le uniche porte aperte ed indirizzabili su una macchina virtuale di Windows Azure sono quelle definite esplicitamente dal file di configurazione del servizio, uploadato con il package dell’applicazione. Inoltre, ogni macchina ha il traffico filtrato dal suo switch, che blocca il traffico non autorizzato, ed è protetta dal Windows Firewall, abilitato per default. Questa configurazione permette di mitigare fortemente la possibilità di ottenere informazioni attraverso port scan e bloccare i tentativi di enumerazione dei servizi.
Eventuali attacchi Denial of Service sono mitigati dai load balancers di Windows Azure. Il continuo monitoraggio permette l’identificazione un eventuale attacco DoS originato dall’interno e l’immediata rimozione dalla rete della macchina virtuale incriminata. Inoltre il Root Host OS, che gestisce le macchine virtuali, non è indirizzabile dall’esterno ne da nessun altro tenant sulla rete di Azure.
Le VLAN utilizzate per partizionare la rete interna sono segmentate in modo da impedire che nodi compromessi possano impersonare altri sistemi o sistemi vitali come il Fabric Controller. L’unico traffico broadcast e multicast permesso sulle VLAN è quello relativo ai meccanismi di funzionamento del DHCP. Le comunicazioni tra il Root Host OS e i Fabric Controller sono particolarmente critiche (vengono trasferite le configurazioni e i certificati) e sono efficacemente protette utilizzando una connessione HTTPS crittografata e utilizzante un meccanismo di mutua autenticazione.
Lo switch virtuale dell’Hypervisor impedisce che una macchina virtuale possa sniffare il traffico relativo ad un’altra macchina sullo stesso host fisico e gli switch dei rack sono utilizzati per limitare gli IP ed i MAC Address utilizzabili, impedendo di fatto lo spoofing. L’unico modo per ascoltare il traffico diretto alle macchine virtuali gestite da un hypervisor è quello di ottenere un accesso amministrativo su una VM, trovare una falla di sicurezza sull’hypervisor tale da permettere un accesso al Root OS e ottenere un account di sistema sulla macchina fisica. Se non impossibile, quantomeno molto improbabile.
Per la mitigazione degli attacchi side channel non si è badato a spese: ogni macchina virtuale ha generalmente una CPU dedicata. Non essendo presenti più CPU logiche su una CPU fisica i pattern di accesso alle cache non sono esposti dai context switch. Le migrazioni di macchine virtuali tra CPU differenti sono ancora possibili, ma talmente rare da non fornire nessuna informazione.
I nodi attualmente hanno coppie di CPU con quattro core indipendenti. Ogni core ha una cache privata e la cache è condivisa al terzo livello. Ciò significa che le cache sono condivise con altre tre CPU. Il bus di memoria, poi, è condiviso con altre sette CPU. Questo livello di condivisione è tale da produrre un livello di rumore sufficiente a rendere impossibile la ricostruzione delle attività attuate dai meccanismi di crittografia.

Pubblicato in Cloud computing | Contrassegnato , , , , , , , , | Lascia un commento

Amazon Web Services e Windows Azure a confronto

Nei miei post precedenti, ho esaltato le potenzialità del cloud computing ed i vantaggi derivanti ma, nel concreto, come è possibile spostare i servizi sul cloud? O meglio, quale servizio tra quelli disponibili sul mercato è più vantaggioso?
Probabilmente non esiste una sola risposta a questo quesito. Da parte mia ho scelto i servizi Microsoft Windows Azure, ma esistono delle alternative, ognuna con le proprie caratteristiche. Tra queste, ha sicuramente un ruolo importante Amazon Web Services (AWS), il servizio pionieristico di cloud computing erogato da Amazon. In questo post, vorrei approfondire quali sono le differenze principali tra Windows Azure ed Amazon Web Services e raccontarvi quali sono le ragioni per cui, tra i due, ho preferito il primo.
Ovviamente si tratta di un giudizio personale dettato, non solo dalle caratteristiche tecniche dei due servizi, ma anche da considerazioni di tipo strategico/commerciale (time to market, economicità e livello di astrazione della componente infrastrutturale).
La differenza più grande ed evidente tra i servizi di AWS ed Azure sta nel fatto che il primo è una infrastruttura (IaaS) mentre il secondo è una piattaforma (PaaS). Azure usa un approccio ad alto livello nei confronti delle macchine virtuali, queste vengono istanziate e gestite senza nessun intervento diretto dell’utente dal computing service. Amazon Elastic Compute Cloud (EC2), invece, richiede la creazione ed il deployment esplicito delle macchine virtuali, scegliendo l’AMI (Amazon Machine Image) con le caratteristiche desiderate.
Le AMI sono disponibili per i sistemi operativi Red Hat Enterprise Linux, Windows Server 2003, Oracle Enterprise Linux, OpenSolaris, openSUSE, Ubuntu, Fedora, Gentoo e Debian. Sulle macchine virtuali è possibile eseguire database server come Oracle 11g e SQL Server 2005 o server come Apache, IIS, Java Application Server o JBoss Enterprise Application Platform.
D’altro canto Azure, sebbene preveda un unico sistema operativo (Windows Azure Guest OS, basato su Windows Server 2008 a 64 bit) ed un unica tipologia di server web (IIS), permette l’utilizzo, oltre alle tecnologie ed i linguaggi dei framework .NET, di applicazioni sviluppate in PHP, Ruby, Python o Java. A tale scopo sono disponibili gli SDK per Java, PHP, e Ruby ed il plug-in per Eclipse.
La Windows Azure App Fabric offre servizi di calcolo (compute) e simple storage. Un compute service permette di eseguire su Azure applicazioni composte da Web Roles e Worker Roles. I Web Role e Worker role possono essere eseguiti da un numero configurabile di istanze di macchine virtuali scelte fra una delle dimensioni disponibili:

  • Small (1 CPU core, 1,7 GB Ram, 250 GB local storage)
  • Medium (2 CPU core, 3,5 GB Ram, 500 GB local storage)
  • Large (4 CPU core, 7 GB Ram, 1000 GB local storage)
  • ExtraLarge (8 CPU core, 14 GB Ram, 2000 GB local storage)

Il Web Role è molto simile ad una web application tradizionale e pertanto viene eseguito su una macchina virtuale che esegue IIS 7. Possono presentarsi come una aplicazione ASP.NET, con file ASPX, codebehind e servizi WCF o applicazioni web sviluppate utilizzando altre tecnologie (ad. es. Ruby). Nel caso di utilizzo di istanze multiple, Windows Azure utilizza automaticamente dei load balancers hardware per ripartire il carico tra le istanze, quindi è imperativo che le applicazioni siano stateless.
Il Worker Role ricorda i servizi Windows. Vengono eseguiti su una macchina virtuale priva di IIS e non possono accettare connessioni dall’esterno. Possono, invece, iniziare delle connessioni verso il mondo esterno per ottenere i dati di input su cui lavorare.

Analogamente ad Amazon EC2 il local storage dei servizi Azure non è persistente e va utilizzato solo per la memorizzazione di informazioni temporanee. Per memorizzare dati persistenti su Amazon, è necessario quindi agganciare all’istanza dell’AMI un volume per lo storage persistente chiamato Elastic Block Store. EBS è praticamente l’analogo del cloud drive su Azure e permette di avere unità a blocchi nelle quali è possibile memorizzare dati in un file system. Come per il CloudDrive di Azure, una unità può essere montata da una sola istanza di macchina virtuale e, di conseguenza, sia L’EBS che il CloudDrive non sono adatti alla memorizzazione di dati condivisi.
Oltre ad EBS Amazon mette a disposizione un servizio per lo storage e la pubblicazione di dati: Amazon Simple Storage Service (S3). S3 è un repository sul cloud che può essere utilizzato per memorizzare informazioni di qualunque dimensione. Così come per gli altri servizi Amazon, sono disponibili dei web service per permettere alle applicazioni di utilizzare S3. I dati sono conservati come oggetti, delle entità contenenti i dati ed i metadati che li descrivono. Un oggetto non può essere più grande di 5 GB. Gli oggetti sono contenuti in buckets, il namespace degli oggetti, e caratterizzato da una chiave, che lo identifica univocamente.

Su Windows Azure si utilizza il servizio di storage, che permette la memorizzazione di dati sotto forma di blob, tabelle e code.
Il blob permette la memorizzazione di testi e dati binari organizzati utilizzando tre risorse: lo storage account, i containers e i blob. Lo storage account è l’entry point del servizio, all’interno del quale è possibile creare dei container, che forniscono un mezzo per organizzare insiemi di blob. Ai blob ed ai container possono essere associati dei metadati sotto forma di coppie chiave/valore. Tutte le operazioni sono effettuate utilizzando una semplice interfaccia REST ed i dati sono manipolati con comuni operazioni HTTP. Ciò permette un accesso semplice, standard e indipendente dalla piattaforma e dai linguaggi utilizzati.
Le code memorizzano messaggi che possono essere letti da qualunque client che ha accesso allo storage account. Una coda può contenere un numero illimitato di messaggi con dimensione massima pari a 8 KB. I messaggi sono normalmente aggiunti alla fine della coda e recuperati dalla cima. Il comportamento FIFO (first in, first out) non è comunque garantito.
Le funzionalità delle code sono simili a quelle offerte da Amazon Simple Queue Service (SQS), il servizio per la memorizzazione affidabile di messaggi per applicazioni realizzate utilizzando EC2 ed S3. Analogamente ad i servizi di storage di Azure, SQS supporta le funzioni di base per la manipolazioni di code e messaggi accessibili con semplici interfacce HTTP GET/POST.
La tabella offre uno storage strutturato sotto forma di tabella. Le tabelle memorizzano i dati sotto forma di collezioni di entità. Le entità sono simili a righe, con una chiave primaria ed un insieme di proprietà sotto forma di coppie nome/valore simili a colonne. A differenza delle tabelle di un database, due entità nella stessa tabella possono avere insiemi differenti di proprietà.

Come si può vedere esiste una forte analogia tra Amazon S3 e lo storage service di Windows Azure, sia dal punto di vista della strutturazione delle informazioni che dal punto di vista dell’utilizzo. Un interessante confronto tra Windows Blob Storage ed Amazon S3 è disponibile su thestoragearchitect.com.

Un’altra differenza sostanziale tra Windows Azure ed Amazon Web Service sta nella disponibilità di un server RDBMS. In Amazon è possibile, ad esempio, di un server Oracle ma è necessaria una attività di amministrazione e gestione. Il servizio Amazon SimpleDB permette di memorizzare, indicizzare e utilizzare query su dati strutturati. Il modello dei dati è semplice: grandi collezioni di item organizzati in domain. Gli item sono delle hash table contenenti attributi sotto forma di coppie chiave/valore. Sebbene gli attributi possano essere ricercati utilizzando query lessicografiche simili a quelle utilizzate in un comune database relazionale (ad es.: select output_list from domain_name [where expression] [sort_instructions] [limit limit]), SimpleDB non è un database relazionale. E’ solo uno storage strutturato distribuito.
Il servizio SQL Azure è un servizio costruito sulla tecnologia su Microsoft SQL Server, che permette di ottenere istanze SQL Server altamente disponibili che possono essere connesse utilizzando le modalità usuali. Non richiede nessuna attività di carattere amministrativo, eccettuata la scelta delle dimensioni ed la configurazione degli account di accesso. L’accesso al database è protetto da un firewall configurabile dal portale http://sql.azure.com che permette di abilitare l’accesso da applicazioni on premises con ADO.NET o ODBC. Rispetto ad una istanza SQL Server 2008 ha delle limitazioni, come la mancanza di SQL Agent (e di tutte le features dipendenti) e la presenza di costrutti non supportati (ad es. SELECT INTO). Le limitazioni, però, non sono tali da rendere complesso l’utilizzo di SQL Azure da parte di applicazioni legacy. In un post futuro vi racconterò della mia esperienza nel porting di una applicazione on premises sul cloud di Azure: con un po’ di attenzione non solo può essere aggirato ogni ostacolo, ma si può approfittare dell’occasione per migliorare l’architettura dell’applicazione.

Windows Azure App Fabric, oltre a rendere disponibili le funzioni fondamentali di calcolo e storage per la costruzione di applicazioni nel cloud, offre anche il Service Bus e l’Access Control. Il Service Bus fornisce l’infrastruttura di rete per connettere le applicazioni attraverso la rete per realizzare il pattern dell’Enterprise Service Bus in modo tale da poter attraversare firewall e dispositivi NAT senza richiedere la ricalibrazione delle politiche di sicurezza. Il criterio di funzionalmento si basa sul concetto di Relay Service. L’applicazione dietro il firewal contatta il Relay Service con una connessione bidirezionale ad un indirizzo di rendezvous. A questo punto le due applicazioni possono comunicare attraverso il Relay Service. Visto che la connessione viene originata da dietro il firewall, non è necessario riconfigurare quest’ultimo. Oltre a fornire il meccanismo di connessione relayed, il Service Bus permette di passare alla connessione diretta per migliorare la velocità di comunicazione. A tale scopo viene utilizzato un algoritmo di predizione delle porte che cerca di identificare quali porte sono aperte sui firewall coinvolti. Utilizzando queste informazioni i client ed i servizi possono tentare una connessione diretta. Nel caso in cui tale connessione non vada a buon fine o non sia realizzabile viene riapplicata la connessione relayed.
L’Access Control permette di applicare in modo semplice il modello di sicurezza claims-based alle comunicazioni del Service Bus. L’approccio utilizza un token di sicurezza SWT che può essere gestito indipendentemente dall’utilizzo del framework .NET (basta poter calcolare il codice di autenticazione hash HMACSHA256. L’interfaccia, tanto per cambiare, è basata su web service REST ed utilizza il protocollo per la richiesta di token di sicurezza WRAP. In sostanza, basta effettuare il POST del nome utente e della password all’indirizzo relativo alla risorsa protetta, per ottenere il token di sicurezza. Questo viene poi passato con tutte le richieste al servizio, finchè non scade.

Per quanto mi risulta, al momento Amazon non fornisce direttamente un servizio analogo al Service Bus e all’Access Control su Amazon. Tali funzionalità sono implementabili con del lavoro aggiuntivo.

Un altro servizio interessante, disponibile sia su AWS che su Azure, è la Content Delivery Network. La CDN permette di distribuire contenuti su scala globale in modo efficiente utilizzando dei nodi che gestiscono una cache locale. Amazon CloudFront è la content delivery network offerta da Amazon che permette di erogare i dati memorizzati in S3 dal datacenter più vicino al punto di utilizzo. I server CloudFront sono presenti in Europa (Regno unito, Irlanda, Olanda e Germania), Asia (Hong Kong, Singapore e Giappone) e nelle maggiori città statunitensi.
La Content Delivery Network di Windows Azure, ultimamente espansa a 20 nodi (distribuiti tra Stati Uniti, Europa, Asia, Australia e Sud America), può essere attivata per ogni account del servizio di storage. All’attivazione viene reso disponibile l’indirizzo di accesso che permette l’accesso attraverso la cache più vicina.

Amazon Elastic MapReduce è un servizio progettato per eseguire task data intensive in un ambiente parallelo, utilizzando istanze EC2 multiple e aggregando i risultati finali che vengono memorizzati su S3. MapReduce utilizza il framework Apache Hadoop, ispirato dalle documentazioni di Google MapReduce e Google File System. Il suo funzionamento è indicato all’esecuzione di operazioni semplici su una quantità molto elevata di dati.

Su Windows Azure non è disponibile un servizio con queste caratteristiche. Per ottenere qualcosa del genere è necessario sviluppare da zero il servizio ed eseguirlo utilizzando più Worker Role.

Come dicevo all’inizio di questo post, la scelta tra AWS ed Azure è dettata da valutazioni che riguardano non solo aspetti puramente tecnici, ma anche strategici e commerciali. Da parte mia ritengo, comunque, che l’approccio ad alto livello di una PaaS sia vantaggioso, soprattutto per un ISV. Non preoccuparsi in alcun modo della componente infrastrutturale permette di focalizzare l’attenzione sul core business. L’attività di deployment si riduce all’upload del package dell’applicazione e della configurazione relativa.
La disponibilità di SQL Azure e del Service Bus permette di rilasciare delle soluzioni ibride con una porzione on premise, anche utilizzando codice legacy, ottime per un passaggio graduale sul cloud. Altro aspetto importante di Windows Azure è l’eccellente supporto fornito agli sviluppatori dai tool per Visual Studio 2010 e la facilità di conversione di una applicazione web in Web Role. L’insieme di queste caratteristiche permette la creazione ed il rilascio di una applicazione per il cloud in tempi brevissimi. In un post precedente, parlando dei vantaggi del cloud, menzionavo la rapidità di prototipazione e time to market. Beh, in questo Azure colpisce in pieno il bersaglio.

Pubblicato in Cloud computing | Contrassegnato , , , , , , , , , , , , | 2 commenti

Cloud computing: opportunità per il business

Nella gestione dell’IT, gli obiettivi principali del management sono stati tipicamente la massimizzazione dell’uptime, a garanzia dell’affidabilità delle applicazioni mission critical, e la minimizzazione dei costi di gestione. Per perseguire questi obiettivi e ottenere una maggiore economia di scala, le aziende hanno concentrato le risorse dell’infrastruttura IT in datacenter e, successivamente, incrementato l’efficienza d’uso dei server utilizzando le tecnologie di virtualizzazione.
Tutto questo ha comportato un forte disallineamento tra gli obiettivi di business e quelli della gestione IT. Inoltre, la gestione di risorse in datacenter ha reso particolarmente difficile valutare il TCO di una singola applicazione e, di conseguenza, del ROI e del valore effettivo di quest’ultima. In poche parole, la tendenza all’accentramento, se da un lato introduce una economia di scala, dall’altro rende difficile la visione dei reali benefici e del valore dell’IT per il management.
Infine, il perseguimento degli obiettivi di uptime elevato e minimizzazione dei costi rende meno dinamica la gestione delle risorse di calcolo. La prototipazione di nuove soluzioni richiede la redazione di un business case con una lunga trafila che porta dall’approvazione del budget all’acquisizione delle risorse necessarie, con tempi totali di azione anche prossimi ai 12 mesi. Per velocizzare lo sviluppo del prototipo, le singole linee di business possono decidere di dotarsi in proprio delle risorse necessarie, mantenendole al di fuori del contesto del datacenter. Il risultato è una shadow app, una applicazione sconosciuta alla gestione IT, mantenuta da persone potenzialmente prive degli skill necessari a garantire i requisiti di sicurezza e non in grado di fornire supporto adeguato agli utenti.

Il cloud computing permette alle aziende di creare e mantenere applicazioni enterprise in modo più flessibile ed efficiente, mascherando tutte le complessità infrastrutturali necessarie a garantire il livello di servizio richiesto.
I costi relativi alle applicazioni nel cloud sono trasparenti, dettagliati e legati all’utilizzo, consentendo una valutazione precisa del ROI e del valore stesso dell’applicazione. L’adozione del cloud computing libera le risorse IT dalla necessità di occuparsi dell’aspetto infrastrutturale (acquisizione e mantenimento dei server e dell’hardware relativo), permettendo la focalizzazione in attività di maggiore valore e strategicità. Non essendo più necessario un lungo processo di procurement per la creazione di proof of concepts, i reparti IT possono rispondere velocemente alle richieste e alle variazioni degli obiettivi di business con il rilascio veloce ed economico di prototipi e nuovi servizi.
Infine, le risorse di calcolo possono scalare non solo verso l’alto, ma (molto più importante) anche verso il basso, abbassando i costi nei periodi in cui la richiesta abbassa. I costi possono seguire da vicino l’andamento del mercato e si paga solo ciò di cui si ha reale necessità.

Pubblicato in Cloud computing | Contrassegnato , , , | Lascia un commento

Il cloud computing: opportunità, flessibilità e rispetto per l’ambiente

La ricerca di una sempre maggiore efficienza energetica per le infrastrutture IT è un obiettivo perseguito da relativamente poco tempo. Storicamente, l’unica preoccupazione relativa all’alimentazione di un data center è stata la disponibilità in modo affidabile dell’energia, ma il progressivo aumento dei costi energetici e la sempre maggiore attenzione riguardo l’impatto ecologico delle infrastrutture IT, hanno cambiato questa mentalità.

I punti critici che influenzano l’efficienza energetica dei datacenter sono:

  • i consumi strutturali delle facility di power e cooling;
  • i consumi dell’infrastruttura fisica (server e networking);
  • il livello di utilizzo dei server;

I consumi delle facility possono essere ottimizzati attraverso l’applicazione di criteri di progettazione innovativi, che limitano i consumi elettrici per il raffreddamento. Ad esempio, il data center di Helsingin Energia ad Helsinki ricicla il calore estratto dai server producendo acqua calda per il riscaldamento delle abitazioni, mentre il datacenter Microsoft di Dublino riduce i consumi di energia ed acqua utilizzando l’aria esterna a bassa temperatura per alleggerire il lavoro dei gruppi di condizionamento.

I server di ultima generazione hanno un’efficienza energetica di gran lunga superiore rispetto a quelli di quattro o cinque anni fa. I produttori hanno fatto notevoli sforzi per ridurre i consumi senza penalizzare le prestazioni. In un datacenter possono coesistere decine di migliaia di macchine e mantenere i server aggiornati permette di ridurre drasticamente i consumi.

Infine, per mantenere le risorse dei server in continuo utilizzo, sono emerse due tecnologie: il grid computing e la virtualizzazione.
Il grid computing nasce come una tecnologia adatta a gestire i picchi di utilizzo, creando un insieme di risorse di calcolo interconnesse e distribuite. Ogni applicazione può trarre le risorse necessarie dalla rete e, se questa è abbastanza grande, i picchi di utilizzo possono essere facilmente assorbiti. L’applicazione del grid computing, però, presenta delle difficoltà relative all’esecuzione di una singola istanza applicativa mission critical su più server fisici. Si hanno, in pratica, le stesse problematiche viste nella gestione dei sistemi multiprocessore, ma su scala geografica, rendendo la soluzione talmente dispendiosa da annullare i benefici della tecnologia.

La virtualizzazione permette l’esecuzione di più server o istanze applicative su una singola macchina hardware. Ciò permette lo sfruttamento intensivo delle risorse che, altrimenti, verrebbero usate in media solo al 20%. Per rispondere ai picchi di utilizzo esistono delle tecnologie, come il Distributed Resource Scheduler di VMWare, che permettono di gestire pool di risorse e attribuirle alle macchine virtuali sulla base delle necessità. Nei periodi di basso utilizzo, per limitare i consumi, le macchine virtuali vengono consolidate ed i server inutilizzati vengono spenti. A differenza del grid computing, però, la virtualizzazione non permette l’utilizzo di hardware distribuito geograficamente.

L’idea che gli utenti possano utilizzare risorse remote, lanciata dal grid computing, ha segnato il percorso verso l’avvento del cloud computing. Grazie alla maggiore capacità di calcolo delle CPU e la connettività a larga banda, il cloud computing si è rivelato un mezzo tecnologicamente realizzabile per offrire risorse di calcolo condivise e geograficamente distribuite.
La quadratura del cerchio si è ottenuta mantenendo la vecchia filosofia di avere un server o istanza applicativa per macchina, ma applicandola a macchine virtuali. La virtualizzazione ha, così, permesso la massimizzazione dell’utilizzo dell’hardware evitando le difficoltà proprie del grid computing.

Il cloud computing, dal punto di vista economico, ha permesso una transizione strategica dal modello di erogazione di software come servizio (SaaS) al modello infrastruttura come servizio (IaaS) o piattaforma come servizio (PaaS). Il modello SaaS ha permesso agli utenti di non preoccuparsi (e spendere) sulla infrastruttura IT. Questa è gestita da chi produce ed eroga il servizio.

L’acquisizione di una infrastruttura con l’acquisto è un’operazione che comporta intrinsecamente uno spreco: il dimensionamento va effettuato sulla base delle capacità di calcolo dettate dal trend di crescita e di conseguenza si ha un sotto utilizzo fino al raggiungimento delle previsioni.
L’acquisizione dell’infrastruttura IT di cloud computing permette al fornitore di servizio SaaS di far crescere quest’ultima con il suo business, a tutto vantaggio della competitività sul mercato. Infine, la dispersione geografica dei datacenter permette di fornire in modo ottimale il software come servizio su tutto il Globo rendendo più facile l’aggressione di nuovi mercati.

Pubblicato in Cloud computing | Contrassegnato , , , , | Lascia un commento