Welcome

This is the generic homepage (aka Aggregate Blog) for a Subtext community website. It aggregates posts from every blog installed in this server. To modify this page, look for the Aggregate skin folder in the Skins directory.

To learn more about the application, check out the Subtext Project Website.

Powered By:
Powered by Subtext

Blog Stats

  • Blogs - 714
  • Posts - 31493
  • Articles - 310
  • Comments - 101852
  • Trackbacks - 226411

Bloggers (posts, last update)

Latest Posts

Quei siti che non ti lasciano incollare la password

computer-security-padlock-hacker-163009

Sempre per quella storia della sicurezza. Sapete quella cosa noiosa che in molti la fuori ignorano, pensando stupidamente che sia un dettaglio. Ho un fastidio profondo per quei siti che in fase di registrazione non ti lasciano fare copia incolla della password nel campo conferma password. Credono forse che sia più sicuro impormi di scriverla due volte? no spiegatemi, perché io sinceramente le vostre stupidate non le capisco.

Le mie password sono tipicamente cose del tipo:

*I^%RT FC p97tgn 9ouvb$E%^

Pensate davvero che facendomela scrivere sia più sicura? o cos'altro? Quando vi renderete conto che non fate altro che abbassare i livelli di sicurezza, invogliate gli utenti a scegliere password semplici, perché devono scriverle più volte a mano.

Stendiamo un velo pietoso su quelli che poi non ti lasciano usare caratteri speciali o addirittura non consentono gli spazi.

posted @ 12/11/2017 12:09 PM by Mauro Servienti

C# 7.2 piccole novità: ref on extensions

wood-grain-1498938249NHu

In C# 7 questo non era possibile:

public static class Extensions
{
   public static void Something( ref this ExtendedStruct es)
   {
   }
}

Non era cioè possibile passare ad esempio una struct ad un extension method per reference, pagando quindi pegno se volevamo usare extension method su strutture.

Con C# 7.2 adesso è possibile, ci sono altre novità che riguardano “ref”, forse più interessanti ancora. Novità tutte orientate a tenere sempre più in considerazione le performance.

posted @ 12/6/2017 2:47 PM by Mauro Servienti

Immutabilità o mutabilità, questo è il problema! Vediamo un esempio in Angular.

Durante il porting di Raptor UI, il front-end Angular del nostro framework, abbiamo utilizzato il nuovo HttpClient di Angular, come illustratrato nel post precedente, e ci siamo imbattuti nel problema dell'immutabilità di alcuni nuovi oggetti.

Per chi è interessato, ne parlo qui: http://www.tolist.net/Article/Parlando-di-HttpClient-in-Angular-5-immutabile-o-non-immutabile-questo--il-problema-19

posted @ 12/6/2017 3:17 AM by Michele Aponte

LINQ to DB

https://linq2db.github.io
LINQ to DB is the fastest LINQ database access library offering a simple, light, fast, and type-safe layer between your POCO objects and your database

posted @ 12/4/2017 6:41 PM by Alessandro Gervasoni

C# 7.1 piccole novità: AsyncMain

i-am-waiting

Una delle cose “noiose“ quando si scrive un’applicazione, ad esempio, Console è quando nel metodo Main si deve avere a che fare con codice asincrono, si finisce per scrivere una cosa del tipo:

public void Main(string[] args)
{
   MainAsync(args).GetAwaiter().GetResult();
}

public Task MainAsync(string[] args)
{
   return Task.CompletedTask;
}

che ultimamente si può ulteriormente accorciare in:

public void Main(string[] args) => MainAsync(args).GetAwaiter().GetResult();

public Task MainAsync(string[] args)
{
   return Task.CompletedTask;
}

Usando i nuovi expression-bodied members. Con C# 7.1 si può finalmente eliminare la parte sincrona, limitandosi a scrivere:

public static async Task Main(string[] args)
{
   return Task.CompletedTask;
}

Le funzionalità nuove sono opt-in e devono essere attivate nel file di progetto aggiungendo ad esempio:

<PropertyGroup>
   <LangVersion>latest</LangVersion>
</PropertyGroup>

posted @ 12/4/2017 9:56 AM by Mauro Servienti

Le sette regole d&rsquo;oro della sicurezza nel cloud

