All Posts in Blog

Aprile 21, 2020 - Commenti disabilitati su Perché è importante uno sviluppo iterativo e incrementale anche in una libreria OpenSource?

Perché è importante uno sviluppo iterativo e incrementale anche in una libreria OpenSource?

Questa è la nostra esperienza sulla realizzazione di una libreria OpenSource, di come lo sviluppo iterativo, incrementale si applichi non solo a progetti "commerciali" ma anche allo sviluppo open source, in particolare a quello guidato dalle esigenze e dal feedback.

Questa è la storia di Daikon

a dead simple and minimal framework for creating web applications in Kotlin with minimal effort

Una libreria utiizzata in molti progetti del nostro team.

La Nascita

Tutto è nato dal team in cui lavoriamo: il Team Vega e dal nostro coinvolgimento su progetti riguardanti lo sviluppo di applicazioni web in Kotlin.

Siamo stati per molto tempo dei fan di SparkJava per la sua semplicità e il suo DSL molto intuitivo.

Un'applicazione scritta in Spark è anche abbastanza semplice da testare e da manutenere, ma ci trovavamo spesso nelle condizioni di non poter usare SparkJava anche per i test.

In particolare, come spesso accade, abbiamo a che fare con servizi esterni (autenticazione, API varie, etc...), quindi nei test E2E ci piace (ove non sono disponibili i servizi veri) usare delle implementazioni che simulano il comportamento reale. Per fare questo solitamente creiamo dei test che lanciano delle API HTTP programmabili con validazioni e risposte realistiche.

Con SparkJava non possiamo lanciare più di un server HTTP nella stessa applicazione, questo perché dietro le quinte lavora con oggetti statici.

Sappiamo però che esistono librerie per soddisfare questa necessità ad esempio WireMock, ma non ci siamo mai trovati troppo bene ed in più ci forzano a configurare API HTTP in due modi diversi:
1. la libreria per il codice di produzione
2. la libreria per il codice di test.

Questo è stato uno dei motivi che hanno dato il via allo sviluppo di Daikon: avere un unico modo per lanciare più applicazioni che usano HTTP nella stessa suite di test.

In più volevamo anche qualcosa che fosse:
- rapido a partire e a servire richieste, dato che ultimamente stiamo lavorando parecchio su container docker che per loro natura sono volatili e necessitano di startup veloci.
- senza magia, ovvero la possibilità di capire facilmente come utilizzare la libreria senza magie/convenzioni che obblighino gli utilizzatori a fare mille ricerche su StackOverflow. (es: SpringBoot)

L'Evoluzione

Cosa sta dietro al concetto di iterativo-incrementale in pratica?

L'idea parte dalla necessità di trovare un modo per validare il prima possibile quello che stiamo sviluppando e capire se questo porta valore.

Per andare in questa direzione dobbiamo avere sempre qualcosa di funzionante e pronto per essere utilizzato anche se con funzionalità ridotte, grezze e migliorabili.

Non solo, gli incrementi e le raffinazioni devono essere guidate dal feedback e motivate da reali esigenze, senza speculare su quello che potrà essere o potrà avvenire nel futuro.

Oramai è qualcosa che noi in Claranet Italia diamo per scontato nella realizzazione dei progetti, ma non sempre è un concetto che viene applicato da chi sviluppa, in modo particolare nel mondo OpenSource.

A volte perché si sviluppa pensando a utilizzatori immaginari (non reali), a volte perché ci si fa prendere da manie di grandezza con il risultato di complicare il codice provando a renderlo più estensibile/configurabile/astratto, salvo poi ritrovarsi tra le mani un codice più complesso e difficile da manutenere senza una reale necessità.

In Daikon tutto (o quasi) è stato guidato dal feedback e dalla necessità.

Le prime versioni erano molto scarne: si faceva partire un' applicazione web con pochi metodi HTTP supportati, solo GET, POST e poco altro.

