Latest Posts
C’era una volta la velleità di avere il mega-sistemone che facesse tutto, velleità rapidamente abbandonata al crescere del monolite per ovvi motivi. Nel tentativo di realizzare il monolite ci si scontra molto rapidamente con il fatto che tipicamente i requisiti di business cambiano più rapidamente del tempo necessario per la realizzazione, ci si scontra con il fatto che non è possibile pensare di fare il deploy del monolite bloccando ogni volta tutta l’infrastruttura, ci si scontra con il dettaglio che non è possibile far evolvere indipendentemente le varie parti del monolite.
Tutto questo, e molto altro, ci fa dire che tentare di realizzare un monolite non ha senso, o meglio non è economicamente sensato, perché è plausibile ipotizzare che dato un quantitativo di risorse sensate sia possibile abbattere in misura sensibile i problemi di cui sopra rendendolo possibile, ma non necessariamente sensato.
Detto questo diventa evidente che dobbiamo convivere con sistemi eterogenei, con un ciclo di vita, e di rilascio, indipendente gli uni dagli altri; sistemi che hanno ognuno le proprie logiche e i propri formati di persistenza, e tante belle (o brutte) cose che li rendono molto isolati e distanti tra loro.
Risulta altresì vero che i requisiti di business sempre più spesso ci spingono verso la necessità di far parlare tra loro questi sistemi, in una parola si rende necessario parlare di integrazione.
Ma quando abbiamo a che fare con sistemi che non sono, almeno nel ciclo di vita, sotto il nostro controllo diventa necessario introdurre qualcosa che protegga il nostro sistema da evoluzioni non retro-compatibili dei sistemi esterni con cui desideriamo dialogare.

Un ACL ha quindi lo scopo di frapporsi far i due:

Se abbiamo quindi due mondi molto diversi che in qualche modo devono poter dialogare, due mondi molto diversi come nell’esempio di cui sopra, ha molto senso mettere un cuscino di sicurezza che faccia da mediatore nel dialogo e che in alcuni casi ci possa dare molto di più.