imageDurante la sessione “Azure Ninja vs Genio del Male” che io e Vito abbiamo fatto a WPC 2017, abbiamo mostrato come partire da una semplice architettura PaaS con una componente IaaS, attaccarla e migliorarla fino a renderla molto più sicura.

Alla fine della sessione abbiamo presentato le sette regole che abbiamo estratto come lezione:

- Script everything e Backup everything: queste due regole ci servono per riparare i danni dopo che è avvenuto un disastro, o per replicare ambienti per fare prove o altro

- Least user privilege e Trust no one: queste regole servono per minimizzare la superficie di attacco, bloccare tutti gli accessi non necessari, ridurre i permessi al minimo, etc…

- Monitor everything: questa regola è la più semplice da applicare (usando strumenti come Azure Monitor, Application Insight, il Security Center, etc…) e serve per capire cosa succede prima che sia troppo tardi, o comunque per non ripetere gli stessi errori…

- Assume cloud failure: questa regola serve per mettere in atto tutte quelle strategie per gestire casi di non disponibilità di parte della soluzione, per motivi malevoli o semplicemente per problemi al servizio. Nel cloud tutto è accessibile via rete, e quindi va trattato come tale. Non si limita solo a gestire gli errori di connessione, ma ad esempio si possono gestire scenari di connettività limitata con il blob storage salvando in locale i file che gli utenti ci inviano, per poi andarli a processare quando il problema è risolto.

- Protect your secrets: questa in assoluto è la più complessa,soprattutto quando le chiavi di accesso sono distribuite nelle app o in dispositivi IoT.

posted @ 12/1/2017 2:00 PM by Lorenzo Barbieri

Non c&rsquo;&egrave; scritto da nessuna parte che i messaggi vengano consegnati o processati

pexels-photo-292426

Abbiamo già detto che esiste solo oneway-messaging e che exactly-once delivery è una chimera, per continuare la mia carrellata di buoni motivi per non impelagarsi in un sistema distribuito oggi vorrei introdurvi al magico mondo delle poison queue.

Quando un messaggio viene inviato possono succedere le seguenti cose:

  • L’infrastruttura non riesce a consegnarlo alla coda di destinazione
  • Il messaggio arriva alla coda di destinazione malformed
  • Il destinatario riceve il messaggio ma fallisce nel processarlo

Come più volte ho ribadito in un sistema basato su messaggi la perdita di un messaggio porta all’inevitabile corruzione dei dati, ergo perdere un messaggio è cosa quantomeno poco simpatica.

Nei primi due casi di cui sopra l’infrastruttura di solito ci viene in aiuto con il concetto (quasi sempre) built-in di poison queue. Quello che succede è che è possibile definire una coda da usarsi come parcheggio per i messaggi che non possono essere consegnati o che sono malformed.

Il terzo caso è un po’ al limite, tecnicamente il messaggio è buono ed è stato pure consegnato, ma il destinatario fallisce nel processarlo, per colpa, ad esempio, di un bug viene sollevata un’eccezione. Ne consegue che il messaggio resta in coda, in testa alla coda, con il rischio quindi che venga riprocessato, e riprocessato, e riprocessato, e riprocessato, all’infinto. Causando una sorta di denial of service al destinatario per colpa del destinatario. In base all’infrastruttura anche un messaggio malformed potrebbe portare allo stesso identico scenario.

In questo terzo caso avete quindi bisogno che il vostro codice sia in grado di dire all’infrastruttura: basta, non farmelo più vedere e spostalo in una poison queue.

Ovviamente ci ritroviamo in uno scenario interessante:

  • Il mittente ha mandato un messaggio, e come abbiamo detto non ha alcuna possibilità di sapere come stanno le cose
  • Il destinatario non l’ha mai ricevuto o l’ha ricevuto e ha fallito nel processarlo
  • Il messaggio sta bello bello, buono buono, in una poison queue

Abbiamo quindi bisogno di fare monitoraggio delle poison queue, di capire perché i messaggi sono finiti li, e infine ove servisse di riprovare a consegnare i messaggi.

posted @ 12/1/2017 10:19 AM by Mauro Servienti

L&rsquo;infrastruttura di Azure App Service verr&agrave; aggiornata a Windows Server 2016 nei prossimi giorni