Man mano che usavamo Daikon nei nostri progetti, ci rendevamo conto che mancavano delle funzionalità. Quindi cercavamo di utilizzare queste reali necessità come spinta alla crescita di Daikon invece che svilupparle all'interno dei singoli progetti.

Siccome non siamo soli nell'universo, anche i feedback di colleghi, clienti e collaboratori sono stati importantissimi per capire quali funzionalità aggiungere o affinare.

Nonostante avessimo testato l'applicazione con scrupolo e il suo design sia stato fatto in TDD, niente è esente da bug. Questi feedback, quindi, ci hanno aiutato molto a trovarne alcuni (pochi per fortuna), verificarli con dei test e correggerli.

Man mano che Daikon veniva usato ci sono stati segnalati alcuni miglioramenti che avrebbero potuto semplificare il suo utilizzo e così, basandoci su necessità, feedback e uso quotidiano, abbiamo fatto la sua roadmap, fino a renderlo una libreria stabile e usata in diversi progetti in produzione.

I Traguardi Raggiunti

Uno degli obiettivi che ci eravamo prefissati era di tenere la libreria il più snella possibile. Per questo motivo abbiamo sempre cercato di evitare l'aggiunta di dipendenze. Quando qualcosa si rendeva necessario (es: parsing delle richieste e risposte in JSON) creavamo delle estensioni per Daikon che a tutti gli effetti erano progetti separati.

In questo modo l'utilizzatore ha a disposizione il set minimo di funzionalità che gli servono ed eventualmente aggiunge le estensioni alla sue dipendenze per le altre funzionalità.

Per quanto riguarda le estensioni, ci è venuto in soccorso Kotlin che, grazie alle Extension Functions, ci ha permesso di trovare un modo elegante, leggero ed espressivo per estendere il core di Daikon.

Sono nate così diverse estensioni:
* Daikon Freemarker
* Daikon Gson
* Daikon Jackson XML
* Daikon Eureka
* Daikon Prometheus

Dopo qualche tempo abbiamo iniziato a gestire anche alcuni servizi Serverless, quindi abbiamo deciso di estrarre l'intero routing nel CORE di Daikon in modo che fosse flessibile ed utilizzabile sia come server HTTP (usando Jetty) sia in Lambda che semplifica la gestione di applicazioni serverless.

Quindi è nato un altro interessante progettino: Daikon Lambda che ha la stessa interfaccia e le stesse funzionalità di base di Daikon.

Abbiamo poi deciso di estendere il concetto di semplicità e minimalismo anche al client HTTP. Così è nato anche Topinambur.

Collaborazione ed entusiasmo

Una cosa che ci è piaciuta moltissimo è stato il fatto che il Team Vega non fosse solo in questa avventura. Ai nostri colleghi è piaciuto il progetto e si sono adoperati per darci una mano a realizzare qualcosa che mancava o a migliorare quanto avevamo fatto. Ad esempio Daikon Prometheus è nato dall'esperienza in quell'ambito di un nostro collega che ha visto l'opportunità di estendere la nostra libreria con quanto conosceva.

I clienti, inoltre, si sono dimostrati da subito entusiasti del progetto, sia perché avevano a disposizione qualcosa di funzionante e semplice integrato nei loro progetti, sia perché lo hanno potuto integrare in altri loro sistemi senza difficoltà e molto velocemente. Senza contare il fatto che lo sviluppo di Daikon non aveva intaccato (se non positivamente ) la delivery del progetto.

Feedback

Daikon è un progetto in continua crescita che si evolverà ulteriormente grazie ai feedback che riceveremo. Potete contribuire in vari modi:
* usatelo e diteci come vi trovate, cosa vorreste avere in più o cosa vorreste migliorare;
* diventate contributor del progetto;
* mettete un like a questo post e una stellina al progetto su GitHub.

PS: vi siete chiesti come mai le librerie hanno nomi di vegetali? Basta nomi di animali, finalmente una libreria vegetariana!

Marzo 4, 2019 - Commenti disabilitati su Preparati a diventare un AWS Specialist in Big Data

Preparati a diventare un AWS Specialist in Big Data