esagerato :-)
Il cuscino, il nostro ACL, in questo caso è molto ma molto di più di un semplice cuscino, abbiamo:
- un sistema (AS400) la cui forma dei dati è molto, ma molto diversa da quello che servirebbe a noi, inoltre noi non siamo gli unici a cui servirebbero quei dati;
- c’è quindi un software commerciale di terze parti il cui unico scopo è quello di travasare, ogni 15 minuti, da AS400 a SQL Server i dati, una gran quantità di dati, e anche di fare un primo passaggio di normalizzazione/trasformazione;
- a questo punto da SQL Server siamo in grado di lanciare (al termine di ogni sync) un processo che capisce cosa è effettivamente cambiato dall’ultima sync e si limita a mettere in una coda queste informazioni;
- c’è quindi un servizio in ascolto su quella coda privata che estrae le informazioni da SQL, fa un po’ di ragionamenti e le trasforma nella forma definitiva che il mondo esterno desidera salvando i dati su MongoDB;
- infine il processo di salvataggio su MongoDB notifica su una coda pubblica l’evento avvenuto;
Che cosa otteniamo alla fine?
Una cosa fantastica un sistema push che notifica tutti gli interessati di ogni modifica che avviane sul sistema di origine.
Ovviamente con lo scotto dei 15 minuti di ritardo e con il fatto che se nella finestra temporale ci sono più modifiche le perdiamo, ma ci interessa poco perché se ci pensate passiamo dal non avere nulla di nulla ad avere una catena di integrazione facilissima da utilizzare per qualsivoglia tecnologia ci sia la fuori.
Easy peasy, lemon squeezy… ;-)
.m
Ci siamo domani sera ci sarà il secondo appuntamento con MVVM w/ Radical, ancora per questo giro la piattaforma è quella di Live Meeting, di seguito i dettagli:
Url per la partecipazione: https://www.livemeeting.com/cc/mvp/join?id=7N746Q&role=attend&pw=FrWm%2B_-6f
Meeting ID: 7N746Q
Access Code: FrWm+_-6f
A domani!
.m
Segue la traduzione in italiano del articolo pubblicato online dal Guardian la sera del 9 Giugno.
Essendo un argomento importante che riguarda tutti gli utenti Italiani di Internet e dei servizi internet di aziende Americane (Google, YouTube, Microsoft, Skype, Apple, Yahoo!, Facebook) lo ho tradotto. (Clicca sul titolo per continuare a leggere).
L’esigenza penso che possa essere comune a molti: supponiamo di avere due pagine, A e B memorizzate su domini differenti. Supponiamo di aprire B da A e di voler refreshare A quando un determinato evento si verifica in B (ad esempio l’utente preme sul classico bottone “Salva”).
Come fare? Il solito Google ci viene in aiuto con una miriade di hack e trucchi vari che però nel nostro scenario non sono tutti applicabili. Se la pagina B viene aperta con il classico window.open, una soluzione banale è quella di impostare il document.domain di entrambe la pagine ad un valore comune. Facendo questo la pagina B può richiamare una funzione qualsiasi del chiamante usando la sintassi: window.opener.MyFunction.
Questa soluzione è efficace nei casi più semplici, ma può generare effetti spiacevoli, soprattutto se A o B (o entrambe) richiamano a loro volta altre funzioni o altre pagine. In questi casi infatti il document.domain va impostato su tutte le pagine, altrimenti avremo problemi di sicurezza in altre chiamate.
La soluzione che propongo in questo post è un po’ più complessa ed è un mix delle varie tecniche che si possono trovare in giro:
- Al verificarsi dell’evento desiderato nella pagina B, andremo ad impostare un valore usando il localStorage.
1: localStorage.setItem("MyProperty", 'myValue');
Il localStorage è una delle tante novità di HTML 5 ed è supportato su tutti i browser moderni (per IE dalla versione 8 in su). In alternativa al localStorage si può usare il sessionStorage oppure per maggiore compatibilità anche i “vecchi” cookie.
Il valore impostato sarà disponibile per il dominio B, ma non per A che quindi, se ci accede, lo troverà vuoto.
- Nella pagina A inseriamo un iFrame che punterà ad una nuova pagina C, memorizzata nello stesso dominio di B. La pagina C può essere una semplice pagina HTML che conterrà il seguente codice javascript:
1: setInterval(function () {
2: var storageValue = localStorage.getItem("MyProperty");
3: if (storageValue != null) {
4: window.parent.postMessage(storageValue, "*");
5: // Remove the property
6: localStorage.removeItem("MyProperty");
7: }
8: }, 400);
Sostanzialmente viene creato un timer che ciclamente controlla la proprietà andando a leggere il localStorage. Nel caso venisse trovata valorizzata la proprietà cercata, verrà postato un messaggio al parent utilizzando il metodo postMessage. Il metodo consente di inviare messaggi cross domain tra le finestre del browser. Nell’esempio window.parent referenzierà la pagina A che è quella che sta aprendo C all'interno dell’iframe. Il secondo parametro del metodo postMessage è l’origine del messaggio e andrebbe valorizzato con il giusto dominio, nel nostro caso con quello della pagina A. Una volta inviato il messaggio alla pagina parent la proprietà verrà rimossa dal localStorage per evitare messaggi multipli.
- Nella pagina A va aggiunto un listener che rimarrà in attesa di eventuali messaggi provenienti dall’iFrame:
1: var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
2: var eventer = window[eventMethod];
3: var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
4:
5: // Listen to message from child IFrame window
6: eventer(messageEvent, function (e) {
7: alert(e.data);
8: }, false);
I messaggi inviati alla pagina A vengono gestiti dal listener sull’evento onmessage (o sul vecchio message nel caso si usi attachEvent). Nell’esempio ogni qual volta B invia un messaggio, la pagina A gestirà tale messaggio e la proprietà e.data conterrà il valore MyValue. Chiaramente all’interno della funzione che riceve il messaggio è possibile implementare qualsiasi tipo di logica ed è anche possibile distinguere le eventuali origini dei messaggi utilizzando la proprietà origin dell’oggetto e.
Una soluzione simile, ma più semplice, è applicabile anche quando B è direttamente "hostata" dentro un iFrame di A. In questo caso sarà possibile scambiare messaggi tra A e B senza passare dal localStorage, ma usando direttamente la postMessage con relativa gestione attraverso il listener.
Fino a ieri, volendo gestire qualcosa in piu’ di User Story e Task, Bug, etc. si doveva usare un certo livello di astrazione e l’uso di tool specifici come Project Server, spesso forzati ad un comportamento ai limiti del consentito.
Con le nuove feature rivelate ieri per l’Agile Portfolio Management possiamo evitare di scomodare Project Server per compiti nei quali sarebbe eccessivo, ma comunque potremo integrarlo con TFS 2013 se necessario.
Prendiamo questo esempio: vogliamo creare un sistema, e una delle sue feaure e’ il cestino dei rifiuti. Quindi creiamo la feature con il nuovo Work Item Type, e la vediamo nel backlog filtrando per feature:

Ovviamente questa feaure avra’ delle user story al suo interno. Diciamo che vogliamo mettere roba nel cestino e svuotare il cestino quando necessario.
Queste sono Product Backlog Item, o Requirement a seconda del Process Template che si utilizza. Sto usando MSF for CMMI, quindi sono requisiti – ora posso nuovamente cambiare il filtro per visualizzarli:

Ovviamente questi Requirement saranno suddivisi in una serie di Task, non ci sono differenze rispetto al passato. Ecco cosa vedo cambiando ancora il filtro:

Questa vista e’ esattamente quello che vogliamo ottenere. Ed e’ molto piu’ semplice da capire e visualizzare. piuttosto che usare altri strumenti magari in modo improprio.
Allarghiamo questo concetto: puo’ essere utile se si hanno diversi team Scrum a lavorare sullo stesso backlog? E se si hanno backlog differenti (anche se non si dovrebbe…) perche’ non unire tutto nello stesso backlog in questo modo? Era dura spiegare ad alcuni manager come il progetto sta progredendo in termini di feature e copertura del mercato. Ora non lo e’ usando il Work Item Type Feature come una astrazione sul lavoro che stanno svolgendo i team. Ed e’ out-of-the-box, il che non e’ mai male.
Come Brian ha detto, e’ solo l’inizio…c’e’ sicuramente molto ancora da aggiungere qui.
Nel post di Brian Harry qui:
http://blogs.msdn.com/b/bharry/archive/2013/06/03/visual-studio-2013.aspx
La prima preview build di VS 2013 verra’ rilasciata alla fine del mese di Giugno alla conferenza “Build 2013”.
Probabilmente se usate i blob storage di azure ma non usate chrome non vi siete mai accorti che caricando un pdf nel blob, chrome poi non ve lo scarica linkandolo. Questo perchè probabilmente non avete impostato il content type delle proprietà del blob quando avete caricato il file:
blockBlob.Properties.ContentType = "application/pdf";
Spero vi sia utile.
--Michele
In un mio precedente post abbiamo visto come cambiare la pagina di startup di un progetto Windows Phone per poter decidere all’avvio della applicazione quale pagina aprire.
Nel mio caso era per visualizzare una pagina di mancata disponibilità della rete dati, ma le applicazioni possono essere molteplici.
Per la nuova versione della mia app (pensata espressamente per WP8) ho deciso di usare il framework Caliburn.Micro ispirato dai post del bravo e disponibilissimo Matteo.
Salto tutti i dettagli del setup di una app che utilizza Calibrun, perchè nel link qui sopra potete trovare tutte le informazioni necessarie. 
La soluzione si è perfino semplificata:
- Nel bootstrapper dell’applicazione facciamo l’override della funzione CreatePhoneApplicationFrame
protected override PhoneApplicationFrame CreatePhoneApplicationFrame()
{
var frame = new PhoneApplicationFrame { UriMapper = new AssociationUriMapper() };
return frame;
}
- Definiamo ora la classe AssociationUriMapper che deriva la classe base UriMapperBase
public class AssociationUriMapper : UriMapperBase
{
public override Uri MapUri(Uri uri)
{
if (uri.OriginalString.Contains("AboutPageView"))
return uri;
return !PhoneUtilities.HasInternetConection ? new Uri("/Views/NoConnectionPageView.xaml", UriKind.Relative) : uri;
}
}
Questa classe semplicemente ritorna l’uri a seconda di alcune condizioni (nel mio caso la presenza o assenza di rete). Per qualche View è possibile saltare il controllo (ad esempio la pagina di about non necessitò di connettività)
Questa implementazione ha anche il vantaggio di funzionare per l’intera app (qualsiasi navigazione passa per il nostro UriMapper), per cui abbiamo centralizzato una gestione che prima era necessario applicare in ogni pagina.
Non sono solo uno strumento di chat all’interno del team, le appena annunciate Team Room sono un ottimo tool per arricchire la comunicazione all’interno del team.
Possiamo innanzitutto configurarle per fornire comunicazioni broadcast per specifici eventi, come una build particolare o una specifica modifica nel codice.




Ma il meglio arriva con i due tag specifici per la collaborazione: @ e #.
Il tag @ serve per taggare un utente:
che sara’ poi notificato a riguardo.
il tag # invece serve per menzionare uno specifico work item.