Ieri è arrivata la mail a tutti quelli che hanno applicazioni su Azure App Service, Azure Functions, Web Apps, etc… avvisandoli che a partire da lunedì prossimo l’infrastruttura sottostante verrà aggiornata a Windows Server 2016, con notevoli miglioramenti, come ad esempio il supporto di HTTP/2.

La parte importante della mail è questa:

Recommended actions
  • Test your app in your local environment if you are working in Windows Server 2016.
  • Test your app in any Windows 10 environment because Windows shares many components with Windows Server 2016.

Se le vostre app dovessero avere problemi, potete aprire un ticket al supporto.

Attenzione, la migrazione richiede il riavvio dell’app!

posted @ 12/1/2017 9:11 AM by Lorenzo Barbieri

Una piccola idea per un progetto&hellip;

Visto che come mostrato chiaramente da Guy Kawasaki, i post su LinkedIn (e probabilmente anche Facebook) ricevono più visibilità se non contengono il link all’interno del post ma solo dei commenti, mi è venuta un’idea Smile

Visto che servizi come http://dlvr.it (che uso anch’io…) non consentono di farlo in maniera automatica, potrei fare una Azure Function che, triggerata da un timer, legge il feed RSS e posta in modo oppurtuno su Facebook e Linkedin, prima il contenuto e poi un commento col link al post originale.

Chissà se troverò mai il tempo, o se qualcuno mi suggerirà prima un servizio che già lo fa Smile

p.s. non tutti credono che le conclusioni di Guy siano applicabili a tutti i “normali” Smile

posted @ 12/1/2017 12:38 AM by Lorenzo Barbieri

Exactly-once delivery &egrave; una chimera

oct_12_2003_delivery

Abbiamo già spiegato perché esiste solo one-way messaging, oggi cerchiamo di sfatare un secondo mito: exactly-once delivery. Che altro non è che l’aspettativa che un messaggio sia sempre consegnato una ed una sola volta.

È possibile?

Si, in un solo scenario:

un trasporto transazionale con il supporto per il DTC in combinazione con un processo di gestione del messaggio che è in grado di fare enlistment nella transazione distribuita.

Quindi se avete MSMQ con le code transazionali, tutto quello che fate quando processate il messaggio è lavorare ad esempio con un database su SQL Server, e infine decidete di accettare di pagare l’obolo del DTC, ecco, siete in grado di gestire il seguente scenario:

  • Il messaggio è in coda
  • Il processo client lo scoda iniziando una transazione con la coda
  • La fase di processamento scrive dei dati su un database transazionale
  • Il processo client committa la transazione
    • Il messaggio viene cancellato dalla coda come processato
    • I dati sono nel DB
  • Qualsiasi cosa vada storta il processo client fa rollback della transazione ed è come se nulla fosse successo

Ovvio che se invece di parlare con un database transazionale stessimo parlando con un endpoint HTTP c’è poco da fare rollback, il messaggio verrebbe riprovato e la chiamata HTTP rifatta. Prima di affrontare questo secondo problema vediamo cosa succede con un trasporto che non va a braccetto con il DTC.

Amazon SQS: at-least-once delivery semantics

Dal punto di vista infrastrutturale Amazon SQS è un broker, internamente per garantire affidabilità e scalabilità l’infrastruttura è basata su repliche master-master, questo significa che una coda X è replicata su più nodi.

Vediamo cosa succederebbe con MSMQ in uno scenario simile: cluster.

  • 4 macchine con MSMQ
  • Windows Network Load Balancing tools per definire il cluster
  • I mittenti vedono una sola coda, quella del cluster
  • Quando un messaggio arriva in realtà arrivano 4 messaggi identici nelle code locali di ognuna delle 4 macchine
  • Inizia una transazione distribuita che porta al consenso su chi processerà il messaggio effettivamente
  • Come potete immaginare, o sapere se avete nozione degli internals del DTC, all’aumentare delle risorse coinvolte nella 2 phase commit diminuiscono le prestazioni. Cioè il tempo impegnato per garantire exactly-once delivery cresce al crescere della richiesta di affidabilità e anche di scalabilità, che è un controsenso: voglio più potenza di fuoco ma la più potenza inficia la potenza di fuoco stessa.