L'esame di certificazione AWS Big Data Specialty è un esame di alto livello che richiede al candidato una eccellente conoscenza non solo dei servizi AWS ma anche delle tecnologie Big Data.

Ottenere la certificazione AWS Big Data Specialty ti permette di imparare nuove skills e portarti ad un avanzamento di carriera come professionista nel campo dei Big Data e Analytics.

L’esame è rivolto a persone che operano analisi complesse di Big Data e valida l’abilità di:
- implementare i servizi core di AWS Big Data con le best practices architetturali;
- sfruttare e automatizzare strumenti di data analysis.

Il formato dell’esame è quello solito, si può prenotare una sessione direttamente dal portale di training AWS e sostenere l’esame con domande a risposta multipla in un tempo massimo di 3 ore. Il costo di registrazione all’esame di certificazione è di $ 300. Le domande d'esame sono tipicamente riferite a scenari pratici e reali di utilizzo delle tecnologie Big Data.

Nel percorso di studio consigliato da Amazon c’è il corso Big Data on AWS che offriamo regolarmente on-site e in classi pubbliche. Ulteriori materiali utili per prepararsi sono i whitepapers, la documentazione, il canale Youtube AWS re:Invent e la piattaforma di training ufficiale AWS.

Prima dell’esame ti consigliamo di visualizzare il blueprint dell’esame disponibile qui. In questo documento sono elencati i prerequisiti necessari al sostenimento dell'esame.

Il nostro trainer Gianluigi Mucciolo a proposito della certificazione: "Per il superamento dell'esame il corso è fondamentale, e sono necessari almeno 6 mesi di utilizzo di AWS per conoscere al meglio gli aspetti più particolari dei servizi big data."

Cosa imparerai nel nostro corso:

- Amazon Kinesis Firehose and Kinesis Stream;
- Amazon S3;
- Amazon DynamoDB;
- Amazon Quicksight;
- Amazon Redshift;
- AWS IoT;
- Amazon Machine Learning;
- Security: IAM, AWS KMS, AWS CloudHSM;
- Disaster Recovery: Soluzioni per Backup e Restore di dati in altre regioni AWS.
- Amazon Data Pipeline.

Altri argomento oggetto, in misura limitata, del corso sono:

- Amazon VPC.
- Elastic Load Balancer e Auto Scaling.
- Amazon SQS e Amazon SNS.

La certificazione ti da un valore aggiunto, ormai ci sono tantissime persone che si spacciano per "big data specialist" ma pochi di questi sono veramente competenti in materia, con questa certificazione puoi effettivamente dire di saperci mettere le mani."

I nostri trainer hanno già sostenuto l’esame di certificazione Big Data e sono a disposizione per suggerimenti e indicazioni per raggiungere l’obiettivo.

Hai già sostenuto l'esame AWS Big Data Specialty? Candidati e Lavora in XPeppers come Cloud Engineer oppure consulta la nostra offerta formativa.

Ottobre 1, 2018 - Commenti disabilitati su XPeppers entra a far parte del gruppo Claranet

XPeppers entra a far parte del gruppo Claranet

XPeppers entra a far parte del gruppo Claranet portando una forte cultura Agile e DevOps all’interno della multinazionale.

Claranet, leader europeo nei servizi di hosting e di gestione delle applicazioni critiche, estende la propria offerta di servizi con competenze di DevOps e di metodologie e sviluppo Agile grazie alla fusione con XPeppers. Espande inoltre la propria offerta Amazon Web Services (AWS) e conferma la sua posizione di leader nel mercato europeo del cloud outsourcing, rafforzando le competenze per supportare ancora meglio applicazioni complesse nel Cloud.

XPeppers è una delle aziende leader nel mercato italiano di sviluppo software e Cloud che utilizza le metodologie Agili, avvalendosi anche di framework come Scrum e Kanban, per migliorare la gestione dei processi aziendali e lo sviluppo di prodotti software altamente affidabili e manutenibili.

