SlideShare ist ein Scribd-Unternehmen logo
1 von 37
Downloaden Sie, um offline zu lesen
Flow: viaggio nel futuro con un
        caso realizzato
              Tarcisio Fedrizzi
           16-17 Novembre 2012
                  Bologna
Federazione provinciale Scuole
              materne di Trento
    ✗   Associazione di 135 scuole materne
    ✗   21 circoli
    ✗   Quasi 1500 maestre




17 Novembre 2012     Tarcisio Fedrizzi - T3Camp Bologna   2/37
Outline
    ✗   Presentazione                                  ✗    Fluid Standalone
    ✗   Il progetto                               ✗   Considerazioni su
                                                      Flow
         ✗   Dominio
         ✗   Tecnologie
                                                  ✗   Conclusioni
    ✗   POSIT.MethodLogger                        ✗   Domande
         ✗   Annotazioni
         ✗   AOP


17 Novembre 2012       Tarcisio Fedrizzi - T3Camp Bologna          3/37
Presentazione
                                              ✗   Progettazione e
                                                  sviluppo applicazioni
                                                  ad-hoc
                                              ✗   Primo progetto
                                                  basato su
    ✗   Libero professionista
                                                  TYPO3.Flow messo in
        dal 2005
                                                  produzione
    ✗   Socio di POSIT dal
        2009

17 Novembre 2012   Tarcisio Fedrizzi - T3Camp Bologna      4/37
210ore: tecnologie 1/2
    ✗   Server: TYPO3.Flow
    ✗   Client:
        ✗   Insegnanti: ExtJS 4
            (è stato
            necessario rendere
            l'interfaccia
            più fedele possibile
            a quella del client
            windows usato
            in precedenza)


17 Novembre 2012       Tarcisio Fedrizzi - T3Camp Bologna   5/37
210ore: tecnologie 2/2
         ✗   Gestori:
             TYPO3.Fluid +
             JQuery DataTable
         ✗   Amministratori:
             TYPO3.Expose
             oppure
             TYPO3.Fluid
             (ancora in
             fase di sviluppo)



17 Novembre 2012      Tarcisio Fedrizzi - T3Camp Bologna   6/37
Il modulo POSIT.MethodLogger
    ✗   Estratto dal progetto 210ore
    ✗   Permette di loggare chiamate a qualsiasi
        metodo
    ✗   È possibile accedere ai parametri della
        chiamata
    ✗   Permette di vedere alcuni aspetti del
        framework Flow in azione


17 Novembre 2012   Tarcisio Fedrizzi - T3Camp Bologna   7/37
Annotazioni 1/2
        Elementi che permettono di “appiccicare” dei
        dati descrittivi (metadati) a classi, metodi e
        interfacce
    ✗   In alcuni linguaggi (es. Java) sono un costrutto
        che fa parte del linguaggio
    ✗   In altri, tra cui PHP, non sono ancora
        disponibili nativamente e vengono quindi
        specificate nei commenti.


