maggio 2005 - Posts
Ho scritto un post su SqlJunkies relativo alla generazione di chiavi surrogate con SSIS che può essere interessante per chi si occupa di Data Warehouse e vuole capire l'approccio di SSIS, diverso da DTS, in merito a questo tipo di problematiche. L'articolo è in inglese, purtroppo in questo periodo non ho il tempo di tradurlo (già tanto che l'abbia scritto!).
Da sempre (e soprattutto dall'anno scorso) spiego come non sia possibile pensare di essere "al sicuro" solo per il fatto di aver installato un firewall e un antivirus, pur mantenendoli aggiornati.
Il pericolo numero uno per la sicurezza è l'utente, che quando ha diritti amministrativi può installare qualsiasi tipo di software sul proprio computer. Anche a sua insaputa. Il famoso motto "usate il computer senza essere amministratori della macchina" ha radici molto fondate.
Nel tour di MSDN dell'anno scorso dedicato alla security e nel .NET Security Day di quest'anno a Zurigo ho sempre illustrato come sia possibile scrivere del software "su misura" che non viene intercettato da nessun firewall e da nessun antivirus, spiegando anche come, nell'informatica, se qualcosa è possibile qualcuno probabilmente l'ha già fatta. Stamattina ho letto questa notizia su Punto Informatico che, semplicemente, fa venire alla luce il primo caso di questo tipo: sicuramente ce ne sono altri che non vengono pubblicizzati e magari nemmeno scoperti (in questo caso, infatti, la scoperta è avvenuta per caso e in modo anche un po' indiretto). In breve, un programmatore israeliano metteva la sua capacità di "virus writer" al servizio di agenzie investigative dedite allo spionaggio industriale.
Quello che colpisce è la cifra relativamente esigua (3.000 euro per ogni virus/trojan creato) richiesta dal colpevole. Da un punto di vista meramente economico, queste tariffe "abbattono il livello di ingresso nel mercato" da parte di chi non si fa troppi problemi per acquisire i segreti della concorrenza. Difendersi è assolutamente più caro, più che altro perché richiede un po' di cultura della sicurezza che non si può semplicemente comprare.
Vedendo la cosa da un punto di vista più generale, la considerazione che mi viene da fare è che la sicurezza in senso assoluto non è perseguibile, quindi è più sensato, arrivati a un certo punto, tracciare informazioni che consentano di risalire al colpevole in caso di "attacchi", oltre ad avere una qualche forma di intrusion detection system che consenta di analizzare le situazioni sospette. Se poi il sistema investigativo e giudiziario faranno il loro dovere, il rapporto rischio-benefici sarebbe spostato a sufficienza per dormire sonni un po' più tranquilli. Se ci pensiamo è lo stesso per l'antifurto di una casa: la sirena è ormai del tutto inutile, molto meglio un sistema di allarmi mirati (telefono, sms, ecc.) e una bella ripresa dell'intruso. Privacy permettendo, ovviamente.
PS: Ma la privacy di un ladro è più importante dell'inviolabilità della propria abitazione? Domanda interessante...
Don Box rettifica alcune affermazioni del suo libro rispetto all'uso di BeginInvoke, EndInvoke e QueueUserWorkItem. La morale è che l'ultima opzione risulta preferibile, in quanto richiede meno risorse e non obbliga a una chiamata finale (EndInvoke) una volta esaurita la chiamata asincrona.
Anche nel mio libro ho commesso un errore simile, nel senso che non ho precisato che la EndInvoke fosse obbligatoria. Comunque il problema viene da lontano, visto che non era chiaro neanche a molti sviluppatori del Framework quanto questa cosa fosse importante.
In .NET 2.0 gli anonymous methods danno una mano a evitare di rimpiangere la comodità di BeginInvoke per il passaggio dei parametri. Adesso bisogna che qualcuno scriva un libro "definitivo" su tutta la materia...
Ho saputo che i posti per L'Aquila stanno per esaurirsi: chi vuole partecipare a FWC 2005 (L'Aquila, 8 giugno, evento gratuito ma posti limitati) può ancora iscriversi sul sito dell'evento.
La giornata è tutta dedicata allo sviluppo web con ASP.NET 2.0: ho visto in anteprima il materiale che Roberto e Luca hanno preparato e devo dire che non si tratta di una semplice introduzione ma di molto di più. Purtroppo questa volta non potrò esserci (è un periodo di lavoro molto intenso che mi lascia poco tempo anche per il blog) e invidio un po' chi potrà godersi una giornata a L'Aquila (e perché no magari anche due...).
Chi ha usato le beta e le CTP di SSIS se ha provato a migrare un package DTS sarà rimasto un po' deluso dall'impossibilità di migrare i Data Transformation Task, che restano in formato DTS2000 (con la conseguenza di richiamare il motore di DTS 2000 e di non poter editare quella parte di package con l'editor di SSIS).
Beh, restavano.
Dalla prossima CTP (aka Beta3) di SQL Server 2005, dovrebbe esserci un nuovo Task in grado di "tradurre" i vecchi Data Transformation Task.
Credo di aver capito che non saranno convertiti nei nuovi Dataflow Task, ma resteranno dei task a sé, ma per lo meno saranno editabili con il nuovo editor e non richiederanno il motore di DTS 2000. Non posso che essere estremamente felice di questa decisione, che rende molto, molto più semplice affrontare la decisione di migrare a SSIS e di migliorare poi gradualmente il package nei punti più critici (leggi lenti) usando le nuove funzionalità.
Iniziamo a fare le prime previsioni su PDC 2005. Dalle informazioni disponibili finora si instuisce che i temi più "futuristici" potrebbero essere:
- C# 3.0 (quello che vediamo oggi in C-Omega è un assaggio o qualcosa di più?)
- Office 12 (client e server... uhm...)
- Microsoft Business Framework (l'avrei voluto 10 anni fa)
- Orcas (il successore di Whidbey)
- WinFS (quello vero)
Ovviamente ci saranno un sacco di dettagli (ASP.NET, Avalon, ecc. ecc.) con tante cose nuove e meno nuove. Un tema che mi sembra emergere è che non assisteremo più a una PDC come quella del 2003, completamente rirvolta al futuro (che comincia a materializzarsi solo ora, due anni dopo): ci sarà un mix tra tecnologia esistente (approfondimenti), di prossima uscita (un anno) e più futuribile (da due anni in poi).
Come al solito, scrivendo sul blog queste cose sarà divertente rileggerle a settembre.
Da oggi è disponibile il primo corso su Avalon di DevLeap. Credo sia il primo anche in Italia, ma in realtà è sempre pericoloso dire di essere i primi... comunque i commenti sono aperti e potete segnalare se c'è già qualcosa in giro. Il docente di riferimento è Luca Regnicoli, che scrive poco ma studia molto (con questo non vorrei dire che chi scrive studia poco... spero di non darmi la zappa sui piedi...) e su Avalon ha speso ormai un bel pezzo di vita.
Sinceramente è una scommessa pensare che (in Italia) ci siano molte realtà interessate ad approfondire Avalon oggi. Però comprendere Avalon può essere strategico per chi vuole scrivere oggi con Windows Forms e passare domani ad Avalon senza rifare tutto. Il gestionale su Avalon potrebbe avere molte carte in più da giocare rispetto a quello su Windows: qualcuno (e un po' anche io) pensa che passando dall'interfaccia carattere a quella Windows si sia perso qualcosa in termini di velocità di inserimento (infatti esistono ancora delle interfacce a carattere che resistono, e non è per obsolescenza); Avalon, sotto certi aspetti, consente di superare questa difficoltà, anche se interpretarlo nel modo corretto per trarne tutti i benefici è tutt'altro che semplice, tanti software dovranno nascere e morire prima di trovare la via giusta.
Spero di non rileggere questo post tra 3 anni e dovermene pentire...
Prossimamente Microsoft offre 3 giorni di sessioni sull sviluppo con Office (sempre a Segrate, Milano... per fortuna di qualcuno e sfortuna di altri).
Il nostro Luca Regnicoli sarà speaker in alcune parti (Smart Document e Information Bridge Framework). Sono giorni di quasi-ponte per molti, ma magari è proprio una buona scusa per partecipare.
Alla fine i feedback (negativi) sulle intenzioni di Microsoft di escludere Team System da MSDN Universal hanno dato dei frutti. Il risultato è una sorta di compromesso (rispetto all'attale MSDN Universal = paghi 1 prendi tutto). Su questa pagina di MSDN c'è un dettaglio piuttosto completo. Io non sono ancora riuscito a comprendere bene i vari scenari di licensing (ma perché deve essere sempre così complicato calcolare quanto costano le licenze dei prodotti Microsoft?).
Il Database Snapshot di SQL Server 2005 è uno strumento dai molteplici usi.
la funzionalità consiste nel fare una "fotografia" di un database in un certo istante. In realtà lo spazio occupato per lo snapshot è (a parte una quota minima iniziale) soltanto quello necessario a mantenere il delta, in termini di pagine, tra la versione "fotografata" e quella corrente del database.
Tralasciando gli usi applicativi che possono esistere, per motivi di test, sviluppo e deployment ci sono molti scenari in cui questo strumento può tornare utile.
In fase di test è sviluppo, è utile fare uno "snapshot" di un database prima di fare attività di modifica delle strutture delle tabelle o di elaborazione dei dati (magari con una funzione nuova). La presenza dello snapshot consente di evitare la sequenza backup/restore per tornare al punto di partenza di un database modificato.
In fase di deployment lo snapshot consente di avere un "punto di ripartenza" che si può ripristinare prima di eseguire gli script di aggiornamento della struttura di un database. In generale, prima di una qualsiasi operazione amministrativa (insomma, si può fare un UNDO senza dover fare una transazione).
Questo tipo di utilizzo ne fa uno strumento che è importante conoscere anche per uno sviluppatore, non è solo "roba da DBA".
Ho appena scoperto l'esistenza di Diff, un add-in per Reflector in grado di evidenziare le differenze tra due versioni di un assembly .NET. Non l'ho ancora installato ma sembra molto utile.
Ultimando la preparazione di un corso personalizzato su Reporting Services ho indagato sulle possibili vulnerabilità ad attacchi di tipo SQL Injection fatti ai danni di un report parametrico. Una volta tanto buone notizie, ma vale la pena di ricordare come si possono scrivere query dinamiche senza rischiare di lasciare delle porte aperte.
Reporting Services consente di scrivere query SQL parametriche. Quando queste vengono inviate a SQL Server attraverso il managed provider di SQL Server, il codice generato è una sp_executesql che contiene la parte parametrica separata da quella costante. In altre parole, se si definisce:
SELECT * FROM Customers WHERE CustomerID = @CustomerID
quello che viene inviato a SQL Server è:
exec sp_executesql 'SELECT * FROM Customers WHERE CustomerID = @CustomerID', '@CustomerID nvarchar(4000)', @CustomerID = 'ABC'
Questo uso di sp_executesql consente di avere il vantaggio e la flessibilità di una query dinamica e di avere la sicurezza di un report parametrico, dove il contenuto di ogni parametro non può modificare la semantica dell'espressione di query. Ovviamente bisogna scrivere un minimo di codice in più rispetto alla semplice concatenazione di stringhe che è il modo "normale" (ma insicuro) di affrontare il problema, però cercando sulla rete si trova facilmente qualche esempio efficace, come questa macro per CodeSmith (editor di testo) da cui si ricava facilmente del codice .NET (l'esempio è in VB.NET ma in C# cambia solo la sintassi, la logica resta identica).
Credo di non averne parlato in passato nel blog e questa era una buona occasione. Che mi dà modo anche di ricordare che ci sarà un Developer Security Tour di MSDN che tra maggio e giugno 2005 toccherà Roma, Torino, Bologna, Bari, Udine e Palermo. Gli speaker sono Fabio Santini e Raffaele Rialdi. Spero che quest'anno ci sia una sensibilità più alta di quella che abbiamo riscontrato lo scorso anno (io e Paolo Pialorsi abbiamo toccato 10 città più una giornata a Milano) dove in alcuni casi la partecipazione fu molto al di sotto delle aspettative. Ma chi legge questo blog è già stato sensibilizzato alla cosa in passato (nessun sviluppa più con un utente amministratore, vero?).
ATTENZIONE: è sempre possibile usare Reporting Services in modo "non standard" e forzare la creazione di query dinamiche che non usano la parametrizzazione delle query: si possono creare espressioni (o funzioni VB.NET) che manipolano la stringa della query direttamente, per esempio per parametrizzare un TOP n di una SELECT o per modificare la clausola di ORDER BY o altro ancora, dove la parametrizzazione di una query non può arrivare. Ma il mio post non era inteso a enfatizzare la sicurezza di Reporting Services (anzi, fate attenzione e seguite bene i consigli di Hitchhiker's Guide to SQL Server 2000 Reporting Services), quanto a ricordare come si possano creare query dinamiche in maniera più sicura (ma per ciò che non è parametrizzabile non basta e quindi bisogna sempre validare l'input prima di concatenarlo a una stringa SQL...).
Oggi ho assistito alla prima giornata (pre-conference) di SQL Pass 2005 a Monaco. Grazie a Kimberly Tripp ho compreso meglio un po' di funzionalità di SQL Server 2005 relativa alla high availability dei db relazionali, settore che in questa fase di beta non ho ancora avuto il tempo di provare (sono più concentrato sulle funzionalità di Business Intelligence).
Una funzionalità molto interessante per chi deve fare data warehousing è quella del database snapshot: fatta la "fotografia" quasi istantanea di un database, si possono convogliare su questa immagine tutte le attività di alimentazione di un data warehouse, avendo una situazione consistente tra tutte le tabelle. Farlo su un DB di produzione che viene usato realmente 24x7 sarebbe impensabile a causa del carico (immaginate una mega-transazione con isolamento Serializable...). Ovviamente, anche se si eliminano i lock, resta il carico sul database OLTP, che può essere eliminato o ridotto con un tradizionale log shipping o con il nuovo database mirroring, che nella configurazione asincrona (una delle tante possibili) fornisce una base quasi allineata al database principale, su cui si può fare uno snapshot e poi far girare le query; il mirror asincrono non rallenta le operazioni sul database principale, resta però da vedere se non sia meglio, in questa particolare condizione, continuare a fare affidamento al log shipping. Area da indagare in futuro.
In realtà in Italia non mi è ancora capitato di vedere una situazione così critica, ma la disponibilità di questi nuovi strumenti consente di affrontare scenari di aggiornamento di un data warehouse in cui si elaborano i dati anche più volte al giorno, e non solo di notte.
Da ieri pomeriggio è disponibile SQL Server 2000 SP4. L'ho già installato e ho verificato che il bug che avevo segnalato in beta (editor package DTS) è stato risolto. Non ho avuto particolari problemi a installare SP4 su un SP3, su un SP4 beta e su un RTM.
Ricordo che il SP4 è presente anche per Analysis Services (stessa pagina ma download separato) e che quest'ultimo richiede poi l'aggiornamento dei client (PTS, PivotTable Service, trovate il file PTSFULL.EXE nella directory C:\SQL2KSP4\msolap\install\PTS se scompattate il SP nella directory di default).
Ultima buona notizia: anche la versione italiana è già disponibile.
Rispondendo a una mail questa sera ho rovistato un po' di codice delle classi Collection. Probabilmente è una questione di cui avevo anche già letto da qualche parte, ma ribadire il concetto male non fa.
In .NET 1.x la classe ArrayList è molto comoda per fare array dinamici. Per iterare un array è comodo usare foreach, che in realtà genera codice che richiede un Enumerator alla classe Collection; poiché durante l'uso dell'oggetto Enumerator (durante l'iterazione nella lista) il contenuto della lista stessa potrebbe cambiare (aggiunta/cancellazione di elementi), ArrayList mantiene un numero di versione incrementato a ogni aggiunta/cancellazione e tale numero è copiato nella classe Enumerator quando quest'ultima viene creata (cioè quando parte foreach) controllando poi che a ogni iterazione (MoveNext su Enumerator) il numero di versione sia ancora uguale tra Enumerator e ArrayList corrispondente.
Pare (ma non ho misurato personalmente) che questo controllo sia piuttosto pesante rispetto ai tempi della sola iterazione (ma bisogna ricordare che in un ciclo poi farete pur qualcosa, che spesso è molto molto più costoso del costo della sola iterazione) e sarebbe bello poterlo eliminare.
In .NET 2.0 la classe ArrayList non cambia ma abbiamo i generic e la corrispondente classe è la List<T>. Usando tale classe è possibile usare il foreach vecchio stile, che però chiede un Enumerator e procede operativamente nello stesso modo descritto per ArrayList. Se però si usa il metodo List<T>.ForEach( Action<T> ) si evita tale overhead, perché il ciclo for interno a tale metodo si "adatta" a eventuali cambiamenti della dimensione della lista durante l'iterazione.
Che poi questa ottimizzazione sia vitale nella maggior parte dei programmi, ho i miei legittimi dubbi (misurare, misurare, misurare...) ma indubbiamente in qualche caso il miglioramento sarà apprezzabile. Usare i generic non è solo una questione di forma (o vogliamo dire stile?) ma anche di sostanza (prestazioni).
More Posts
Next page »