Adotta e promuove inoltre la cultura e le pratiche di eXtreme Programming per aiutare le aziende a ridurre il tempo tra l’idea e la produzione oltre ad aumentare la qualità del software.

XPeppers vanta inoltre una profonda conoscenza dei principi e dei valori, nonché delle pratiche tecniche e metodologiche connesse alla cultura DevOps e ai cosiddetti metodi di sviluppo Agili, attraverso i quali guida i propri clienti verso la trasformazione digitale.

«Essere parte del Gruppo Claranet creerà nuove importanti opportunità per i nostri clienti, partner e dipendenti - commentano soddisfatti Mario Lanzillotta e Anna Tocci, i due fondatori di XPeppers -. Tutto il nostro ecosistema potrà infatti beneficiare delle operazioni paneuropee di Claranet, della sua base finanziaria e di un’offerta di servizi mai così ampia e di valore»

In questo modo XPeppers è in grado di affiancare i clienti in tutto il ciclo di sviluppo, dal miglioramento dei processi aziendali alla realizzazione del prodotto fino alla gestione dell’applicazione su server on-premise o su cloud.

XPeppers ha un fatturato annuo di circa 4 milioni di euro e tra i suoi clienti annovera, tra gli altri, Condé Nast e Mercury Payments.

«L’ingresso di XPeppers nel gruppo Claranet era inevitabile. In qualità di specialista AWS, XPeppers incarna un partner ideale e consente a Claranet di perfezionare la sua capacità di portare tutti i benefici di AWS ai clienti europei. Attraverso AWS e DevOps XPeppers completa in maniera ideale il nostro portafoglio e la nostra offerta. I nostri clienti ora potranno beneficiare di tutti i vantaggi del cloud pur mantenendo un unico punto di contatto sul territorio e a livello locale» spiega Lucia Terranova, Deputy General Manager Claranet srl.

Febbraio 12, 2018 - Commenti disabilitati su Condé Nast Genius on AWS

Condé Nast Genius on AWS

In questo episodio di This is My Architecture, il format AWS in cui vengono presentate architetture cloud innovative, Marco Viganò CTO digital di Condé Nast ha mostrato la soluzione adottata per il progetto Genius.

Genius è il cervello dietro molti dei portali del gruppo Condé Nast, un motore di recommendation per gli oltre 30 milioni di visitatori.

Abbiamo collaborato con Condé Nast per la realizzazione di parte dell’infrastruttura. Il loro approccio da early adopter ci ha permesso di iniziare ad utilizzare i servizi di Rekognition poche ore dopo il loro rilascio al pubblico.
I nuovi servizi di machine learning di AWS vanno ad arricchire i contenuti presenti nel DAM interno con informazioni relative agli oggetti e le celebrity individuati nelle foto.

Con un’infrastruttura completamente serverless, i costi di elaborazione e manutenzione sono ridotti al minimo e i media taggati in maniera automatica sono diventati immediatamente abilitanti allo sviluppo di nuove funzionalità. Nello specifico, le informazioni relative alle celebrity presenti nella gallery vengono utilizzate in un modello di MXnet per migliorare la rilevanza dei contenuti suggeriti ai visitatori.

Citando il CEO di AWS, per la riuscita del progetto è fondamentale avere la possibilità di esplorare nuove soluzioni in maniera iterativa senza grandi investimenti anticipati che possano in qualche modo precludere la scelta di altre strade.

Febbraio 7, 2018 - Commenti disabilitati su Pixartprinting case study

Pixartprinting case study

Fresco di stampa, un nuovo case study prodotto da Amazon Web Services per un cliente con cui collaboriamo da tempo, Pixartprinting.
L'azienda, specializzata nella fornitura online di servizi di stampa personalizzata di cataloghi, riviste, packaging e molto altro ancora, vanta una utenza di 600.000 clienti attivi in tutta Europa.

Il nostro coinvolgimento è iniziato con un percorso di training volto a preparare il team al cambiamento per una infrastruttura distribuita, automatizzata, affidabile e di veloce evoluzione.