I vendor quindi scappano a gambe levate dal DTC verso il concetto di visibility timeout (ce ne sono svariate implementazioni), il che vuol dire che nell’esempio di cui sopra il dialogo è più o meno il seguente:

  • 4 macchine con i nodi della coda di nostra scelta, ad esempio SQS
  • tools per definire il cluster
  • I mittenti vedono una sola coda, quella del cluster
  • Quando un messaggio arriva la struttura master-master fa si che arrivino 4 messaggi identici nelle code locali di ognuna delle 4 macchine
  • A questo punto una delle 4 dice: preso, è mio per i prossimi x secondi
  • L’infrastruttura master-master propaga questa informazione al cluster e gli altri 3 stanno li buoni buoni nascondendo il messaggio agli eventuali client

Adesso fate scale-out anche dei client, introducendo il così detto modello competing consumers. Quindi 2 client identici, su due nodi diversi, che guardano la stessa coda di input.

Va tutto bene fintantoché…Il carico è moderato, ooops

Al crescere del carico, numero di messaggi ricevuti per secondo, quello che può facilmente succedere è che questo:

  • A questo punto una delle 4 dice: preso, è mio per i prossimi x secondi
  • L’infrastruttura master-master propaga questa informazione al cluster e gli altri 3 stanno li buoni buoni nascondendo il messaggio agli eventuali client

Non si propaghi abbastanza velocemente e se due dei client di cui sopra per sbaglio stanno guardando due nodi diversi (shard) del cluster ecco che entrambi cominciano tranquillamente a processare lo stesso identico messaggio. At-least-once delivery servita su un piatto d’argento.

Nel frattempo dietro le quinte il visibility timeout si è propagato, quindi il nodo che per ultimo darà l’ACK al cluster confermando di aver processato il messaggio riceverà un errore e avrà la possibilità di fare rollback, sempre che possa ovviamente.

Ho usato SQS come esempio perché è quello dove è più facile che il problema si presenti, Azure ServiceBus è anch’esso at-least-once ma i namespace riducono lo scope, facendovi vedere solo un sottoinsieme del cluster riducendo l’impatto del problema, ma introducendo altri problemi che non sono oggetto di questo post.

Dobbiamo preoccuparci?

Neanche per sogno, dobbiamo però sapere bene che come un messaggio potrebbe non essere mai processato allo stesso modo potrebbe essere processato più volte.

Il nostro sistema deve essere ben conscio di tutto ciò e deve accettare che exactly-once delivery non scala o addirittura è impossibile. Ha quindi molto più senso fregarsene e spostare la nostra attenzione su exactly-once processing.

Alla prossima.

posted @ 11/29/2017 12:29 PM by Mauro Servienti

Dapper - a simple object mapper for .Net

posted @ 11/28/2017 3:14 PM by Alessandro Gervasoni

peachpie


Open-Source PHP Compiler to .NET
https://www.peachpie.io

posted @ 11/27/2017 10:35 PM by Alessandro Gervasoni

Angular 5 HttpClient e Interceptor

In azienda abbiamo da poco fatto il porting per il nostro frameowrk (Raptor) da Angular 4 a 5 e ne abbiamo approfittato per fare un po' di refactoring e cominciare a usare gli Interceptor per centralizzare alcune gestioni che facciamo.

Se a qualcuno può interessare ne parlo qui: http://tolist.net/Article/Il-nuovo-HttpClient-in-Angular-5-18

Ne parlerò anche domani a WPC 2017, durante la mia sessione proprio su come abbiamo realizzato il framework: http://www.wpc2017.it/cms/it-IT/SpeakerPage?parameters%5B0%5D=67

Per chi sarà a WPC ci vediamo stasera/domani.

posted @ 11/27/2017 8:16 PM by Michele Aponte

Perch&eacute; esiste solo one-way messaging

q

Prima di addentrarci e scoprire cosa possiamo fare con una coda e ovviamente dei messaggi, cerchiamo di dare una risposta definitiva al perché “two-way messaging” non abbia senso, e quindi esista solo “one-way messaging”. Quando si parla di code abbiamo due macro tipologie di architetture:

  • store & forward
  • broker