17 Novembre 2012   Tarcisio Fedrizzi - T3Camp Bologna   8/37
Annotazioni 2/2
    ✗   Flow ne fa un uso piuttosto consistente. Ad
        esempio:
            ...
            use TYPO3FlowAnnotations as Flow;
            ...
            /**
             * @FlowEntity
             */
            class MethodLog {
            ...


        nelle definizioni delle Entità.


17 Novembre 2012       Tarcisio Fedrizzi - T3Camp Bologna   9/37
Definizione Annotazioni
    ✗   Semplice classe che                       ...
                                                  * @Annotation
                                                  * @Target("METHOD")
        contiene i parametri                      */
                                                 final class LogMethod {
        passati dove                               /**
                                                    * @var string
        l'annotazione è                             */
                                                   public $message;
        specificata;                              ...

                                                 ...
    ✗   I parametri sono                         class PostController {
                                                   /**
        passati al costruttore                       * @POSITLogMethod(
                                                     *    message="Creato post.")
        dell'annotazione in un                       */
                                                     public function createAction(
        unico array.                             ...




17 Novembre 2012      Tarcisio Fedrizzi - T3Camp Bologna           10/37
AOP 1/2
        Ideata da Gregor Kiczales e altri di Xerox
        PARC
    ✗   Permette di mantenere una netta separazione
        tra logica di business e funzionalità non
        specifiche dell'applicazione
    ✗   Queste funzionalità vengono aggiunte con un
        sistema che si basa su tre concetti



17 Novembre 2012   Tarcisio Fedrizzi - T3Camp Bologna   11/37
AOP 2/2
    ✗   I concetti sono i seguenti:
         ✗   Advice: definisce la funzionalità che dev'essere
             aggiunta (Logging, controlli di accesso, ecc);
         ✗   Pointcut: permette di specificare in quali punti la
             funzionalità dev'essere eseguita (prima di
             chiamare un metodo, quando viene lanciata
             un'eccezione, ecc);
         ✗   Join point: descrive il contesto presente nel
             punto in cui è stata sospesa l'esecuzione.


17 Novembre 2012       Tarcisio Fedrizzi - T3Camp Bologna   12/37
AOP in Flow: Aspect
    ✗   L'aspetto in Flow è una classe annotata con
        @FlowAspect.
    ✗   La classe deve inoltre definire un Advice o un Pointcut
        per essere un aspetto considerato valido.

    ...
    /**
     * @FlowAspect
     */
    class LogMethodAspect {
      /**
        * @FlowAround(
        *   "POSITMethodLoggerAspectLogMethodAspect->methodsAnnotatedWithLogMethod")
        */
      public function runMethodLogging(TYPO3FlowAopJoinPointInterface $joinPoint){
    ...




17 Novembre 2012            Tarcisio Fedrizzi - T3Camp Bologna          13/37
AOP in Flow: Pointcut
    ✗   Flow offre diversi designatori di pointcut:
        method, class, ecc...
    ✗   Essi permettono di selezionare i metodi ai
        quali dev'essere applicato un advice
    ...
    /**
     * @FlowPointcut(
     *   "methodAnnotatedWith(
     *      POSITMethodLoggerAnnotationsLogMethod)")
     */
     public function methodsAnnotatedWithLogMethod() {}
    ...



17 Novembre 2012     Tarcisio Fedrizzi - T3Camp Bologna   14/37
AOP in Flow: Advice
    ✗   L'advice è il metodo che viene eseguito quando vengono
        chiamati i metodi selezionati con il pointcut;
    ✗   Esso viene eseguito secondo le indicazioni
        dall'annotazione che decora il metodo;

        ...
        /**
          * @FlowAround(
          *    "POSITMethodLoggerAspectLogMethodAspect->methodsAnnotatedWithLogMethod")
          */
        public function runMethodLogging(TYPO3FlowAopJoinPointInterface $joinPoint){
            $logMethod = $this->getLogMethodAnnotation($joinPoint);
            $this->logMessage($joinPoint, $logMethod);
            return $joinPoint->getAdviceChain()->proceed($joinPoint);
        }
        ...




17 Novembre 2012              Tarcisio Fedrizzi - T3Camp Bologna          15/37
AOP in Flow: Join point
    ✗   Il join point permette di accedere al contesto e alla descrizione del
        metodo al quale è applicato l'advice;
    ✗   tramite il join point è possibile conoscere il nome del metodo, i
        parametri che sono stati passati, ecc


    ...
    $i               = 0;
    $className       = $joinPoint->getClassName();
    $methodName      = $joinPoint->getMethodName();
    $methodArguments = $joinPoint->getMethodArguments();
    print("$className->$methodName(");
    foreach ($methodArguments as $argumentName => $argumentValue) {
      if ($i++ > 0) { print(", "); }
      print("$argumentName = $argumentValue");
    }
    print(");n");
    ...




17 Novembre 2012              Tarcisio Fedrizzi - T3Camp Bologna      16/37
Fluid standalone 1/2
    ✗   È possibile utilizzare il motore di templating anche in
        maniera standalone
    ✗   Questo ci permette di riutilizzare la sintassi di fluid
        anche in contesti differenti rispetto a quello delle pagine
        web
    private function renderViewText(TYPO3FlowAopJoinPointInterface $joinPoint
                                     $text) {
      $textView = new TYPO3FluidViewStandaloneView();
      $textView->initializeObject();
      $textView->setTemplateSource($text);
      foreach ($joinPoint->getMethodArguments() as $name => $value) {
        $textView->assign($name, $value);
      }
      return $textView->render();
    }




17 Novembre 2012         Tarcisio Fedrizzi - T3Camp Bologna      17/37
Fluid standalone 2/2
    ✗   L'utilizzo del metodo definito nella slide
        precedente ci permette quindi di accedere ai
        parametri del metodo loggato all'interno del
        messaggio di log
    ...
    /**
     * @POSITLogMethod(message="{newPost.author} ha creato il nuovo
     *                            post intitolato {newPost.title}.")
     */
     public function createAction(
                TYPO3BlogDomainModelPost $newPost) {
    ...



17 Novembre 2012     Tarcisio Fedrizzi - T3Camp Bologna   18/37
Considerazioni su Flow 1/9
    ✗   Dal punto di vista tecnologico offre molte possibilità
        (AOP, annotazioni, slot e segnali)
        ✗   c'è tutto quello che (e anche di più) può servire per lo
            sviluppo web
    ✗   È in generale semplice aggiungere e/o modificare le
        funzionalità offerte dal framework
        ✗   Si tratta in genere di ereditare da una classe e di
            implementare un'interfaccia definendo pochi metodi
            (molte volte è sufficiente uno)



17 Novembre 2012        Tarcisio Fedrizzi - T3Camp Bologna   19/37
Considerazioni su Flow 2/9
    ✗   Il sistema di controllo degli accessi è molto
        flessibile
        ✗   Permette di specificare anche condizioni
            complesse modificando soltanto i file di
            configurazione
    ✗   Il sistema di mapping dei parametri della
        richiesta sui parametri del metodo dell'azione
        chiamata nel controller permette di
        mantenere la logica di business molto pulita

17 Novembre 2012     Tarcisio Fedrizzi - T3Camp Bologna   20/37
Considerazioni su Flow 3/9
    ✗   Configurabilità da file
    ✗   Semplice aggiungere la configurazione anche
        per i propri moduli
    ✗   L'interfaccia a linea di comando
    ✗   Semplice aggiungere comandi per i propri
        moduli




17 Novembre 2012   Tarcisio Fedrizzi - T3Camp Bologna   21/37
Considerazioni su Flow 4/9
    ✗   Problema maggiore riguarda l'usabilità:
        ✗   Punti fondamentali per lo sviluppo
            di un progetto reale non sono
            documentati. Ad esempio:
             ✗   Logging e debugging
             ✗   Deployment e amministrazione
        ✗   L'applicazione di esempio TYPO3.Blog copre alcune
            casistiche ma non offre un esempio esaustivo
        ✗   Gli esempi che ci sono nella documentazione sono utili
            ma anche in questo caso non esaustivi


17 Novembre 2012          Tarcisio Fedrizzi - T3Camp Bologna   22/37
Considerazioni su Flow 5/9
         ✗   In molti casi è difficile capire dov'è o a quale
             elemento si riferisce un errore




         ✗   Non c'è menzione a qualche cosa che mi possa
             aiutare a trovare il soggetto dell'errore


17 Novembre 2012       Tarcisio Fedrizzi - T3Camp Bologna   23/37
Considerazioni su Flow 6/9
           ✗    E lo stacktrace dell'eccezione scritto su file non
                offre maggiori informazioni
    Uncaught exception #1222268609 in line 146 of
     Data/Temporary/Development/Cache/Code/FLOW3_Object_Classes/TYPO3_FLOW3_Security_Authorization_AccessDecisionVoterManager. Php:
       Access denied (1 denied, 0 granted, 0 abstained)


    22 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager_Original::decideOnJoinPoint(TYPO3FLOW3AopJoinPoint)
    21 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager::decideOnJoinPoint(TYPO3FLOW3AopJoinPoint)
    20 call_user_func_array(array, array)
    19 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager::FLOW3_Aop_Proxy_invokeJoinPoint(TYPO3FLOW3AopJoinPoint)
    18 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager::decideOnJoinPoint(TYPO3FLOW3AopJoinPoint)
    17 TYPO3FLOW3SecurityAuthorizationInterceptorPolicyEnforcement_Original::invoke()
    16 TYPO3FLOW3SecurityAspectPolicyEnforcementAspect_Original::enforcePolicy(TYPO3FLOW3AopJoinPoint)
    15 TYPO3FLOW3AopAdviceAroundAdvice::invoke(TYPO3FLOW3AopJoinPoint)
    14 TYPO3FLOW3AopAdviceAdviceChain::proceed(TYPO3FLOW3AopJoinPoint)
    13 POSITDuecentodieciOreControllerDomainAccountingAnnualEstimateController::initializeAction()
    12 TYPO3FLOW3MvcControllerActionController_Original::processRequest(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse)
    11 TYPO3FLOW3MvcDispatcher_Original::dispatch(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse)
    10 TYPO3FLOW3MvcDispatcher::dispatch(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse)
    9 call_user_func_array(array, array)
    8 TYPO3FLOW3MvcDispatcher::FLOW3_Aop_Proxy_invokeJoinPoint(TYPO3FLOW3AopJoinPoint)
    7 TYPO3FLOW3AopAdviceAdviceChain::proceed(TYPO3FLOW3AopJoinPoint)
    6 TYPO3FLOW3SecurityAspectRequestDispatchingAspect_Original::blockIllegalRequestsAndForwardToAuthenticationEntryPoints(
                                                                      TYPO3FLOW3AopJoinPoin t)
    5 TYPO3FLOW3AopAdviceAroundAdvice::invoke(TYPO3FLOW3AopJoinPoint)
    4 TYPO3FLOW3AopAdviceAdviceChain::proceed(TYPO3FLOW3AopJoinPoint)
    3 TYPO3FLOW3MvcDispatcher::dispatch(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse)
    2 TYPO3FLOW3HttpRequestHandler::handleRequest()
    1 TYPO3FLOW3CoreBootstrap::run()




17 Novembre 2012                         Tarcisio Fedrizzi - T3Camp Bologna                                  24/37
Considerazioni su Flow 7/9
         ✗   Spesso errori nel progetto (per esempio derivanti
             da elaborazione del codice del progetto da parte
             del framework, configurazioni errate all'interno
             del progetto) producono stacktrace e messaggi in
             cui non appare niente che riguarda il progetto.
             Questo rende quindi molto difficile e pesante
             comprendere qual'è il problema.




17 Novembre 2012      Tarcisio Fedrizzi - T3Camp Bologna   25/37
Considerazioni su Flow 8/9
    ✗   Assenza di utility per rendere lo sviluppo più
        comodo e rapido
        ✗   Mi sarei aspettato di trovare nella distribuzione
            base:
             ✗     Un'interfaccia web per il debugging (area che posso
                   consultare per leggere i log, profiling, ecc)
                    ✗   Vedi Debug.Toolbar (debug), Plumber (profiling)
             ✗     Un'interfaccia grafica per una gestione di base degli
                   oggetti definiti nel progetto
                    ✗   Vedi TYPO3.Expose



17 Novembre 2012              Tarcisio Fedrizzi - T3Camp Bologna   26/37
Considerazioni su Flow 9/9
                   ✗   Un interfaccia CRUD che mi permetta di gestire gli oggetti nel
                       database senza dover scrivere sempre lo stesso codice.
    ✗   L'usabilità è troppe volte posta come un
        elemento a bassa priorità. È invece molto
        importante dato che la sua carenza:
         ✗   costituisce una barriera per l'adozione da parte di
             nuovi utenti
         ✗   rende frustranti operazioni che dovrebbero
             essere semplici


17 Novembre 2012             Tarcisio Fedrizzi - T3Camp Bologna   27/37
Conclusione
    ✗   TYPO3.Flow è un framework completo che offre tutti gli strumenti per creare le più
        disparate applicazioni web
    ✗   Offre una base ricca e solida su cui costruire i propri progetti
    ✗   Ancora molto dev'essere fatto sul fronte dell'usabilità perché:
        ✗   non tutti se la sentono di mettere il naso nel codice del framework per fare il debug della
            propria applicazione
        ✗   un framework che si pone come obiettivo di ...“far tornare la gioia di sviluppare.”...
            dovrebbe rendere veloci e semplici quelle operazioni noiose e ripetitive che fanno parte di
            ogni progetto
    ✗   Per evitare che il progetto rimanga nel limbo è necessario cominciare ad utilizzare,
        e quindi testare, il framework in ambienti reali. Soltanto così è possibile verificare
        quali aspetti vanno migliorati, capire cosa sarebbe comodo avere e, riportandolo
        agli sviluppatori oppure contribuendo noi stessi, migliorare il framework fino a
        renderlo lo strumento più adatto alle nostre esigenze.




17 Novembre 2012                 Tarcisio Fedrizzi - T3Camp Bologna              28/37
Grazie per l'attenzione
    ✗   Il codice dell'esempio mostrato nella presentazione è
        disponibile all'url:
        ✗   https://github.com/posit-it/POSIT.MethodLogger
            ✗   L'esempio gira su Flow 2.0 (ex FLOW3 1.2)
    ✗   Altri pacchetti menzionati nella presentazione:
        ✗   Plumber:
            ✗   https://github.com/sandstorm/Plumber
        ✗   Debug.Toolbar:
            ✗   https://github.com/mneuhaus/Debug.Toolbar/
        ✗   TYPO3.Expose:
            ✗   http://git.typo3.org/FLOW3/Packages/TYPO3.Expose.git



17 Novembre 2012             Tarcisio Fedrizzi - T3Camp Bologna    29/37
Persistenza
    ✗   In Flow la persistenza dei dati è gestita
        tramite un livello di astrazione
    ✗   Flow si basa sulla programmazione orientata
        agli oggetti. Questo implica che in flow la
        “base dati” è costituita dalla definizione di una
        serie di oggetti collegati tra loro.
    ✗   Dietro le quinte il framework si occupa di
        mappare gli oggetti da e verso il database


17 Novembre 2012   Tarcisio Fedrizzi - T3Camp Bologna   30/37
Persistenza: Doctrine
    ✗   Flow supporta diversi metodi di persistenza
        tuttavia quello maggiormente integrato è
        Doctrine.
    ✗   Doctrine (la versione 2 è quella integrata in
        FLOW) è un Object Relational Mapping
        Software. Questo genera, a partire dalla
        descrizione dei dati e dalle azioni che noi
        facciamo sui dati stessi, le query che
        aggiornano i dati nel database.

17 Novembre 2012     Tarcisio Fedrizzi - T3Camp Bologna   31/37
Persistenza: entità
    ✗   Per poter mappare gli oggetti su database è
        necessario decorare gli oggetti con alcune
        annotazioni. Queste permettono all'ORM di
        raccogliere le informazioni necessarie a generare lo
        schema.
    ...
     * @FlowEntity
     */
    class MethodLog {
    ...
      /**
       * L'indirizzo del client che ha causato l'invocazione del metodo loggato.
       * @var string
       * @ORMColumn(length=15, nullable=true)
       */
      protected $ip;
    ...




17 Novembre 2012              Tarcisio Fedrizzi - T3Camp Bologna              32/37
Gestione degli oggetti
    ✗   In Flow il cliclo di vita degli oggetti è gestito
        automaticamente dal framework
    ✗   La gestione degli oggetti viene quindi affidata
        ad una classe chiamata ObjectManager
    ✗   Ad ogni classe è associato quello che è
        definito scope. Questo determina il modo in
        cui viene gestito il ciclo di vita dell'oggetto



17 Novembre 2012      Tarcisio Fedrizzi - T3Camp Bologna   33/37
Gestione degli oggetti
    ✗   Gli scope offerti dal framework sono:
        ✗   Singleton: il gestore degli oggetti crea un'unica istanza
            dell'oggetto. Ogni volta che viene richiesto l'oggetto viene
            ritornata la stessa istanza.
        ✗   Session: il ciclo di vita dell'oggetto corrisponde alla
            sessione di un utente. L'oggetto che ha questo tipo di
            scope è quindi specifico per ogni sessione.
        ✗   Prototype: ogni volta che si richiede un oggetto con
            questo tipo di scope ne viene ritornata una nuova istanza




17 Novembre 2012        Tarcisio Fedrizzi - T3Camp Bologna   34/37
Dependency injection
    ✗   La gestione centralizzata degli oggetti permette di
        eliminare la gestione delle dipendenze tra gli oggetti.
    ✗   È possibile richiedere un oggetto in varie maniere. La più
        semplice consiste nella specifica di due annotazioni nel
        commento della variabile che ospiterà l'oggetto.
    ...
    /**
     * Il repository delle operazioni fatte dagli utenti.
     *
     * @FlowInject
     * @var POSITMethodLoggerDomainRepositoryMethodLogRepository
     */
    protected $methodLogRepository;
    ...




17 Novembre 2012       Tarcisio Fedrizzi - T3Camp Bologna   35/37
Configurazione 1/2
                                                ...
    ✗   Flow mette a disposizione               /**
        tramite la dependency                     * L'array che contiene le
                                                  * impostazioni specificate per
        injection un meccanismo                   * il package.
                                                  * @var array
        semplice per l'accesso a                  */
        impostazioni di                         protected $settings;
                                                ...
        configurazioni specifiche               /**
                                                  * @param array $settings
        del modulo.                               * @return void
                                                  */
                                                public function
                                                  injectSettings(array $settings) {
                                                   $this->settings = $settings;
                                                }
                                                ...




17 Novembre 2012     Tarcisio Fedrizzi - T3Camp Bologna          36/37
Configurazione 2/2
                                               ...
    ✗   Una volta iniettato                    private function isEnabled() {
        l'array delle                            return
                                                   array_key_exists('enable',
        impostazioni sarà                            $this->settings) &&
                                                   $this->settings['enable'];
        possibile accedere                     }
                                               ...
        all'albero di
                                               ...
        configurazione che è                   POSIT
                                                 MethodLogger
        denominato come il                         enable: true
        namespace del                          ...

        modulo

17 Novembre 2012    Tarcisio Fedrizzi - T3Camp Bologna       37/37

Weitere ähnliche Inhalte

Ähnlich wie Flow: viaggio nel futuro con un caso realizzato

Closure Visto Da Vicino
Closure Visto Da VicinoClosure Visto Da Vicino
Closure Visto Da Vicinodavide ficano
 
Deep diving C# 4 (Raffaele Rialdi)
Deep diving C# 4 (Raffaele Rialdi)Deep diving C# 4 (Raffaele Rialdi)
Deep diving C# 4 (Raffaele Rialdi)DotNetMarche
 
How I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven DesignHow I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven DesignAndrea Saltarello
 
Apache Hadoop: Introduzione all’architettura ed approcci applicativi
Apache Hadoop: Introduzione all’architettura ed approcci applicativiApache Hadoop: Introduzione all’architettura ed approcci applicativi
Apache Hadoop: Introduzione all’architettura ed approcci applicativiDario Catalano
 
PowerMock TDD User Group Milano
PowerMock TDD User Group MilanoPowerMock TDD User Group Milano
PowerMock TDD User Group MilanoMassimo Groppelli
 
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...Massimo Cenci
 
Non solo Django: MVC orientato agli oggetti con Plone e Zope Toolkit
Non solo Django: MVC orientato agli oggetti con Plone e Zope ToolkitNon solo Django: MVC orientato agli oggetti con Plone e Zope Toolkit
Non solo Django: MVC orientato agli oggetti con Plone e Zope ToolkitMaurizio Delmonte
 
Generazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGenerazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGiacomoZorzin
 
TYPO3 Versione 10.2 - Le novita
TYPO3 Versione 10.2 - Le novitaTYPO3 Versione 10.2 - Le novita
TYPO3 Versione 10.2 - Le novitaRoberto Torresani
 
Explaining the use of Trento_p
Explaining the use of Trento_pExplaining the use of Trento_p
Explaining the use of Trento_pRiccardo Rigon
 
Inversion of control e Dependency Injection (ITA)
Inversion of control e Dependency Injection (ITA)Inversion of control e Dependency Injection (ITA)
Inversion of control e Dependency Injection (ITA)Giancarlo Valente
 

Ähnlich wie Flow: viaggio nel futuro con un caso realizzato (20)

Closure Visto Da Vicino
Closure Visto Da VicinoClosure Visto Da Vicino
Closure Visto Da Vicino
 
Pesce d'aprile
Pesce d'aprilePesce d'aprile
Pesce d'aprile
 
Deep diving C# 4 (Raffaele Rialdi)
Deep diving C# 4 (Raffaele Rialdi)Deep diving C# 4 (Raffaele Rialdi)
Deep diving C# 4 (Raffaele Rialdi)
 
TYPO3 CMS 7.5: le novita
TYPO3 CMS 7.5: le novita TYPO3 CMS 7.5: le novita
TYPO3 CMS 7.5: le novita
 
How I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven DesignHow I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven Design
 
Java Advanced
Java AdvancedJava Advanced
Java Advanced
 
SVN/TRAC
SVN/TRACSVN/TRAC
SVN/TRAC
 
Apache Hadoop: Introduzione all’architettura ed approcci applicativi
Apache Hadoop: Introduzione all’architettura ed approcci applicativiApache Hadoop: Introduzione all’architettura ed approcci applicativi
Apache Hadoop: Introduzione all’architettura ed approcci applicativi
 
Xml annessi e connessi
Xml annessi e connessiXml annessi e connessi
Xml annessi e connessi
 
PowerMock TDD User Group Milano
PowerMock TDD User Group MilanoPowerMock TDD User Group Milano
PowerMock TDD User Group Milano
 
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
 
Il Pattern di Zend Framework 2
Il Pattern di Zend Framework 2Il Pattern di Zend Framework 2
Il Pattern di Zend Framework 2
 
Non solo Django: MVC orientato agli oggetti con Plone e Zope Toolkit
Non solo Django: MVC orientato agli oggetti con Plone e Zope ToolkitNon solo Django: MVC orientato agli oggetti con Plone e Zope Toolkit
Non solo Django: MVC orientato agli oggetti con Plone e Zope Toolkit
 
Logging
LoggingLogging
Logging
 
Generazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGenerazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptx
 
#dd12 grillo daniele_xpages_tips_tricks_rev2
#dd12 grillo daniele_xpages_tips_tricks_rev2#dd12 grillo daniele_xpages_tips_tricks_rev2
#dd12 grillo daniele_xpages_tips_tricks_rev2
 
Riepilogo Java C/C++
Riepilogo Java C/C++Riepilogo Java C/C++
Riepilogo Java C/C++
 
TYPO3 Versione 10.2 - Le novita
TYPO3 Versione 10.2 - Le novitaTYPO3 Versione 10.2 - Le novita
TYPO3 Versione 10.2 - Le novita
 
Explaining the use of Trento_p
Explaining the use of Trento_pExplaining the use of Trento_p
Explaining the use of Trento_p
 
Inversion of control e Dependency Injection (ITA)
Inversion of control e Dependency Injection (ITA)Inversion of control e Dependency Injection (ITA)
Inversion of control e Dependency Injection (ITA)
 

Flow: viaggio nel futuro con un caso realizzato

  • 1. Flow: viaggio nel futuro con un caso realizzato Tarcisio Fedrizzi 16-17 Novembre 2012 Bologna
  • 2. Federazione provinciale Scuole materne di Trento ✗ Associazione di 135 scuole materne ✗ 21 circoli ✗ Quasi 1500 maestre 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 2/37
  • 3. Outline ✗ Presentazione ✗ Fluid Standalone ✗ Il progetto ✗ Considerazioni su Flow ✗ Dominio ✗ Tecnologie ✗ Conclusioni ✗ POSIT.MethodLogger ✗ Domande ✗ Annotazioni ✗ AOP 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 3/37
  • 4. Presentazione ✗ Progettazione e sviluppo applicazioni ad-hoc ✗ Primo progetto basato su ✗ Libero professionista TYPO3.Flow messo in dal 2005 produzione ✗ Socio di POSIT dal 2009 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 4/37
  • 5. 210ore: tecnologie 1/2 ✗ Server: TYPO3.Flow ✗ Client: ✗ Insegnanti: ExtJS 4 (è stato necessario rendere l'interfaccia più fedele possibile a quella del client windows usato in precedenza) 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 5/37
  • 6. 210ore: tecnologie 2/2 ✗ Gestori: TYPO3.Fluid + JQuery DataTable ✗ Amministratori: TYPO3.Expose oppure TYPO3.Fluid (ancora in fase di sviluppo) 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 6/37
  • 7. Il modulo POSIT.MethodLogger ✗ Estratto dal progetto 210ore ✗ Permette di loggare chiamate a qualsiasi metodo ✗ È possibile accedere ai parametri della chiamata ✗ Permette di vedere alcuni aspetti del framework Flow in azione 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 7/37
  • 8. Annotazioni 1/2 Elementi che permettono di “appiccicare” dei dati descrittivi (metadati) a classi, metodi e interfacce ✗ In alcuni linguaggi (es. Java) sono un costrutto che fa parte del linguaggio ✗ In altri, tra cui PHP, non sono ancora disponibili nativamente e vengono quindi specificate nei commenti. 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 8/37
  • 9. Annotazioni 2/2 ✗ Flow ne fa un uso piuttosto consistente. Ad esempio: ... use TYPO3FlowAnnotations as Flow; ... /** * @FlowEntity */ class MethodLog { ... nelle definizioni delle Entità. 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 9/37
  • 10. Definizione Annotazioni ✗ Semplice classe che ... * @Annotation * @Target("METHOD") contiene i parametri */ final class LogMethod { passati dove /** * @var string l'annotazione è */ public $message; specificata; ... ... ✗ I parametri sono class PostController { /** passati al costruttore * @POSITLogMethod( * message="Creato post.") dell'annotazione in un */ public function createAction( unico array. ... 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 10/37
  • 11. AOP 1/2 Ideata da Gregor Kiczales e altri di Xerox PARC ✗ Permette di mantenere una netta separazione tra logica di business e funzionalità non specifiche dell'applicazione ✗ Queste funzionalità vengono aggiunte con un sistema che si basa su tre concetti 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 11/37
  • 12. AOP 2/2 ✗ I concetti sono i seguenti: ✗ Advice: definisce la funzionalità che dev'essere aggiunta (Logging, controlli di accesso, ecc); ✗ Pointcut: permette di specificare in quali punti la funzionalità dev'essere eseguita (prima di chiamare un metodo, quando viene lanciata un'eccezione, ecc); ✗ Join point: descrive il contesto presente nel punto in cui è stata sospesa l'esecuzione. 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 12/37
  • 13. AOP in Flow: Aspect ✗ L'aspetto in Flow è una classe annotata con @FlowAspect. ✗ La classe deve inoltre definire un Advice o un Pointcut per essere un aspetto considerato valido. ... /** * @FlowAspect */ class LogMethodAspect { /** * @FlowAround( * "POSITMethodLoggerAspectLogMethodAspect->methodsAnnotatedWithLogMethod") */ public function runMethodLogging(TYPO3FlowAopJoinPointInterface $joinPoint){ ... 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 13/37
  • 14. AOP in Flow: Pointcut ✗ Flow offre diversi designatori di pointcut: method, class, ecc... ✗ Essi permettono di selezionare i metodi ai quali dev'essere applicato un advice ... /** * @FlowPointcut( * "methodAnnotatedWith( * POSITMethodLoggerAnnotationsLogMethod)") */ public function methodsAnnotatedWithLogMethod() {} ... 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 14/37
  • 15. AOP in Flow: Advice ✗ L'advice è il metodo che viene eseguito quando vengono chiamati i metodi selezionati con il pointcut; ✗ Esso viene eseguito secondo le indicazioni dall'annotazione che decora il metodo; ... /** * @FlowAround( * "POSITMethodLoggerAspectLogMethodAspect->methodsAnnotatedWithLogMethod") */ public function runMethodLogging(TYPO3FlowAopJoinPointInterface $joinPoint){ $logMethod = $this->getLogMethodAnnotation($joinPoint); $this->logMessage($joinPoint, $logMethod); return $joinPoint->getAdviceChain()->proceed($joinPoint); } ... 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 15/37
  • 16. AOP in Flow: Join point ✗ Il join point permette di accedere al contesto e alla descrizione del metodo al quale è applicato l'advice; ✗ tramite il join point è possibile conoscere il nome del metodo, i parametri che sono stati passati, ecc ... $i = 0; $className = $joinPoint->getClassName(); $methodName = $joinPoint->getMethodName(); $methodArguments = $joinPoint->getMethodArguments(); print("$className->$methodName("); foreach ($methodArguments as $argumentName => $argumentValue) { if ($i++ > 0) { print(", "); } print("$argumentName = $argumentValue"); } print(");n"); ... 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 16/37
  • 17. Fluid standalone 1/2 ✗ È possibile utilizzare il motore di templating anche in maniera standalone ✗ Questo ci permette di riutilizzare la sintassi di fluid anche in contesti differenti rispetto a quello delle pagine web private function renderViewText(TYPO3FlowAopJoinPointInterface $joinPoint $text) { $textView = new TYPO3FluidViewStandaloneView(); $textView->initializeObject(); $textView->setTemplateSource($text); foreach ($joinPoint->getMethodArguments() as $name => $value) { $textView->assign($name, $value); } return $textView->render(); } 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 17/37
  • 18. Fluid standalone 2/2 ✗ L'utilizzo del metodo definito nella slide precedente ci permette quindi di accedere ai parametri del metodo loggato all'interno del messaggio di log ... /** * @POSITLogMethod(message="{newPost.author} ha creato il nuovo * post intitolato {newPost.title}.") */ public function createAction( TYPO3BlogDomainModelPost $newPost) { ... 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 18/37
  • 19. Considerazioni su Flow 1/9 ✗ Dal punto di vista tecnologico offre molte possibilità (AOP, annotazioni, slot e segnali) ✗ c'è tutto quello che (e anche di più) può servire per lo sviluppo web ✗ È in generale semplice aggiungere e/o modificare le funzionalità offerte dal framework ✗ Si tratta in genere di ereditare da una classe e di implementare un'interfaccia definendo pochi metodi (molte volte è sufficiente uno) 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 19/37
  • 20. Considerazioni su Flow 2/9 ✗ Il sistema di controllo degli accessi è molto flessibile ✗ Permette di specificare anche condizioni complesse modificando soltanto i file di configurazione ✗ Il sistema di mapping dei parametri della richiesta sui parametri del metodo dell'azione chiamata nel controller permette di mantenere la logica di business molto pulita 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 20/37
  • 21. Considerazioni su Flow 3/9 ✗ Configurabilità da file ✗ Semplice aggiungere la configurazione anche per i propri moduli ✗ L'interfaccia a linea di comando ✗ Semplice aggiungere comandi per i propri moduli 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 21/37
  • 22. Considerazioni su Flow 4/9 ✗ Problema maggiore riguarda l'usabilità: ✗ Punti fondamentali per lo sviluppo di un progetto reale non sono documentati. Ad esempio: ✗ Logging e debugging ✗ Deployment e amministrazione ✗ L'applicazione di esempio TYPO3.Blog copre alcune casistiche ma non offre un esempio esaustivo ✗ Gli esempi che ci sono nella documentazione sono utili ma anche in questo caso non esaustivi 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 22/37
  • 23. Considerazioni su Flow 5/9 ✗ In molti casi è difficile capire dov'è o a quale elemento si riferisce un errore ✗ Non c'è menzione a qualche cosa che mi possa aiutare a trovare il soggetto dell'errore 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 23/37
  • 24. Considerazioni su Flow 6/9 ✗ E lo stacktrace dell'eccezione scritto su file non offre maggiori informazioni Uncaught exception #1222268609 in line 146 of Data/Temporary/Development/Cache/Code/FLOW3_Object_Classes/TYPO3_FLOW3_Security_Authorization_AccessDecisionVoterManager. Php: Access denied (1 denied, 0 granted, 0 abstained) 22 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager_Original::decideOnJoinPoint(TYPO3FLOW3AopJoinPoint) 21 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager::decideOnJoinPoint(TYPO3FLOW3AopJoinPoint) 20 call_user_func_array(array, array) 19 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager::FLOW3_Aop_Proxy_invokeJoinPoint(TYPO3FLOW3AopJoinPoint) 18 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager::decideOnJoinPoint(TYPO3FLOW3AopJoinPoint) 17 TYPO3FLOW3SecurityAuthorizationInterceptorPolicyEnforcement_Original::invoke() 16 TYPO3FLOW3SecurityAspectPolicyEnforcementAspect_Original::enforcePolicy(TYPO3FLOW3AopJoinPoint) 15 TYPO3FLOW3AopAdviceAroundAdvice::invoke(TYPO3FLOW3AopJoinPoint) 14 TYPO3FLOW3AopAdviceAdviceChain::proceed(TYPO3FLOW3AopJoinPoint) 13 POSITDuecentodieciOreControllerDomainAccountingAnnualEstimateController::initializeAction() 12 TYPO3FLOW3MvcControllerActionController_Original::processRequest(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse) 11 TYPO3FLOW3MvcDispatcher_Original::dispatch(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse) 10 TYPO3FLOW3MvcDispatcher::dispatch(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse) 9 call_user_func_array(array, array) 8 TYPO3FLOW3MvcDispatcher::FLOW3_Aop_Proxy_invokeJoinPoint(TYPO3FLOW3AopJoinPoint) 7 TYPO3FLOW3AopAdviceAdviceChain::proceed(TYPO3FLOW3AopJoinPoint) 6 TYPO3FLOW3SecurityAspectRequestDispatchingAspect_Original::blockIllegalRequestsAndForwardToAuthenticationEntryPoints( TYPO3FLOW3AopJoinPoin t) 5 TYPO3FLOW3AopAdviceAroundAdvice::invoke(TYPO3FLOW3AopJoinPoint) 4 TYPO3FLOW3AopAdviceAdviceChain::proceed(TYPO3FLOW3AopJoinPoint) 3 TYPO3FLOW3MvcDispatcher::dispatch(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse) 2 TYPO3FLOW3HttpRequestHandler::handleRequest() 1 TYPO3FLOW3CoreBootstrap::run() 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 24/37
  • 25. Considerazioni su Flow 7/9 ✗ Spesso errori nel progetto (per esempio derivanti da elaborazione del codice del progetto da parte del framework, configurazioni errate all'interno del progetto) producono stacktrace e messaggi in cui non appare niente che riguarda il progetto. Questo rende quindi molto difficile e pesante comprendere qual'è il problema. 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 25/37
  • 26. Considerazioni su Flow 8/9 ✗ Assenza di utility per rendere lo sviluppo più comodo e rapido ✗ Mi sarei aspettato di trovare nella distribuzione base: ✗ Un'interfaccia web per il debugging (area che posso consultare per leggere i log, profiling, ecc) ✗ Vedi Debug.Toolbar (debug), Plumber (profiling) ✗ Un'interfaccia grafica per una gestione di base degli oggetti definiti nel progetto ✗ Vedi TYPO3.Expose 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 26/37
  • 27. Considerazioni su Flow 9/9 ✗ Un interfaccia CRUD che mi permetta di gestire gli oggetti nel database senza dover scrivere sempre lo stesso codice. ✗ L'usabilità è troppe volte posta come un elemento a bassa priorità. È invece molto importante dato che la sua carenza: ✗ costituisce una barriera per l'adozione da parte di nuovi utenti ✗ rende frustranti operazioni che dovrebbero essere semplici 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 27/37
  • 28. Conclusione ✗ TYPO3.Flow è un framework completo che offre tutti gli strumenti per creare le più disparate applicazioni web ✗ Offre una base ricca e solida su cui costruire i propri progetti ✗ Ancora molto dev'essere fatto sul fronte dell'usabilità perché: ✗ non tutti se la sentono di mettere il naso nel codice del framework per fare il debug della propria applicazione ✗ un framework che si pone come obiettivo di ...“far tornare la gioia di sviluppare.”... dovrebbe rendere veloci e semplici quelle operazioni noiose e ripetitive che fanno parte di ogni progetto ✗ Per evitare che il progetto rimanga nel limbo è necessario cominciare ad utilizzare, e quindi testare, il framework in ambienti reali. Soltanto così è possibile verificare quali aspetti vanno migliorati, capire cosa sarebbe comodo avere e, riportandolo agli sviluppatori oppure contribuendo noi stessi, migliorare il framework fino a renderlo lo strumento più adatto alle nostre esigenze. 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 28/37
  • 29. Grazie per l'attenzione ✗ Il codice dell'esempio mostrato nella presentazione è disponibile all'url: ✗ https://github.com/posit-it/POSIT.MethodLogger ✗ L'esempio gira su Flow 2.0 (ex FLOW3 1.2) ✗ Altri pacchetti menzionati nella presentazione: ✗ Plumber: ✗ https://github.com/sandstorm/Plumber ✗ Debug.Toolbar: ✗ https://github.com/mneuhaus/Debug.Toolbar/ ✗ TYPO3.Expose: ✗ http://git.typo3.org/FLOW3/Packages/TYPO3.Expose.git 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 29/37
  • 30. Persistenza ✗ In Flow la persistenza dei dati è gestita tramite un livello di astrazione ✗ Flow si basa sulla programmazione orientata agli oggetti. Questo implica che in flow la “base dati” è costituita dalla definizione di una serie di oggetti collegati tra loro. ✗ Dietro le quinte il framework si occupa di mappare gli oggetti da e verso il database 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 30/37
  • 31. Persistenza: Doctrine ✗ Flow supporta diversi metodi di persistenza tuttavia quello maggiormente integrato è Doctrine. ✗ Doctrine (la versione 2 è quella integrata in FLOW) è un Object Relational Mapping Software. Questo genera, a partire dalla descrizione dei dati e dalle azioni che noi facciamo sui dati stessi, le query che aggiornano i dati nel database. 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 31/37
  • 32. Persistenza: entità ✗ Per poter mappare gli oggetti su database è necessario decorare gli oggetti con alcune annotazioni. Queste permettono all'ORM di raccogliere le informazioni necessarie a generare lo schema. ... * @FlowEntity */ class MethodLog { ... /** * L'indirizzo del client che ha causato l'invocazione del metodo loggato. * @var string * @ORMColumn(length=15, nullable=true) */ protected $ip; ... 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 32/37
  • 33. Gestione degli oggetti ✗ In Flow il cliclo di vita degli oggetti è gestito automaticamente dal framework ✗ La gestione degli oggetti viene quindi affidata ad una classe chiamata ObjectManager ✗ Ad ogni classe è associato quello che è definito scope. Questo determina il modo in cui viene gestito il ciclo di vita dell'oggetto 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 33/37
  • 34. Gestione degli oggetti ✗ Gli scope offerti dal framework sono: ✗ Singleton: il gestore degli oggetti crea un'unica istanza dell'oggetto. Ogni volta che viene richiesto l'oggetto viene ritornata la stessa istanza. ✗ Session: il ciclo di vita dell'oggetto corrisponde alla sessione di un utente. L'oggetto che ha questo tipo di scope è quindi specifico per ogni sessione. ✗ Prototype: ogni volta che si richiede un oggetto con questo tipo di scope ne viene ritornata una nuova istanza 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 34/37
  • 35. Dependency injection ✗ La gestione centralizzata degli oggetti permette di eliminare la gestione delle dipendenze tra gli oggetti. ✗ È possibile richiedere un oggetto in varie maniere. La più semplice consiste nella specifica di due annotazioni nel commento della variabile che ospiterà l'oggetto. ... /** * Il repository delle operazioni fatte dagli utenti. * * @FlowInject * @var POSITMethodLoggerDomainRepositoryMethodLogRepository */ protected $methodLogRepository; ... 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 35/37
  • 36. Configurazione 1/2 ... ✗ Flow mette a disposizione /** tramite la dependency * L'array che contiene le * impostazioni specificate per injection un meccanismo * il package. * @var array semplice per l'accesso a */ impostazioni di protected $settings; ... configurazioni specifiche /** * @param array $settings del modulo. * @return void */ public function injectSettings(array $settings) { $this->settings = $settings; } ... 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 36/37
  • 37. Configurazione 2/2 ... ✗ Una volta iniettato private function isEnabled() { l'array delle return array_key_exists('enable', impostazioni sarà $this->settings) && $this->settings['enable']; possibile accedere } ... all'albero di ... configurazione che è POSIT MethodLogger denominato come il enable: true namespace del ... modulo 17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 37/37