Dopo aver cliccato sull’ hyperlink si aprira’ una nuova tab con il work item linkato.
Potra’ sembrare stupido e semplicistico, ma e’ davvero un ausilio utile ed aggiunge valore anche a quelle discussioni ‘informali’ che si trascinano via email, oltre al fatto che essendo salvate su TFS rappresentano informazioni utili al team recuperabili a piacimento.
Confermato, la seconda puntata di “MVVM con Radical” è fissata per il 12 giugno, ore 21.30, a breve i dettagli sulle modalità di partecipazione.
http://www.doodle.com/m5rpuudxt474ies7
.m
L'obiettivo era di 8 App presenti su Windows Store entro la fine di maggio, ma alla fine sono arrivato "solo" a 7. Le App che si aggiungono all'elenco precedente sono:
Roma Trova Hotel
Impianti Sportivi Roma
Scuole Comunali Infanzia Roma
Sono principalmente delle "App Catalogo" con funzionalità di ricerca (è stata l'occasione per utilizzare SQLite). Per alcune delle 7, saranno presto rilasciati degli aggiornamenti che aggiungeranno nuove funzionalità.
Critiche e consigli costruttivi sono sempre ben accetti.
Tutti i dettagli del caso nel post del blog di ADO.NET qui
http://cytoscape.github.io/cytoscape.js
A JavaScript graph library for analysis and visualisation
http://handjs.codeplex.com
libreria per gestire via script gli eventi generati utilizzando un interfaccia touch screen
Direi che ci siamo quasi, come abbiamo già avuto modo di dire la seconda “puntata” ci porterà verso una prima bozza di applicazione reale.
Ho purtroppo dovuto modificare il doodle perché una data disponibile, il 5/6, purtroppo per cause di forza maggiore non lo è più, direi che lascio aperto il sondaggio fino a fine settimana e sabato pubblico la data definitiva.
.m
Dato che molte persone spesso chiedono quanto sia complesso aggiornare TFS, ho deciso di fare un post che mostra la procedura passo passo.
In realtà è tutto molto semplice e si può procedere semplicemente guidati da un wizard, e soprattutto è possibile farlo su una nuova macchina, lasciando nel frattempo la vecchia online. In questo modo si può effettuare un “test di upgrade”, verificare che tutto sia a posto, risolvere con calma eventuali problemi e quando tutto è a posto procedere al reale upgrade.
Come sempre potete leggere tutto su GetLatestVersion.It, Aggiornare TFS 2010 a TFS 2012 su una nuova macchina.
Gian Maria
Se dovete migrare un grosso repository Git a Team Foundation Server, e’ molto probabile che vi scontrerete contro uno dei problemi piu’ comuni quandi si migra un DVCS verso un centralizzato: capire il ciclo di vita delle branch.
Brevemente, in un DVCS non si ha il concetto di branch che si trova in un VCS come quello di TFS, a causa della natura distribuita, che tende ad avere un numero di branch maggiore, e che permette relazioni fra le branch differenti [molti parent per un’unica child]. Questa struttura non e’ migrabile in Team Foundation Server, che e’ invece un VCS centralizzato e gerarchico.
Si puo’ raggiungere un buon compromesso utilizzando Git-Tf, il tool Microsoft per migrare Git a Team Foundation Server. Dopo aver configurato il repository, si deve eseguire il comando git-tf checkin –deep per replicare ogni changeset invece di un grosso unico commit. Ma si otterra’ un errore:

Ecco cosa intendo: se si hanno piu’ parent per una branch figlia, non si puo’ replicare in Team Foundation Server. Se si effettua un rebase, si modifica la history, e quindi non sarebbe molto corretto da un punto di vista di fedelta’ del dato
Quindi? Si deve utilizzare il comando –autosquash, che andra’ a creare una storia lineare senza modificarla. Come? Analizza le HEAD revision per trovare quella piu’ “vicina” alla branch parent gerarchica. Ovviamente non tutte le gerarchie possono essere replicate da Git a TFS, ma questa soluzione permette un buon livello di fedelta’ alla soluzione originale.
Il primo “giro” di Radical mi sembra di poter dire sia andato bene, ci sono un po’ di cose da affinare ma direi che non mi posso lamentare troppo, ovviamente grazie a tutti i partecipanti.
La registrazione e il materiale del primo incontro è disponibile per il download.
Come da richiesta stiamo organizzando il secondo round il cui scopo è affrontare una “semplice applicazione per editare delle anagrafiche”, gli argomenti che tratteremo sono:
- CRUD usando RavenDB Embedded allo scopo di tener bassissima la complessità, pensate a RavenDB (in questo caso) come un mero meccanismo di serializzazione su disco (è molto ma molto di più ma in questo scenario lo useremo solo come storage nudo e crudo);
- Validazione usando i sistemi built-in di Radical e il supporto out-of-the-box per le DataAnnotation;
- Memento perché in un editor di anagrafiche un undo/redo non si nega a nessuno;
- Windsor Installer(s) ovvero come inserirsi nella pipeline di configurazione del nostro motore di IoC preferito quando le convenzioni di Radical non soddisfano le nostre necessità;
- Perché no…come e che cosa possiamo sfruttare di async/await;
Come al solito ci sono un po’ di date (non troppe questa volta) disponibili, sotto con le votazioni: http://www.doodle.com/m5rpuudxt474ies7
.m