Un ottimo esempio di store & forward, e pure l’unico che a quest’ora di mattina mi viene in mente, è MSMQ. Per mandare un messaggio da A a B:

  • A manda un messaggio alla sua coda locale di uscita, la coda locale è sulla stessa macchina su cui vive A
  • la coda locale di uscita quando avrà connettività cercherà di mandare il messaggio alla coda di input di B sulla macchina remota
    • Se l’invio fallisce il messaggio viene spostato in una dead-letter queue
    • Se l’invio non avviene entro il timeout prestabilito, concettualmente è come se avesse fallito, di nuovo dead-letter queue

Nel caso dei broker, ad esempio RabbitMQ, quello che succede è:

  • A manda un messaggio al broker chiedendo di consegnare il messaggio a B
    • Se non c’è connettività con il broker A scoppia immediatamente
  • Il broker, supponendo la configurazione più restrittiva possibile:
    • Manda un ACK ad A confermando la ricezione del messaggio
    • Informa anche A che la destinazione esiste, quindi la coda di B è effettivamente cosa nota
  • A seconda della tipologia di clustering del broker stesso non è detto che la coda di B sia effettivamente raggiungibile

Dal punto di vista dell’infrastruttura, se osservate i dialoghi di cui sopra, come mittenti il meglio che possiate ottenere è: il messaggio che ho inviato è stato consegnato nella coda del destinatario, oppure la consegna è fallita. In nessun modo avete possibilità di sapere se il messaggio sia stato processato con successo o se nel momento in cui è stato processato vi sia stato un errore, perché per l’infrastruttura questa informazione può essere consegnata solo con un altro messaggio, e quindi siamo di nuovo al problema dei due generali. Come abbiamo già detto l’unico modo che avreste è tenere in piedi una transazione distribuita tra tutte le parti coinvolte, ma è un ossimoro, perché introduciamo code proprio perché vogliamo rendere indipendenti mittente e destinatario.

Le implicazioni di questo “piccolo” dettaglio sono importanti, prima su tutte è l’impatto che il non poter avere certezza che una richiesta sia stata processata ha su come viene disegnato un sistema. Ecco quindi spiegato perché quando si parla di sistemi distribuiti si parla di “design for failure”.

Ricordatevi sempre che la prima regola di un sistema distribuito è: non è vero che avete bisogno di un sistema distribuito ;-)

posted @ 11/27/2017 7:01 AM by Mauro Servienti

The Cost of Javascript

posted @ 11/24/2017 11:31 AM by Alessandro Gervasoni

Angular, NodeJS e Typescript insieme

Se dovete realizzare una applicazione Angular con NodeJs e Typescript per il backend il mio nuovo post potrebbe esservi utile: http://www.tolist.net/Article/Angular-NodeJS-e-Typescript-insieme-17

posted @ 11/22/2017 11:45 PM by Michele Aponte

&ldquo;wanna be architect&rdquo;

image

Settimana scorsa a Torino, durante una delle pause, un ragazzo mi chiede: come faccio a diventare un architetto? La domanda credo nascesse dal fatto che sulle mie slide c’è scritto “Solution Architecth @ Particular Software”. La mia risposta è stata molto semplice: a suon di schiaffoni :-)

In tutta sincerità sul mio biglietto da visita c’è scritto Solution Architect, ma la bio interna inizia così:

image

Non credo che un professionista possa mai dire di avere abbastanza esperienza per definirsi un Solution Architect. Semplicemente per il motivo che ogni soluzione e l’architettura che l’accompagna sono talmente dipendenti dal contesto che avremo sempre qualcosa che non abbiamo mai sperimentato prima. Un problema nuovo che ci coglie totalmente impreparati.

Gli schiaffoni, derivanti dai progetti falliti o non proprio delle perfette ciambelle col buco, sono la cosa che ci fa crescere e accumulare esperienza, esperienza che si può spendere, con tanta umiltà, su queli problemi ignoti di cui sopra.

L’esperienza non si insegna con un corso, e per fare esperienza ci vuole tempo, quindi la vedo dura essere Solution Architect a 25 anni, ma non cercherei neanche di aspettarmi da un neo laureato che abbia nozioni, esperienza e calli a sufficienza.

Quindi:

come faccio a diventare un architetto?

  • sperimentando, fallendo e imparando dai propri errori
  • mettendosi in gioco e confrontandosi con gli altri
  • ovviamente studiando
  • senza fretta soprattutto, spendersi troppo presto può essere controproducente