Alla formazione abbiamo affiancato anche Training on the job, con lo scopo di instaurare metodologie processi e buone pratiche in concreto sul dominio applicativo del cliente. In particolare per le tematiche relative a Docker e ai sistemi di Orchestration offerti dai servizi AWS.

Insieme a loro abbiamo implementato una infrastruttura immutabile che permette di non dover aggiornare i server continuamente sul posto bensì di sostituirli con server nuovi realizzati da una immagine comune secondo necessità. Sempre in ottica DevOps è stato introdotto CodePipeline, il servizio di continuous integration e deployment.

Le parole di Enrico Pesce, DevOps leader, sono quelle che ci danno maggiore soddisfazione; il fatto che la tecnologia non sia più un freno all'evoluzione del business, bensì un elemento abilitante per esplorare nuove fonti di revenue rispecchia appieno il concetto di business agility che vogliamo portare in tutte le aziende con cui collaboriamo.

Leggi il case study completo

Gennaio 18, 2018 - Commenti disabilitati su Incontro DevOps 2018 – Build your serverless glue application using AWS Lambda

Incontro DevOps 2018 – Build your serverless glue application using AWS Lambda

Anche quest’anno saremo presenti a Incontro DevOps con un nuovo workshop.

Esistono molte risorse online in grado di aiutarti a partire con AWS Lambda, ma c’è una carenza di contenuti in grado di portarti ad una soluzione di architettura serverless estesa, in ambienti di produzione. Parte della motivazione è legata al fatto che le pratiche e i pattern sono ancora in fase di evoluzione. Nonostante l’hype iniziale attorno a questo termine, molte aziende sono ancora all’inizio del loro percorso di adozione di questo paradigma che offre notevoli vantaggi.

Il workshop “Build your serverless glue application using AWS Lambda” nasce dall'esperienza sul campo in contesti piuttosto complessi. Copre tutti gli aspetti necessari per essere production ready con una soluzione basata su AWS Lambda, tra cui:

- autenticazione e autorizzazioni
- Continuous Integration
- come organizzare le funzioni
- logging e monitoring
- integrazione di più fonti e servizi esterni

 

Storicamente con il termine glue code ci si è riferiti a del codice sorgente scritto per adattare tra loro moduli software altrimenti incompatibili. Oggi, la cloud-transformation, i numerosi servizi eterogenei ed API-first hanno reso tale pratica quanto mai attuale. Come affrontiamo il conseguente aumento di glue code nelle nostre applicazioni? Quali vantaggi offre un approccio serverless? Quali pattern usare?

Il prossimo 8 marzo a Bologna avrai la possibilità di imparare a costruire applicativi in grado di catturare eventi, elaborarli e renderli disponibili a servizi esterni, basandosi su architetture Serverless. In questo workshop mostreremo come sfruttare AWS Lambda e Amazon API Gateway per ridurre il time to market e la quantità di glue code necessaria ad implementare un'applicazione web che raccolga dati da varie fonti e comunichi con servizi di terze parti come Slack o Twilio. Vedremo anche come configurare la soluzione di Continuous Integration e Monitoring dell'applicazione.

Il costo del biglietto early bird è di € 180, compila il form per la registrazione o contattaci per sconti di gruppo.

Gennaio 11, 2018 - Commenti disabilitati su CULTURAL CONTEXT IS EVERYTHING

CULTURAL CONTEXT IS EVERYTHING

Nell'adozione di agile o delle pratiche lean, il contesto culturale è tutto. Operando nell'ambito del cambio delle organizzazioni, la cultura non è un fattore che può essere trascurato ma al tempo stesso, non è soggetto a principi di design. Matteo Carella esamina gli "errori del passato" da Toyota al modello Spotify per capire il presente e il futuro.

 

Il talk di Matteo, presentato all'ultimo AgileBusinessDay enfatizza il ruolo e il peso della cultura nell'ambito dell'adozione delle pratiche agili. Differenti culture conducono a differenti risultati, dipendentemente dal contesto. Seguono alcune note sulla cultura come fenomeno complesso, che non può essere soggetto a principi di design (banalmente come quelli della mera applicazione di processo), ma che può essere solo analizzato in base alla sua naturale disposizione (che cambia continuamente).