Piccolo spazio pubblicità: 5 giorni con Udi aiutano, ma non sono la base di partenza, piuttosto un check-point da fare lungo la strada.

posted @ 11/22/2017 12:17 PM by Mauro Servienti

An application built on traditional .Net framework is not a legacy application


Se seguite i vari blog MS avrete notato che sull'argomento .Net Core e full .Net Framewotk spesso citano/abusano il termine "legacy application" per fare riferimento alle applicazioni basate sul .Net Framework.

Il loro obiettivo, alla fine dei conti, è spingere sempre più Dev all'adozione del nuovo nato .Net Core parlando per le esistenti (legacy?) applicazioni di porting da un framework all'altro.

Ecco quindi la doverosa precisazione di Cesar de la Torre in occasione del post relativo all'aggiornamento del libro "Microservices and Docker containers: Architecture, Patterns and Development guidance (Updated for .NET Core 2.0)"

"Legacy applications based on the traditional .NET Framework” literally means legacy apps (apps that have a significant time since they were built) that are based (were built) using the traditional .NET Framework. On the contrary, we are not saying, at all, that any new application built on the traditional .NET Framework is a legacy application.

Fonte: Microservices and docker containers architecture patterns and development guidance

posted @ 11/20/2017 5:05 PM by Tommaso Caldarola

Il coach ha sempre torto

swimmer-1678307_1920

Nuoto, da ragazzino nuotavo. Sono anche bradicardico, a 44 anni ho ancora 46/48 battiti a riposo a volte anche meno. Ne consegue che la mia specialità è sempre stata il fondo. Quindi 800, 1500 o oggi le tipiche distanze da triathlon o di più. Da ragazzino avevo un difetto, sulle lunghe distanze a stile libero nelle ultime vasche tendevo a smettere di fare la classica virata con capriola (flip turn) in favore della virata tradizionale. L’allenatore del tempo sosteneva che fosse solo ed esclusivamente una questione di paura, l’aspetto psicologico prendeva il sopravvento e verso la fine tendevo ad evitare le cose rognose. Peccato che il personaggio insistesse nel sottolineare che io avessi paura. Lui era il coach, quello che sapeva, quindi aveva per forza ragione.

Peccato che non capisse un cazzo, ma io non avevo a quell'età nessuna base per comprendere che il problema fosse lui.

Una delle cose fondamentali nel nuoto è la respirazione, lo è in tutti gli sport ovviamente, ma nel nuoto c’è il dettaglio che non respiri quando decidi tu, ma solo quando hai la testa fuori. La respirazione è quindi influenzata dal ritmo della bracciata. Quando la tecnica è buona il tempo in cui mezza faccia è fuori dall'acqua per respirare è tipicamente pochissimo. Questo fa si che nel nuoto la respirazione è si importante ma l'espirazione è fondamentale.

Se si espira male, leggasi non a fondo, si accumula CO2 nei polmoni, nel tempo che la mezza faccia sta fuori l'aria che si è in grado di immettere si riduce perché i polmoni non sono abbastanza vuoti, debito di ossigeno –> iperventilazione –> dispnea. Ovvio che iperventilare mentre si nuota non è molto fattibile, ergo dopo qualche vasca la virata con capriola diventa una rogna perché il tempo di apnea è decisamente superiore a quello della bracciata.

Il segreto è semplice: espirare con tutta la forza possibile prima di tirare fuori la testa per respirare, fine de giochi. Semplice ed efficace. E quello era uno stronzo.

Quindi? direte voi…

Il succo della questione è che fare il coach o il mentor è un lavoro difficile, molto difficile. Ogni volta che vostro allievo o mentee non ci viene dietro la prima cosa da fare è mettere in discussione noi stessi in quanto coach o mentor. Analizzando il nostro comportamento alla ricerca di falle ed errori.

BTW, nuotare è un ottimo modo per meditare.

posted @ 11/20/2017 12:20 PM by Mauro Servienti

Microsoft/sqlopsstudio

SQL Operations Studio is a data management tool that enables working with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux.

https://github.com/Microsoft/sqlopsstudio

posted @ 11/17/2017 4:42 PM by Alessandro Gervasoni

Latest Images

From miscellaneous
From miscellaneous
From miscellaneous
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini
From Immagini