Considerare la cultura come qualcosa suscettibile di design o "impiantabile" comporta una serie di antipattern e misconceptions che conducono a cambi culturali poco o per nulla effettivi (es. la replica a tutti i costi del modello Toyota nelle industrie americane fino all'ossessione per il "modello Spotify" inteso erroneamente come framework piuttosto che come esempio di cultura). L'utilizzo dei rituali nell'ambito dell'organizational design e il loro significato cognitivo. Esempi di successo (Zalando e Lego®) basati su una cultura aziendale sana, radicata e spontanea.

Gennaio 10, 2018 - Commenti disabilitati su CONTINUOUS DELIVERY: DOVE SIETE E DOVE POTETE ARRIVARE?

CONTINUOUS DELIVERY: DOVE SIETE E DOVE POTETE ARRIVARE?

 

Agli ultimi Agile Days a Urbino, Joe Bew ha spiegato cosa significa fare Continuous Delivery, quali sono i passi che in modo iterativo e incrementale aiutano il team a raggiungere una maggiore consapevolezza e conoscenza sul tema, al fine di modellare il processo di rilascio software per adattarsi meglio ai requisiti di business.

Durante le sue attività di supporto ai team, Joe ha messo a punto una tecnica per fare emergere l’attuale processo di delivery per visualizzare gli impedimenti e capire quali passi compiere per visualizzare il processo corrente:

  1. expectation
  2. discover
  3. visualize
  4. redesign
  5. realize
  6. share

Grazie a questo format i vari stakeholder sono riusciti ad evidenziare eventuali roadblock e migliorare il loro processo di delivery.

Gennaio 10, 2018 - Commenti disabilitati su I TERRIBILI “GUARDIANI DELLA CODEBASE”

I TERRIBILI “GUARDIANI DELLA CODEBASE”

Spesso le persone con maggiori conoscenze tecniche e di maggiore esperienza tendono col tempo a diventare over protettive nei confronti del software che hanno costruito con tanta passione. Durante il talk dell'ultimo Agile Days, Paolo D'incau ha raccontato quali sono i principali danni che questo comportamento può arrecare in un’azienda agile e come la figura del “guardiano” possa naturalmente evolvere in un’altra figura che agisce da catalizzatore per la crescita del team.

 

 

Il talk nasce dall'osservazione sul campo di un pattern presente in tanti team dove spesso la persona con più conoscenza tecnica e di prodotto non riesce a rilasciare il controllo e far crescere le persone che ha accanto, perché teme di far abbassare la qualità della codebase.

Il tema è molto caro a Paolo, che afferma: "mi considero un guardiano della codebase "disintossicato" e ho avuto a che fare con parecchi guardiani negli ultimi anni quindi ho moltissimi esempi reali da raccontare durante il talk per guidare la discussion. Credo che in un mondo come il nostro, in cui si parla spesso di eccellenza tecnica e di craftsmanship valga la pena ricordare che alla base di un team agile c'è ben altro, come il lavoro di squadra e la crescita omogenea delle persone."

Settembre 21, 2017 - Commenti disabilitati su Refactoring e architettura emergente di un’applicazione Zeppelin

Refactoring e architettura emergente di un’applicazione Zeppelin

Condividiamo alcune esperienze sulla gestione di un progetto complesso in ambiente Apache Spark/Apache Zeppelin.

Uno dei progetti su cui il team di XPeppers ha lavorato negli ultimi mesi è stato lo sviluppo di un'applicazione di software quality dashboard per un grande gruppo bancario. Il compito dell'applicazione è fornire un pannello di controllo centralizzato attraverso cui monitorare la qualità del software rilasciato dai numerosi fornitori del gruppo. I dati da gestire sono generati da SonarQube, aggregati e rappresentati secondo logiche custom definite dal Cliente. I progetti da tenere sotto monitoring sono molti, e per ciascuno di essi si devono processare sia dati attuali che trend storici; serviva quindi una piattaforma di big data management. La scelta è stata di usare la coppia Apache Zeppelin / Apache Spark, sviluppando il codice necessario per le elaborazioni e visualizzazioni custom in Scala (per l'elaborazione dati) e AngularJS (per la UI), e usando SBT come strumento di build.

Il primo spike

La prima versione dell'applicazione è stata sviluppata in modo un po' quick & dirty: volevamo arrivare velocemente a mostrare un prototipo funzionante agli stakeholder e capire se la scelta dello stack tecnologico (e soprattutto di Zeppelin come front-end) fosse accettabile. La demo è piaciuta e ci siamo trovati con la "release 0" (ci siamo concessi un approccio "Spike and Stabilize").

Questa prima versione era costituita da una singola nota Zeppelin, suddivisa in una ventina di paragrafi, molti dei quali contenenti diverse decine di righe di codice Scala e SQL più o meno complicato. Soltanto due servizi erano forniti da classi Scala compilate separatamente: il dialogo HTTP con i Web Service di SonarQube, e la gestione di una base dati locale in formato Parquet.

noterel0

Primo refactoring

Era il momento di fare un po' di stabilize, e il problema principale della release 0 era evidente: troppo codice troppo complicato inserito nel corpo della nota Zeppelin, e quindi di gestione incredibilmente difficile (versioning quasi inutile, impossibilità di usare IDE o editor evoluti per modificarlo, ...)

Abbiamo quindi cominciato a migrare il codice dalla nota Zeppelin verso classi Scala, cogliendo l'occasione per aggiungere dove possibile test unitari (in Scalatest). Il codice ha cominciato ad assumere una forma vagamente object-oriented, anche se ancora un po' rudimentale.

La relazione fra la nota e le classi Scala importate da JARera un po' migliorata:

notes2.png

Nel frattempo il PO ha cominciato a chiedere modifiche alla nota originale, e un bel giorno le dashboard richieste sono diventate due, molto simili fra loro come layout, ma con diversi set di dati visualizzati (dati di leak period vs. dati storici per una data scelta in input). Questo è stato anche il momento in cui abbiamo agganciato per la prima volta una callback (scritta in Scala) alla GUI AngularJS della dashboard (usando il metodo angularWatch dello ZeppelinContext).

Il secondo punto di partenza

Il fatto di aver migrato una parte del codice dalla nota ai sorgenti Scala, ovviamente, si è rivelato provvidenziale nel passaggio da una a due note. Tuttavia, le due note attingevano a fonti di dati diverse (il database Parquet per la nota principale, i WS Sonar per la nuova dashboard "di leak period") e per farlo usavano metodi nati indipendentemente e collocati in classi diverse. Inoltre, entrambe le note contenevano ancora parecchio codice; andavano lente, ed erano instabili. La manutenzione e il refactoring erano sempre molto difficili. Sapevamo che le classi Scala avevano parecchi problemi (a partire da un forte difetto di SRP: avevamo 2 o 3 classi “demi-god” con decine di metodi di accesso ai dati), ma le possibilità di refactoring erano limitate dal fatto che mancavano ancora molti test unitari e prevedere/verificare le conseguenze delle modifiche sulle note era molto complesso.

Nel frattempo, erano entrate nuove richieste dal PO, tra cui una per una terza dashboard (sempre simile come layout ma diverse come logica di caricamento dati), e ogni tanto ci veniva chiesto di clonare una nota per una demo. Queste note “demo” diventavano tipicamente inutilizzabili dopo qualche settimana, perché legate a codice modificato in continuazione, e non soggette a manutenzione.

Con la terza nota avevamo una valida giustificazione per un nuovo refactoring. A questo punto era evidente che l'applicazione sarebbe stata soggetta a ulteriori evoluzioni per i mesi a venire, e che avevamo raggiunto la soglia di design payoff: per non rallentare dovevamo fermarci, e rivedere più profondamente il design.

Secondo refactoring

Nelle settimane successive non abbiamo rilasciato quasi nessuna major feature, e abbiamo lavorato sul debito tecnico, in modo mirato, fino a portare a casa due breakthrough principali:

  • abbiamo trovato un’implementazione molto più efficiente per le note, che ha reso possibile provare il funzionamento in poche decine di secondi (vs. tempi sopra la decina di minuti) e cominciare a parlare di una ten-minute build comprensiva di integration test;
  • abbiamo definito un’interfaccia comune (in effetti una classe astratta) da cui far dipendere, in modo uniforme, tutte le note, migrando faticosamente la vecchia pletora di metodi simili-ma-diversi sotto il cappello della nuova interfaccia. L’abbiamo chiamata Report (nel senso di un report Sonar).

A questo punto la differenza principale fra le diverse note consisteva nella classe concreta che veniva istanziata per popolare la nota. La “Leak Period Dashboard” istanziava un LeakPeriodReport, la “Dashboard” principale (che mostra un report riferito a una data fornita in input) istanziava un TimeReport, la “Comparative Dashboard” (che mostra un report che è il delta fra due date, una generalizzazione del concetto di leak period) istanziava un DeltaReport (dandogli in pasto in costruzione altri due Report fra cui calcolare il delta). Una cosa così:

uml1

Le differenze fra le varie dashboard non erano proprio tutte solo nell’istanziazione del Report concreto: alcune note avevano bisogno di agganciare callback e altre no, c’erano delle variazioni nelle visualizzazioni di alcuni valori, e così via. Ma eravamo arrivati a note con 3-4 paragrafi ciascuna:

  • inizializzazione delle dipendenze (con l'interpretespark.dep)
  • setup di eventuali dati specifici (per esempio, le date fra cui scegliere nelle note "temporali")
  • istanziazione di un (certo tipo) diReport
  • popolamento della dashboard a partire dal report (una serie di binding delle variabili Angular a partire dai dati forniti dalReport)
  •  eventuale aggancio di callback

Terzo refactoring

A questo punto è arrivata una richiesta del PO di tipo nuovo:

"Belle. Ora fatemele uguali anche per questi altri 4 gruppi di progetti."

Si trattava di passare da 3 dashboard (simili fra loro)... a 15!

Se non avessimo già estratto il codice dalle note nelle classi compilate, sarebbe stato un bagno di sangue (sia creare le nuove note che, soprattutto, manutenerle). In realtà le note erano già molto piccole e facilmente clonabili senza incorrere in un effort di manutenzione enorme. C’era comunque ancora un po’ di codice, e come detto sopra, alcune piccole differenze di logica (aggancio di callback, setup specifici, ecc.).

A questo punto abbiamo fatto un ultimo passo di refactoring/DRY: abbiamo spostato TUTTO il codice dalle note nelle classi Scala compilate separatamente, inclusi i binding di variabili Angular e gli altri statement che facevano uso delloZeppelinContext(per inciso, questo ha richiesto l'aggiunta di una nuova dipendenza nel nostrobuild.sbt: "org.apache.zeppelin" %% "zeppelin-spark" % "0.6.1").

Finalmente tutto il codice era gestibile via IDE e alla portata dei test unitari, e non abbiamo avuto difficoltà a fare al volo un ulteriore passo di riorganizzazione, portando a fattor comune in una classe astratta tutto il codice invariante fra le diverse note (p.es. il popolamento delle variabili Angular a partire dai valori tornati dal Report), e isolando le differenze in tre sottoclassi concrete:  BasicDashboardNote,  LeakPeriodDashboardNote, e ComparativeDashboardNote:

uml2

Su Zeppelin abbiamo lasciato solo il minimo indispensabile, ovvero due righe essenzialmente uguali in ogni nota:

val projects = z.input("Elenco dei progetti sotto analisi")
new BasicDashboardNote(z, projects)

Nota: i diagrammi sono fatti con i tool di yUML.