Università degli Studi di Padova

Pagina creata da Enrico Poli
 
CONTINUA A LEGGERE
Università degli Studi di Padova
 Dipartimento di Matematica "Tullio Levi-Civita"
               Corso di Laurea in Informatica

       Studio e applicazione di tecnologie
    alternative a Java in ambito Enterprise
                     Tesi di Laurea Triennale

Relatore
Prof. Mauro Conti

                                                  Laureando
                                                Paolo Broglio

                    Anno Accademico 2018-2019
Paolo Broglio: Studio e applicazione di tecnologie alternative a Java in ambito
Enterprise, Tesi di Laurea Triennale, c Luglio 2019.
Dedicato alla mia famiglia.
Sommario

Il presente documento descrive il lavoro svolto durante il periodo di stage, della durata
di circa trecento ore, dal laureando Paolo Broglio presso l’azienda Infocert S.p.A.
L’obiettivo dello stage consisteva nel ricercare, analizzare e utilizzare linguaggi di
programmazione alternativi a Java per la realizzazione di software utilizzato in ambito
Enteprise.
In primo luogo era richiesta un’analisi del panorama tecnologico per quanto concerne i
linguaggi di programmazione che permettono di produrre software eseguibile su Java
Virtual Machine. Come compito correlato è stata vista come possibilità l’utilizzo di
Application Server alternativi a JBoss, lo standard de facto per Infocert S.p.A. In
seguito allo studio di cui sopra è stato richiesto di implementare un microservizio la cui
funzionalità principale fosse quella di rendere disponibile via interfaccia REST tutte le
operazioni possibili esposte da una Certification Authority preesistente.

                                            v
Ringraziamenti

Innanzitutto, vorrei ringraziare il Prof. Mauro Conti, relatore della mia tesi, per la
disponibilità dimostratami durante il percorso che si è concluso con la mia Laurea.

Desidero ringraziare i miei genitori e tutti i miei amici e colleghi per avermi sostenuto
sempre nelle mie scelte, facendomi superare tutti i momenti di difficoltà che ho incon-
trato durante il mio percorso accademico.

Padova, Luglio 2019                                                       Paolo Broglio

                                           vii
Indice

1 Introduzione                                                                                                                               1
  1.1 Il futuro digitale . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    1
  1.2 L’azienda . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    1
  1.3 L’idea . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    1
  1.4 Organizzazione del testo      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    2

2 Obiettivi del progetto                                                                                                                    3
  2.1 Studio e analisi dei linguaggi eseguibili su JVM . . . . . . . . . .                                                      .   .   .   3
  2.2 Sviluppo di un prodotto software utilizzando le tecnologie scelte .                                                       .   .   .   3
  2.3 Analisi e studio delle performance . . . . . . . . . . . . . . . . .                                                      .   .   .   3
  2.4 Obiettivi collaterali . . . . . . . . . . . . . . . . . . . . . . . . . .                                                 .   .   .   3

3 Descrizione dello stage                                                                                                                   5
  3.1 Introduzione al progetto . . . . . . . .                      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   5
      3.1.1 Temi trattati . . . . . . . . . .                       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   5
      3.1.2 Sviluppo del prodotto software                          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   5
  3.2 Analisi preventiva dei rischi . . . . . .                     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   7
  3.3 Requisiti e milestones . . . . . . . . .                      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   7
      3.3.1 Requisiti . . . . . . . . . . . . .                     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   7
      3.3.2 Milestones . . . . . . . . . . . .                      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   8
  3.4 Pianificazione . . . . . . . . . . . . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   8

4 Studio e analisi delle tecnologie                                                                                                          9
  4.1 Linguaggi di programmazione JVM                       compatibili                 .   .   .   .   .   .   .   .   .   .   .   .   .    9
      4.1.1 Organizzazione dello studio                     . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .    9
      4.1.2 Kotlin . . . . . . . . . . . .                  . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   10
      4.1.3 Groovy . . . . . . . . . . .                    . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   11
      4.1.4 Scala . . . . . . . . . . . . .                 . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   11
      4.1.5 Clojure . . . . . . . . . . .                   . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   12
  4.2 Enterprise application framework .                    . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   13
  4.3 Conclusione dell’analisi . . . . . . .                . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   13

5 Ambiente e strumenti                                                                                                                      15
  5.1 Ambiente di lavoro . . . . . . . . . . . . .                          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
  5.2 Strumenti . . . . . . . . . . . . . . . . . .                         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
      5.2.1 Organizzativi e di documentazione                               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
      5.2.2 Sviluppo . . . . . . . . . . . . . . .                          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15

6 Analisi dei requisiti                                                                                                                     17

                                                    ix
x                                                                                                                                  INDICE

    6.1   Consolidamento dei requisiti     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
          6.1.1 Requisiti del sistema      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
    6.2   Casi d’uso . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
    6.3   Tracciamento dei requisiti .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   20

7 Progettazione                                                                                                                            23
  7.1 Progettazione . . . . . . . . .          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   23
      7.1.1 Architettura . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   23
      7.1.2 Classi . . . . . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   24
  7.2 Design Pattern utilizzati . . .          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   28
      7.2.1 Abstract Factory . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   28
      7.2.2 Dependency Injection               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   28

8 Sviluppo                                                                                                                                 29
  8.1 Struttura del progetto . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   29
  8.2 Sviluppo modulo REST . . . . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   29
       8.2.1 Definizione delle risorse .               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   29
       8.2.2 Manager . . . . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   31
  8.3 Sviluppo modulo CORE . . . . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   31
       8.3.1 Service . . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   31
       8.3.2 Connector . . . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   32
  8.4 Sviluppo modulo CONNECTOR                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   32
       8.4.1 Decoder ed Encoder . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   33
       8.4.2 Client . . . . . . . . . . .              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   34

9 Verifica e validazione                                                                                                                   35
  9.1 Introduzione . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   35
       9.1.1 Test di Unità . . . .         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   35
       9.1.2 Test di Integrazione          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   36
       9.1.3 Test di performance           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   36

10 Conclusioni                                                                                                                             41
   10.1 Consuntivo finale . . . . . . . . . . . . . . . . . . . . . . .                                        .   .   .   .   .   .   .   41
   10.2 Raggiungimento degli obiettivi . . . . . . . . . . . . . . .                                           .   .   .   .   .   .   .   41
        10.2.1 Studio delle tecnologie alternative a Java su JVM .                                             .   .   .   .   .   .   .   41
        10.2.2 Sviluppo prodotto software con le tecnologie scelte                                             .   .   .   .   .   .   .   41
        10.2.3 Analisi delle performance . . . . . . . . . . . . . .                                           .   .   .   .   .   .   .   41
   10.3 Conoscenze acquisite . . . . . . . . . . . . . . . . . . . . .                                         .   .   .   .   .   .   .   41
   10.4 Valutazione personale . . . . . . . . . . . . . . . . . . . .                                          .   .   .   .   .   .   .   42

A Appendice A                                                                                                                              43
  A.1 Specifiche IETF di messaggi PKIX . . . . . . . . . . . . . . . . . . . .                                                             43
      A.1.1 Certification Request - PKCS10 . . . . . . . . . . . . . . . . . .                                                             43

Glossary                                                                                                                                   45

Acronyms                                                                                                                                   49

Bibliografia                                                                                                                               51
Elenco delle figure

 3.1   CA-PROXY mette in comunicazione RA e CA. . . . . . . . . . . . . .                                                                    6
 3.2   Pianificazione stage . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                        8

 6.1   Koraca Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                         19

 7.1   Architettura del Proxy . . . . . . . . .                     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   23
 7.2   Modulo REST . . . . . . . . . . . . .                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   24
 7.3   Modulo REST: bean risposta/richiesta                         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   24
 7.4   Modulo CORE . . . . . . . . . . . . .                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   26
 7.5   Modulo CONNECTOR . . . . . . . .                             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   27

 9.1   Tempo totale di risposta.        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   37
 9.2   Tempo medio di risposta.         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   37
 9.3   Utilizzo della CPU. . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   38
 9.4   Utilizzo della RAM. . . .        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   38

Elenco delle tabelle

 4.1   Confronto Linguaggi di Programmazione. . . . . . . . . . . . . . . . .                                                               10
 4.2   Confronto Framework. . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                           13

 6.1   Tabella   dei   requisti funzionali . . . . . . . . . . .                            .   .   .   .   .   .   .   .   .   .   .   .   18
 6.2   Tabella   dei   requisti di sicurezza . . . . . . . . . .                            .   .   .   .   .   .   .   .   .   .   .   .   18
 6.3   Tabella   del   tracciamento dei requisti funzionali .                               .   .   .   .   .   .   .   .   .   .   .   .   21
 6.4   Tabella   del   tracciamento dei requisiti qualitativi                               .   .   .   .   .   .   .   .   .   .   .   .   21

                                                    xi
xii   ELENCO DELLE TABELLE
Capitolo 1

Introduzione

1.1     Il futuro digitale
Il contesto applicativo cui ho dovuto fare riferimento durante lo svolgimento dello
stage è quello dell’ufficio digitale, ovvero ottenere la completa informatizzazione degli
strumenti e dei processi che vanno a costituire un ufficio. L’eliminazione della carta
come materia prima per lo svolgimento di queste attività è uno degli obiettivi che si
pone questa trasformazione, ottenendo non solo la riduzione dell’utilizzo di questo
materiale, ma anche una velocizzazione e una affidabilità che al giorno d’oggi risultano
indispensabili. In particolare per quanto riguarda la mia esperienza di stage mi sono
dovuto concentrare nell’ambito della Firma Digitale[g] .

1.2     L’azienda
Infocert S.p.A. è una delle più importanti Certification Authority a livello europeo
e fornisce servizi di firma digitale, Posta Elettronica Certificata (PEC)[g] , Sistema
Pubblico di Identità Digitale (SPID)[g] , e fatturazione elettronica. L’obiettivo principale
dell’azienda è quello di rendere disponibili tutti gli strumenti per la creazione di un
ufficio digitale, fornendo ai propri clienti soluzioni paperless. Queste vengono fornite
ad altre aziende e a professionisti come:

   ∗ Commercialisti;

   ∗ Avvocati e notai;

   ∗ Liberi professionisti e Partite IVA.

1.3     L’idea
Il progetto di stage è nato da un bisogno dell’azienda: valutare e mettere in pratica
tecnologie alternative a Java per lo sviluppo di applicazioni web. La scelta del
linguaggio di programmazione è stata associata alla ricerca una soluzione alternativa
all’application server JBoss[g] per la creazione di un Microservizio[g] utilizzando le
tecnologie scelte. Infine si è pensato di eseguire delle comparazioni in termini di
performance tra l’applicativo sviluppato e uno preesistente.

                                             1
2                                                    CAPITOLO 1. INTRODUZIONE

1.4      Organizzazione del testo
Il secondo capitolo descrive gli obiettivi finali del progetto di stage;
Il terzo capitolo descrive lo stage;
Il quarto capitolo tratta lo studio e l’analisi delle tecnologie oggetto del progetto di
     stage;
Il quinto capitolo approfondisce lo studio dei linguaggi basati su Java Virtual
     Machine (JVM)[g] e le alternative in ambito enterprise;
Il sesto capitolo tratta l’analisi dei requisiti del software;

Il settimo capitolo tratta la progettazione del software;
L’ottavo capitolo tratta l’evoluzione dello sviluppo del software;
Il nono capitolo approfondisce il periodo di verifica e validazione;
Il decimo capitolo contiene le conclusioni.

   In merito alla stesura del testo sono state adottate le seguenti convenzioni tipografi-
che:

    ∗ gli acronimi, le abbreviazioni e i termini ambigui o di uso non comune menzionati
      vengono definiti nel glossario, situato alla fine del documento;
    ∗ per la prima occorrenza dei termini riportati nel glossario viene utilizzata la
      seguente nomenclatura: parola [g] ;

    ∗ i termini in lingua straniera o facenti parti del gergo tecnico sono evidenziati con
      il carattere corsivo.
Capitolo 2

Obiettivi del progetto

In questo capitolo verranno illustrati gli obiettivi principali e quelli collaterali scaturiti dal
colloquio con il tutor aziendale.

2.1      Studio e analisi dei linguaggi eseguibili su JVM
Lo studio delle tecnologie alternative a quelle standard aziendali, come Java e JBoss è
stato l’obiettivo principale di questo progetto. Si è pensato di rivolgere l’attenzione
non solo al linguaggio di programmazione ma anche ad un application server differente
ed eventualmente a Framework[g] per la creazione di applicazioni web .

2.2      Sviluppo di un prodotto software utilizzando le
         tecnologie scelte
In seguito all’analisi di cui al punto precedente si è pensato di sviluppare un applicativo
utilizzando le tecnologie scelte. Per la scelta di quale software sviluppare, si è pensato, in
accordo col tutor aziendale, di creare un prodotto simile ad uno preesistente sviluppato
con le tecnologie standard.

2.3      Analisi e studio delle performance
Come conclusione dello sviluppo dell’applicativo si è pensato di eseguire uno studio
delle performance eseguendo un paragone con il software originale. In questo modo si
è pensato di rendere evidenti le differenze tra le due scelte tecnologiche sfruttando dati
oggettivi.

2.4      Obiettivi collaterali
Di seguito sono elencati tutti gli obiettivi secondari ma necessari allo svolgimento del
progetto di stage.

                                                3
4                                     CAPITOLO 2. OBIETTIVI DEL PROGETTO

    ∗ Metodologia di sviluppo Agile: dal momento che il processo di sviluppo del
      software all’interno dell’azienda sfrutta la metodologia Agile[g] , si è pensato di
      approfondire e utilizzarla specificatamente nelli svolgimento del progetto di stage;
    ∗ Certificati e firma digitale: essendo i servizi di punta dell’azienda, si è
      valutato di studiare e approfondire la tecnologia della firma digitale, con lo
      scopo di utilizzare queste conoscenze per lo sviluppo dell’applicativo previsto.
      L’attenzione è stata posta all’intero argomento Public Key Infrastructure (PKI)[g] .
Capitolo 3

Descrizione dello stage

Questo capitolo ha lo scopo di illustrare il contenuto dello stage, completo di requisiti e
pianificazione.

3.1     Introduzione al progetto
3.1.1     Temi trattati
Lo stage ha previsto l’inserimento dello studente nel team operativo LEGALCERT
che si occupa di firma digitale. Gli argomenti trattati sono stati principalmente:

   ∗ Linguaggi di programmazione basati su JVM, alternativi a Java (Kotlin, Scala,
     Clojure, Groovy);

   ∗ tecnologie per la realizzazione di microservizi in ambito enterprise (Spring Boot,
     ecc.);

   ∗ metodologia di sviluppo Agile;

   ∗ PKI.

3.1.2     Sviluppo del prodotto software
Per mettere in pratica lo studio e l’analisi delle tecnologie, e l’approfondimento sulla
PKI e la firma digitale, si è pensato di procedere con la realizzazione di un microservizio,
prendendo spunto da un altro servizio preesistente, sviluppato con le tecnologie standard
aziendali. Tale servizio deve soddisfare i seguenti requisiti:

   ∗ Deve mettere in comunicazione una Registration Authority (RA)[g] e una Certifi-
     cation Authority (CA);

   ∗ deve rendere disponibili le operazioni di emissione, revoca, sospensione e
     riattivazione di un certificato;

   ∗ deve essere configurabile e agnostico agli attori che ci interagiscono;

   ∗ deve poter rimpiazzare senza nessuna modifica il servizio preesistente.

                                             5
6                                     CAPITOLO 3. DESCRIZIONE DELLO STAGE

In seguito allo sviluppo è stato chiesto di creare una Test Suite[g] di carico per analizzare
le performance del microservizio sviluppato, creando dei grafici di comparazione col
prodotto interno all’azienda. Il microservizio prende il nome di CA-PROXY.

               Figura 3.1: CA-PROXY mette in comunicazione RA e CA.
3.2. ANALISI PREVENTIVA DEI RISCHI                                                    7

3.2     Analisi preventiva dei rischi
Durante la fase di analisi iniziale sono stati individuati alcuni possibili rischi. Si è
quindi proceduto a elaborare delle possibili soluzioni per far fronte a tali rischi.

1. Argomenti sconosciuti
Descrizione: Utilizzo di tecnologie mai studiate, come quelle relative alla JVM,
alternative a Java, e alcuni strumenti di sviluppo e gestione di progetto.
Soluzione: coinvolgimento di Product Owner in ambito SCRUM per l’organizzazione
del progetto e introduzione di attività di studio delle nuove tecnologie.
2. Tecnologie emergenti
Descrizione: Alcune delle tecnologie, oggetto di studio dello stage, sono emergenti
nell’azienda e quindi i membri del team in cui lo studente è inserito non possono
contribuire attivamente alla formazione dello studente stesso.
Soluzione: Sessioni di pair programming e condivisione dei risultati di studio da parte
dello studente.

3.3     Requisiti e milestones
3.3.1    Requisiti
Si farà riferimento ai requisiti secondo le seguenti notazioni:

   ∗ min: per i requisiti minimi, vincolanti in quanto obiettivo primario richiesto dal
     committente;

   ∗ max: per i requisiti massimi (comprendenti quelli desiderabili e opzionali), non
     vincolanti o strettamente necessari, ma dal riconoscibile valore aggiunto;

   ∗ for: per gli obiettivi formativi, rappresentanti valore aggiunto non strettamente
     competitivo.

Le sigle precedentemente indicate saranno seguite da una coppia sequenziale di numeri,
identificativo del requisito. Sono stati previsti i segunti requisiti:

Minimi
   ∗ min01: analisi dei linguaggi JVM compatibili in ottica enterprise;

   ∗ min02: realizzazione di un microservice con un linguaggio JVM compatibile;

   ∗ min03: utilizzo di tool di sviluppo Git, Maven, Jenkins;

   ∗ min04: report finale di analisi delle performance.

Massimi
   ∗ max01: Interfacciamento completo del microservizio realizzato con gli attuali
     sistemi PKI.
8                                     CAPITOLO 3. DESCRIZIONE DELLO STAGE

Formativi
    ∗ for01: comprensione dei sistemi di cifratura e firma digitale;
    ∗ for02: utilizzo della metodologia Agile in ambito aziendale;

    ∗ for03: collegato a min01. Studio dei linguaggi di programmazione compatibili
      con JVM in ottica enterprise.

3.3.2      Milestones
Di seguito è riportato l’elenco delle milestone previste nell’arco temporale dello sta-
ge. Ad ogni milestone è stato associato un oggetto deliverable prodotto entro ogni
corrispondente scadenza. Le milestone fissate sono le seguenti:
    1. Fine seconda settimana: creazione del microservizio utilizzando le tecnologie
       scelte durante le attività di studio della prima settimana;

    2. Fine terza settimana: compatibilità del microservizio con le correnti interfacce
       REST di RACA, implementate tramite mock ;
    3. Fine quarta settimana: appresa conoscenza di ASN.1 e PKI Message;
    4. Fine quinta settimana: prodotto che presenta una comunicazione minima verso
       la Certification Authority;
    5. Fine sesta settimana: prodotto che permetta l’emissione, la revoca, la riattivazione
       e la sospensione dei certificati;
    6. Fine settima settimana: compatibilità con attuale Registration Authority;

    7. Fine ottava settimana: report contenente risultati di analisi delle performance
       del prodotto. Il report deve avere un confronto con le performance dell’attuale
       tencologia utilizzata: RACA.

3.4      Pianificazione
Di seguito è riportato il diagramma di Gantt relativo alle attività svolte durante lo
stage.

                             Figura 3.2: Pianificazione stage
Capitolo 4

Studio e analisi delle tecnologie

4.1      Linguaggi di programmazione JVM compatibili
In questa sezione verranno presentati i linguaggi di programmazione alternativi a Java
che possono essere usati per creare programmi eseguibili su Java Virtual Machine. Le
versioni sono state analizzate al momento dell’inizio del periodo di stage, nel novembre
2017.

4.1.1        Organizzazione dello studio
Aspetti analizzati
Di seguito sono enumerati tutti i parametri e gli aspetti presi in considerazione per
poter attuare un confronto significativo ed effettuare una scelta per la prosecuzione del
progetto.

   ∗ Tipizzazione: Statica - Dinamica;

   ∗ Paradigma: OOP - Funzionale;

   ∗ Interoperabilità con Java: Bassa - Media - Alta. Discriminante necessaria in
     ottica di utilizzo del linguaggio studiato per integrarlo con software preesistenti
     sviluppati con Java;

   ∗ Altri aspetti: presenti nello studio, ma non inseriti nella tabella di comparazione
     perché di secondaria importanza.

Risorse e materiale di riferimento
Di seguito sono elencate le risorse prese come riferimento per eseguire lo studio:

   ∗ Kotlin: Documentazione di Kotlin1 , Kotlin in Action2 ;

   ∗ Scala: Documentazione di Scala3 , Functional Programming in Scala4 ;
  1 Kotlin Documentation. url: https://kotlinlang.org/docs/reference/.
  2 SvetlanaIsakova Dmitry Jemerov. Kotlin in Action. Manning, 2017.
  3 Scala Documentation. url: https://docs.scala-lang.org/.
  4 Rúnar Bjarnason Paul Chiusano. Functional Programming in Scala. Manning, 2014.

                                             9
10                           CAPITOLO 4. STUDIO E ANALISI DELLE TECNOLOGIE

      ∗ Clojure: Documentazione di Clojure5 ;

      ∗ Groovy: Documentazione di Groovy6 .

                       Tabella 4.1: Confronto Linguaggi di Programmazione.

 Nome             Tipizzazione      Paradigma       Interoperabilità Java         Versione

 Kotlin               Statica           OOP                   Alta                 v1.1.50

     Scala            Statica        Fun/OOP                  Alta                 v2.12.3

 Groovy             Dinamica            OOP                  Media                 v2.4.9

 Clojure            Dinamica            Fun                  Media                 v1.8.0

4.1.2        Kotlin
Vantaggi
      ∗ Pensato per essere un linguaggio di programmazione semplice e volto alla pro-
        duttività. Uno degli aspetti più interessanti in questo senso è la rimozione ove
        possibile delle Cerimonie[g] ;

      ∗ Mantiene i concetti di OOP, aggiungendo proprietà del Paradigma Funzionale,
        per esempio l’immutabilità e le higher order function;

      ∗ Sviluppato e mantenuto da JetBrains, azienda famosa per IntelliJIDEA. Inoltre
        è stato reso Open Source, il che ha contribuito alla creazione di strumenti creati
        dalla comunità di GitHub;

      ∗ L’elevata interoperabilità con Java rappresenta un altro punto di forza, permet-
        tendo di utilizzare qualsiasi libreria scritta in Java senza alcuna difficoltà;

      ∗ Le risorse di riferimento come la documentazione sono chiare e ben strutturare,
        offrendo una buona esperienza per chi deve consultare le specifiche del linguaggio.

Svantaggi
      ∗ La maturità del linguaggio è un aspetto fondamentale nel caso di un’azienda
        che ha bisogno di tecnologie molto stabili. JetBrains si è prodigata molto in
        tal senso ma per raggiungere il livello di Java ci vuole ancora tempo, sia per le
        ottimizzazioni in fatto di compilazione sia per il supporto a determinate librerie
        sviluppate utilizzando proprio Java. Va comunque fatto presente che Google ha
        deciso di sceglierlo come linguaggio de facto per lo sviluppo di applicazioni per
        sistema operativi Android, il che ha portato una notevole crescita nel numero
        di aziende che hanno iniziato ad utilizzarlo per i propri prodotti software.
     5 Clojure   Documentation. url: http://clojure-doc.org/.
     6 Groovy    Documentation. url: http://groovy-lang.org/documentation.html.
4.1. LINGUAGGI DI PROGRAMMAZIONE JVM COMPATIBILI                                        11

Conclusioni
Kotlin è stato più volte considerato come il successore di Java in diversi contesti (oltre
al supporto per Android, anche Pivotal ha iniziato a raccomandarlo rispetto a Java),
ed è considerato da esperti del settore un "linguaggio su cui scommettere"7 . Un aspetto
da non sottovalutare riguarda alcuni costrutti del linguaggio, quali ad esempio le Data
Class che permettono di creare strutture dati immutabili, con un numero di righe
di codice irrisorio (da una ad un numero che corrisponde alla cardinalità dei campi
di classe). In seguito all’analisi Kotlin si è rivelato essere un buon candidato per il
progetto di stage.

4.1.3     Groovy
Vantaggi
   ∗ La tipizzazione dinamica offre un vantaggio notevole in termini di produttività
     (questo è dovuto al fatto che i linguaggi di questo tipo sono maggiormente concisi).
     Un aspetto interessante è la possibilità di utilizzare la tipizzazione statica tramite
     l’utilizzo di annotazioni specifiche, offrendo flessibilità allo sviluppatore;
   ∗ Il manutentore è Apache Foundation che ha reso Open Source il linguaggio;
   ∗ La documentazione è un ulteriore punto di forza, molto chiara e ben approfondita.

Svantaggi
   ∗ Groovy possiede molteplici annotazioni specifiche per l’utilizzo del linguaggio,
     come quelle inerenti alla tipizzazione di cui sopra. Questo rappresenta anche
     uno difetto, in quanto le annotazioni, se non utilizzate come documentazione del
     codice, rischiano di risultare invasive;
   ∗ Non è un linguaggio di programmazione che "riscuote successo" alla pari di Scala
     oppure Kotlin e nella comunità Open Source rimane in una cerchia abbastanza
     ristretta;
   ∗ La parziale interoperabilità con Java è un difetto non trascurabile dal momento
     che è una discriminante molto importante per questo studio.

Conclusioni
Groovy è un linguaggio che presenta una sintassi che non si discosta molto da quella
di Java (come nel caso di Kotlin), facilitando un’eventuale migrazione verso questo
ultimo. Per contro lo scarso interesse riscontrato nella comunità Open Source non lo
mette in buona luce come candidato. Inoltre in azienda è parzialmente utilizzato per
la scrittura di test automatici grazie al framework SoapUI, che però è in dismissione,
cercando di favorire librerie sviluppate in Java.

4.1.4     Scala
Vantaggi
   ∗ La possibilità di adottare il paradigma funzionale senza rinunciare alla program-
     mazione orientata agli oggetti fa di Scala il tratto distintivo più importante. Il
  7 Dmitry   Jemerov, Kotlin in Action.
12                           CAPITOLO 4. STUDIO E ANALISI DELLE TECNOLOGIE

        concetto di base per cui le funzioni sono cittadini di primo ordine porta notevoli
        benefici, testabilità in primis;

      ∗ L’ecosistema di Scala è stato reso Open Source, e la comunità che lo circonda
        esorta gli utilizzatori a contribuire alla sua crescita. In questo caso il linguaggio
        è stato creato da ricercatori della Scuola Politecnica di Losanna, ambiente
        che è stato determinante per la progettazione del linguaggio;

      ∗ Il supporto è costante, la documentazione è ampia e approfondita. Da non sotto-
        valutare la presenza di innumerevoli risorse come libri, articoli e conferenze
        che trattano Scala in ogni suo aspetto.

Svantaggi
      ∗ Scala è considerato un linguaggio di programmazione che presenta una curva
        di apprendimento ripida a causa del paradigma funzionale e per una sintassi
        nettamente diversa da Java. Nonostante la quantità di risorse di apprendimento
        disponibili, perfezionare la conoscenza del linguaggio non è facile e il tempo
        richiesto potrebbe essere molto.

Conclusioni
Scala è un linguaggio dalle ottime potenzialità a causa di tutti i pregi che presenta
grazie ad una progettazione eseguita con cognizione di causa per quanto riguarda la
qualità del software e la produttività8 . La maturità e il largo utilizzo, soprattutto
in realtà in cui efficienza ed efficacia sono di massima importanza, sono proprietà
fondamentali e in questo caso soddisfatte in pieno. La ripida curva di apprendimento è
l’unico ostacolo evidenziato nel corso dell’analisi.

4.1.5          Clojure
Vantaggi
      ∗ Utilizza il paradigma funzionale, essendo un dialetto del linguaggio LISP[g] .
        Questa proprietà porta notevoli benefici come nel caso di Scala;

      ∗ Come per gli altri linguaggi, anche in questo caso è la comunità Open Source a
        far maturare l’ecosistema;

      ∗ L’obiettivo principale è rendere più semplice la creazione di applicazioni concor-
        renti e parallele, sfruttando l’immutabilità e alcuni costrutti che sono specifici
        di questo linguaggio, come gli atoms.

Svantaggi
      ∗ Obbliga a utilizzare esclusivamente il paradigma funzionale, quindi manca di
        flessibilità rispetto a Scala;

      ∗ La sintassi di Clojure è estremamente differente da quella di Java, obbligando lo
        sviluppatore ad un periodo di formazione che sicuramente supererebbe quello
        richiesto per Scala;
     8 Paul   Chiusano, Functional Programming in Scala.
4.2. ENTERPRISE APPLICATION FRAMEWORK                                                   13

   ∗ Manca un supporto stabile per Integrated Development Environment (IDE) come
     Eclipse e IntelliJIDEA. L’editor di testo più indicato è Emacs, che risulterebbe
     estraneo alle regole di sviluppo aziendali.

Conclusioni
Clojure è molto interessante perché tra tutti i linguaggi analizzati è quello che obbliga
a ragionare solamente col paradigma funzionale. Come precedentemente descritto,
questo aspetto porta anche degli svantaggi, e nel dominio applicativo cui questo
progetto fa capo, non risulta essere una buona soluzione. Inoltre la migrazione da Java
richiederebbe una quantità di tempo eccessiva. Il mancato supporto a strumenti di
sviluppo che sono standard per l’azienda è un ulteriore discriminante da prendere in
considerazione.

4.2       Enterprise application framework
In questa sezione verranno presentati i framework e le librerie analizzate come alterna-
tive a Java Enterprise Edition e all’application server JBoss. Gli aspetti analizzati
sono:

   ∗ Enterprise: Sì - No. Specifica se la libreria o il framework analizzato è utlizzabile
     in ambito enterprise;
   ∗ JPA: Sì - No. Uno dei requisiti di questa analisi è la possibilità di utilizzare Java
     Persistence API (JPA) per poter usufruire della persistenza su una base di dati;
   ∗ Documentazione: Insufficiente - Buona - Ottima;
   ∗ Integrazione: nome del linguaggio utilizzabile. Questo aspetto è fondamentale
     per poter scegliere un framework che possa essere integrabile con i linguaggi
     analizzati;
   ∗ Altri aspetti: presenti nello studio, ma non inseriti nella tabella di comparazione
     perché di secondaria importanza.

                           Tabella 4.2: Confronto Framework.

 Nome      Enterprise      JPA     Documentazione          Integrazione

 Spring          Sì          Sì           Ottima            Kotlin/Scala

 Grails          Sì          Sì           Ottima              Groovy

  Play          No           Sì           Buona             Java/Scala

4.3       Conclusione dell’analisi
Di seguito sono riportati i risultati dell’analisi, completi delle tecnologie scelte per la
prosecuzione del progetto di stage:
14                      CAPITOLO 4. STUDIO E ANALISI DELLE TECNOLOGIE

     ∗ Kotlin: in prima istanza Scala è risultato essere migliore sotto molti aspetti,
       ma a causa della ripida curva di apprendimento si è pensato di sceglier Kotlin.
       L’interoperabilità con Java e la somiglianza con la sua sintassi ne fanno un
       linguaggio ottimo da utilizzare come alternativa;
     ∗ Spring: è notoriamente l’alternativa più famosa a Java EE. Spring è sviluppato
       e manutenuto da Pivotal, che ha reso Open Source il progetto Spring Boot,
       per la creazione di microservizi. Spring si è rivelato essere molto affidabile in
       seguito all’analisi eseguita, largamente utilizzato e integrabile sia con Java, sia
       con Kotlin. La documentazione è chiara e ben strutturata, ricca di esempi con
       listati di Java e Kotlin.
Capitolo 5

Ambiente e strumenti

In questo capitolo verranno illustrati l’ambiente di lavoro e gli strumenti utilizzati.

5.1      Ambiente di lavoro
L’ambiente di lavoro scelto è la distribuzione Linux denominata Kubuntu nella sua
versione 16.04.

5.2      Strumenti
5.2.1     Organizzativi e di documentazione
   ∗ Jira: strumento organizzativo usato per la gestione di progetto, in particolare
     per la metodologia di sviluppo Scrum. Fa parte della suite messa a disposizione
     di Atlassian e usata internamente all’azienda;

   ∗ Confluence: strumento facente parte della suite messa a disposizione da Atlas-
     sian, usato per la gestione della documentazione. Usato internamente all’azienda.

5.2.2     Sviluppo
   ∗ IntelliJ IDEA: IDE sviluppato e mantenuto da Jetbrains, usato per la codifica
     del software;
   ∗ JDK 1.8: Kit di sviluppo per il linguaggio di programmazione Java comprendente
     strumenti come il compilatore javac, il tool documentale javadoc e altri. La JDK
     versione 1.8 distribuita da Oracle;

   ∗ Spring Boot: framework per la creazione di microservizi.                  È prodotto e
     mantenuto da Pivotal;
   ∗ Kotlin: linguaggio di programmazione Open Source mantenuto da Jetbrains;
   ∗ GitLab: server e repository per il versionamento del codice sorgente;

   ∗ Jenkins: server e strumento di Continuous Integration (CI) per l’automatizza-
     zione della fase di build del progetto.

                                              15
Capitolo 6

 Analisi dei requisiti

 Questo capitolo approfondisce l’analisi dei requisiti in merito alla creazione del microservizio

 6.1      Consolidamento dei requisiti
 Di seguito verrà espanso e consolidato il requisito min02: realizzazione di un
 microservizio con un linguaggio eseguibile da JVM. Il codice dei requisiti è
 così strutturato R(F/S)(OB/DE/OP) X.Y.Z dove:

 R = requisito
 F = funzionale
  S = sicurezza
OB = obbligatorio (necessario)

DE = desiderabile
OP = opzionale
 X = requisito di primo livello

 Y = requisito di secondo livello
 Z = requisito di terzo livello

 6.1.1     Requisiti del sistema
 Nelle tabelle 6.1 e 6.2 sono riassunti i requisiti e il loro tracciamento con gli use case
 delineati in fase di analisi.

                                               17
18                                      CAPITOLO 6. ANALISI DEI REQUISITI

                    Tabella 6.1: Tabella dei requisti funzionali

 Requisito    Descrizione
 RFOB-1.0.0   Il sistema deve emettere un certificato
 RFOB-1.1.0   Deve accettare un PKCS10
 RFOB-2.0.0   Il sistema deve revocare un certificato
 RFOB-2.1.0   Deve accettare un serial number che identifica il certificato
 RFOB-3.0.0   Il sistema deve sospendere un certificato
 RFOB-3.1.0   Deve accettare un serial number che identifica il certificato
 RFOB-4.0.0   Il sistema deve riattivare un certificato
 RFOB-4.1.0   Deve accettare un serial number che identifica il certificato
 RFOB-5.0.0   Il sistema deve permettere di configurare una Certification Authority
 RFOB-5.1.0   Deve permettere di configurare la codifica della richiesta da mandare
              alla Certification Authority
 RFOB-5.2.0   Deve permettere di configurare la decodifica della risposta ricevuta
              dalla Certification Authority
 RFOB-5.3.0   Deve permettere di configurare i parametri per comunicare con la
              Certification Authority

                   Tabella 6.2: Tabella dei requisti di sicurezza

 Requisito    Descrizione
 RSOB-1.0.0   I parametri di comunicazione con Certification Authority sono cifrati
 RSOB-1.1.0   La cifratura deve essere eseguita in modo simmetrico
 RSOB-1.1.1   Deve usare l’algoritmo AES-256
 RSOB-2.0.0   Il sistema deve firmare digitalmente le richiesta con un PKCS12
 RFOB-2.1.0   Il PKCS12 è appartenente ad un Registration Authority Officer
              autorizzato
6.2. CASI D’USO                                                                       19

6.2     Casi d’uso
Per lo studio dei casi di utilizzo del prodotto sono stati creati dei diagrammi. I
diagrammi dei casi d’uso (in inglese Use Case Diagram) sono diagrammi di tipo Unified
Modeling Language (UML) dedicati alla descrizione delle funzioni o servizi offerti da un
sistema, così come sono percepiti e utilizzati dagli attori che interagiscono col sistema
stesso.

                             Figura 6.1: Koraca Use Cases

UC1: Emissione di un nuovo certificato
Attori Principali: Registration Authority, Certification Authority.
Precondizioni: La Registration Authority è autorizzata all’operazione.
Descrizione: È possibile emettere un nuovo certificato.
Postcondizioni: Il sistema è pronto per permettere una nuova interazione.

UC2: Revoca di un certificato
Attori Principali: Registration Authority, Certification Authority.
Precondizioni: La Registration Authority è autorizzata all’operazione.
Descrizione: È possibile revocare un certificato.
Postcondizioni: Il sistema è pronto per permettere una nuova interazione.

UC3: Riattivazione di un nuovo certificato
Attori Principali: Registration Authority, Certification Authority.
Precondizioni: La Registration Authority è autorizzata all’operazione.
Descrizione: È possibile riattivare un certificato.
20                                          CAPITOLO 6. ANALISI DEI REQUISITI

Postcondizioni: Il sistema è pronto per permettere una nuova interazione.

UC4: Sospensione di un nuovo certificato
Attori Principali: Registration Authority, Certification Authority.
Precondizioni: La Registration Authority è autorizzata all’operazione.
Descrizione: È possibile sospendere un certificato.
Postcondizioni: Il sistema è pronto per permettere una nuova interazione.

6.3     Tracciamento dei requisiti
Da un’attenta analisi dei requisiti e dei casi d’uso effettuata sul progetto è stata stilata
la tabella che traccia i requisiti in rapporto agli use case.
Sono stati individuati diversi tipi di requisiti e si è quindi fatto utilizzo di un codice
identificativo per distinguerli.
Nelle tabelle 6.3 e 6.4 sono riassunti i requisiti e il loro tracciamento con gli use case
delineati in fase di analisi.
6.3. TRACCIAMENTO DEI REQUISITI                                                        21

             Tabella 6.3: Tabella del tracciamento dei requisti funzionali

Requisito      Descrizione                                                     Use Case
RFOB-1.0.0     Il sistema deve emettere un certificato                         UC1
RFOB-1.1.0     Deve accettare un PKCS10                                        UC1
RFOB-2.0.0     Il sistema deve revocare un certificato                         UC2
RFOB-2.1.0     Deve accettare un serial number che identifica il               UC2
               certificato
RFOB-3.0.0     Il sistema deve sospendere un certificato                       UC4
RFOB-3.1.0     Deve accettare un serial number che identifica il               UC4
               certificato
RFOB-4.0.0     Il sistema deve riattivare un certificato                       UC3
RFOB-4.1.0     Deve accettare un serial number che identifica il               UC3
               certificato

             Tabella 6.4: Tabella del tracciamento dei requisiti qualitativi

Requisito      Descrizione                                                     Use Case
RSOB-1.0.0     I parametri di comunicazione con Certification                  UC1-2-3-4
               Authority sono cifrati
RSOB-1.1.0     La cifratura deve essere eseguita in modo simmetrico            UC1-2-3-4
RSOB-1.1.1     Deve usare l’algoritmo AES-256                                  UC1-2-3-4
RSOB-2.0.0     Il sistema deve firmare digitalmente le richiesta con un        UC1-2-3-4
               PKCS12
RFOB-2.1.0     Il PKCS12 è appartenente ad un Registration Authority           UC1-2-3-4
               Officer autorizzato
Capitolo 7

Progettazione

In questo capitolo verrà illustrata la progettazione del software tramite diagrammi UML e
relative descrizioni.

7.1     Progettazione
7.1.1    Architettura

                          Figura 7.1: Architettura del Proxy

                                           23
24                                               CAPITOLO 7. PROGETTAZIONE

7.1.2      Classi
Package REST

                               Figura 7.2: Modulo REST

                    Figura 7.3: Modulo REST: bean risposta/richiesta

     Di seguito verranno descritte le classi del package REST:

CertificateController e CertificateControllerImpl: Punto di entrata per le ri-
     chieste che hanno come scopo le operazioni sui certificati delineate nei requisiti,
     ovvero emissione, revoca, sospensione e riattivazione;
7.1. PROGETTAZIONE                                                                 25

CertificateManager e CertificateManagerImpl: Facade per permettere al pac-
     kage REST di inoltrare le richieste al package CORE dell’applicazione;

UpdateRequest: Classe immutabile usata per deserializzare il payload JSON conte-
    nuto nella richiesta di sospensione e riattivazione del certificato;
RevokeRequest: Classe immutabile usata per deserializzare il payload JSON conte-
    nuto nella richiesta di revoca del certificato;

EmissionRequest: Classe immutabile usata per deserializzare il payload JSON
    contenuto nella richiesta di emissione;
CertificateEmissionRestResponse: Classe immutabile usata per la serializzazione
     della risposta di emissione del certificato in un payload JSON;
CertificateRevokeRestResponse: Classe immutabile usata per la serializzazione
     della risposta di revoca del certificato in un payload JSON.
CertificateUpdateRestResponse: Classe immutabile usata per la serializzazione
     della risposta di sospensione o riattivazione del certificato in un payload JSON.
26                                               CAPITOLO 7. PROGETTAZIONE

Package CORE

                              Figura 7.4: Modulo CORE

     Di seguito verranno descritte le classi del package CORE:

CertificateEmitterService e CertificateEmitterServiceImpl: Interfaccia e re-
     lativa implementazione che rende più granulare l’operazione di emissione di un
     certificato;

CertificateRevokerService e CertificateRevokerServiceImpl: Interfaccia e re-
     lativa implementazione che rende più granulare le operazioni di revoca, sospen-
     sione e riattivazione di un certificato;
7.1. PROGETTAZIONE                                                                      27

SecurityManager: Classe che si occupa della decifrare il token usato per la connes-
    sione alla Certification Authority richiesta dalla Registration Authority;

ConnectorFactory e ConnectorFactoryImpl: Abstract factory che si occupa del-
    la creazione della classe che verrà usata per eseguire le chiamate alla Certification
    Authority;

EmissionRequest: Classe immutabile usata per deserializzare il payload JSON
    contenuto nella richiesta di emissione;

ConnectorManager: Interfaccia che viene implementata da un Connector esponendo
    i metodi per l’emissione, la revoca, la riattivazione e la sospensione del certificato;

Package CONNECTOR

                          Figura 7.5: Modulo CONNECTOR

   Di seguito verranno descritte le classi del package CONNECTOR:

SignacertConnectorManager: Classe che implementa l’interfaccia ConnectorMa-
    nager che contiene la logica per istanziare un CAClient del tipo Signacert;

CAClient: Interfaccia che deve essere implementata da un client per una specifica
   Certification Authority;
28                                                 CAPITOLO 7. PROGETTAZIONE

ClientCache: Incapsula la logica per la gestione di una cache che permette di ottenere
     un’istanza di un CAClient data una specifica chiave;

SignacertClient: Implementazione di CAClient che contiene i parametri di connessio-
     ne alla Certification Authority denominata Signacert e che esegue la trasmissione
     e la ricezione dei dati;
SignacertRequestEncoder: Classe che ha come scopo la codifica in PKIMessage
     della richiesta;

SignacertRequestDecoder: Classe che ha come scopo la decodifica della risposta
     della Certification Authority Signacert in un modello interpretabile dal software.

7.2      Design Pattern utilizzati
Di seguito sono elencati i design pattern applicati nella progettazione e conseguente
sviluppo del software.

7.2.1     Abstract Factory
Applicato nel package CORE per la produzione di istanze delle classi che implementano
ConnectorManager. La creazione viene decisa tramite un identificativo che rappresenta
univocamente una specifica Certification Authority all’interno del software tramite
il nome della classe. Ogniqualvolta è necessario aggiungere una CA supportata è
sufficiente implementare l’interfaccia ConnectorManager. Una richiesta indirizzata a
quella specifica CA si realizzerà con la creazione dell’istanza di quella classe tramite la
factory.

7.2.2     Dependency Injection
Usata in tutti i package del software per diminuire l’accoppiamento tra le classi
e sfruttando le interfacce con relative implementazioni. Si è usato il sistema di
Dependency Injection proprio del framework di Spring Boot.
Capitolo 8

Sviluppo

In questo capitolo viene trattato lo sviluppo dell’applicativo, package per package, seguendo
la progettazione di cui ai capitoli precedenti.

8.1      Struttura del progetto
Il progetto è stato strutturato seguendo le linee guida di sviluppo interne all’azienda
Infocert S.p.A. Per questo motivo si è pensato di creare un modulo root e tre sotto-
moduli, corrispondenti ai package definiti nel periodo di progettazione. Di seguito è
riportata l’alberatura delle cartelle di primo livello.

8.2      Sviluppo modulo REST
Il modulo REST contiene le classi necessarie alla definizione delle API RESTful
dell’applicativo.

8.2.1     Definizione delle risorse
La definizione delle risorse REST è fatta tramite le classi che presentano il suffisso
Controller. Il codice include l’utilizzo delle annotation Java necessarie per poter creare
la documentazione di Swagger API.
@RequestMapping (
     path = arrayOf ( " " ) ,
     method = arrayOf ( RequestMethod . POST ) ,
     consumes = arrayOf ( MediaType . APP LIC AT ION _J SON _VA LU E ) ,
     produces = arrayOf ( MediaType . APP LIC AT ION _J SON _VA LU E )
)
@ApiOperation ( value = " Emit c e r t i f i c a t e " , response =
    C e rt E m is s i on R e st R e sp o n se :: class )
fun emitCertificate (
     @RequestHeader ( value = " r a c a −t o k e n " ) racaToken : String ,
     @RequestBody certEmissionRequest : CertEmissionRequest
) : ResponseEntity < Any >
                                                                                                

                                             29
30                                                         CAPITOLO 8. SVILUPPO

     Di seguito l’implementazione relativa.
override fun emitCertificate (
     @RequestHeader ( value = " k o r a c a −t o k e n " ) koracaToken : String ,
     @RequestBody certEmissionRequest : CertEmissionRequest
) : ResponseEntity < Any > =
     Eithers . getRightOrLeft (
         certificateManager
                   . emitCertificate ( certEmissionRequest , racaToken )
                   . peek { result -> logger . info ( result . toString () )
                        }
                   . map { result -> Responses . ok (
                             C e rt E m is s i on R e st R e sp o n se ( Base64 .
                                   getEncoder ()
                                    . encodeToString ( result . certificate ?.
                                          encoded ) ) )
                   }. peekLeft { error -> logger . error ( error . message )
                        }
                   . mapLeft { error -> Responses . badRequest ( error ) }
     )
                                                                                            
L’utilizzo delle Data Class del linguaggio Kotlin hanno velocizzato di molto la creazione
di classi per definire strutture immutabili utilizzate per la rappresentazione di oggetti
JSON; di seguito un esempio della semplicità di queste strutture.
data class Cer tS tat us Res tR esp ons e @JsonCreator constructor (
        val status : String ,
        @Nullable val reason : Int ? ,
        val certificate : String ?
)
                                                                                            
8.3. SVILUPPO MODULO CORE                                                                   31

8.2.2      Manager
Le classi che presentano il suffisso Manager sono addette all’incapsulamento della
logica necessaria per interfacciarsi col modulo CORE ove vivono le classi Service che
contengono la vera e propria logica di business.

@Component
class Cer tif ic ate Ma nag erI mp l (
    @Autowired
    val c e r t i fi c a t e E m i t t er S e r v i c e : CertificateEmitterService ,

      @Autowired
      val c e r t i fi c a t e R e v o k er S e r v i c e : CertificateRevokerService ,

      @Autowired
      val c e r t i f i c a t e S t a t u s R e t r i e v e r S e r v i c e :
          CertificateStatusService ,

      @Autowired
      @Qualifier ( " k o r a c a c o n f i g " )
      @KoracaConfig ( Property . CONNECTOR_KEY )
      private val keyStorePassword : String

) : CertificateManager {

      private val logger = LoggerFactory . getLogger ( javaClass )

      override fun emitCertificate (
               certEmissionRequest : CertEmissionRequest ,
               racaToken : String
      ) : Either < KoracaError , CertEmissionResult > =
           getConnectorConfig ( racaToken )
               . peek { connector -> logger . info ( "Got c o n n e c t o r : $ {
                     connector . json }") }
               . flatMap {
                     connector ->
                     c e r t i f ic a t e E m i t t e rS e r v i c e . emit ( connector ,
                            certEmissionRequest )
               }
               . peek { result -> logger . info ( result . certificate .
                     toString () ) }
                                                                                                 

8.3       Sviluppo modulo CORE
Il modulo CORE contiene la logica di business dell’applicativo.

8.3.1      Service
Le classi Service sono responsabili di prendere in carico le richieste che provengono
dall’interfaccia REST e di delegare la manipolazione dei dati ad un Connector.
32                                                       CAPITOLO 8. SVILUPPO

8.3.2    Connector
Questa classe si occupa della creazione dell’implementazione di un ConnectorManager
ricevendo come input un ConnectorConfig. Quest’ultimo è un oggetto costruito tramite
la deserializzazione di un koraca-token: un oggetto JSON che è cifrato in modo
simmetrico con una chiave AES-256.

fun decrypt ( b64Token : String , key : String ) : Either < KoracaError ,
    ConnectorConfig > =
    ‘try ‘ { Base64 . getDecoder () . decode ( b64Token ) }
         . toEither ()
         . mapLeft { error -> KoracaError ( Errors . GeneralErrors .
              INVALID_CONNECTOR_CONFIG , error . message . orEmpty () ) }
         . flatMap { encryptedCfg -> Cyphers . decrypt ( encryptedCfg ,
              key ) }
         . flatMap { json -> unmarshall ( json ) }
                                                                                       
Di seguito il metodo che si occupa della deserializzazione.

private fun unmarshall ( json : String ) : Either < KoracaError ,
    ConnectorConfig > =
    ‘try ‘ { ConnectorConfig ( Gson () . fromJson ( json , JsonObject ::
        class . java ) ) }
         . toEither ()
         . peekLeft { error -> logger . error ( error . message . orEmpty ()
              ) }
         . mapLeft { error -> KoracaError ( Errors . GeneralErrors .
              INTERNAL_SERVER_ERROR , error . message . orEmpty () ) }
         . peek { cfg -> logger . info ( " U n m a r s h a l l e d j s o n t o
              c o n n e c t o r c o n f i g : " + cfg . toString () ) }
         . map { cfg -> cfg }
                                                                                       
La creazione della corretta implementazione di ConnectorManager è stata realizzata
utilizzando la classe ApplicationContext che consente di recuperare tutte le classi
annotate come @Component che si sono registrate nel container Spring.

@Autowired private lateinit var context : ApplicationContext
// ...
return Option . of ( connectorRegister . getConnectorClass (
     connectorConfig . json [ " @type " ]. asString ) )
         . toEither ( KoracaError ( Errors . GeneralErrors .
              INVALID_CONNECTOR ) )
         . map { clazz -> context . getBean ( clazz ) as
              ConnectorManager }
                                                                                       

8.4     Sviluppo modulo CONNECTOR
All’interno di questo package è presente un’unica implementazione di ConnectorMa-
nager : SignacertConnectorManager, che utilizza come Certification Authority quella
denominata Signacert, utilizzata da Infocert S.p.A.
8.4. SVILUPPO MODULO CONNECTOR                                                             33

8.4.1     Decoder ed Encoder

Le principali e più interessanti classi del package sono SignacertRequestEncoder e Signa-
certResponseDecoder. Queste si occupano rispettivamente di codificare e decodificare
messaggi nel formato ASN.1 denominati PKI Message.

fun e n c o d e C e r t R e v o c a t i o n R e q u e s t (
                    cer tRevoc ationR eques t : CertR evoca tionRe quest ? ,
                    raoCert : X509Certificate ,
                    caDN : String ,
                    signerPrivateKey : PrivateKey
) : Either < KoracaError , ASN1Primitive > {
     val pkiMessage = ASN1EncodableVector ()
     val pkiHeader = ASN1EncodableVector ()
     try {
            // Building PKI MESSAGE HEADER
            pkiHeader . add (
                            ASN1Integer (2)
            )
            pkiHeader . add (
                            GeneralName ( GeneralName . directoryName , raoCert .
                                   subjectX500Principal . name ) )
            pkiHeader . add ( GeneralName ( GeneralName . directoryName , caDN
                   ))
            // Protection Algorithm
            pkiHeader . add ( DERTaggedObject ( true , 1 ,
                   AlgorithmIdentifier (
                            ASN1ObjectIdentifier ( OIDHelper .
                                   sha 1With R SAEnc ryptio n . oid ) , DERNull . INSTANCE ) )
                                   )
            // Sender Nonce
            pkiHeader . add ( DERTaggedObject ( true , 5 , DEROctetString (
                   BCUtil . generateNonce () ) ) )
            // Setting PKIHeader in PKI Message
            pkiMessage . add ( DERSequence ( pkiHeader ) )
            val revReqContent = ASN1EncodableVector ()
            val revDetails = ASN1EncodableVector ()
            val certTemplateBuilder = CertTemplateBuilder ()
            // Building template throughout serial number
            certTemplateBuilder . setSerialNumber ( ASN1Integer (
                   cer tRevoc ation Reques t !!. serial ) )
            revDetails . add ( certTemplateBuilder . build () )
            //
            // Omittted
            //
     } catch ( exception : Exception ) {
            logger . warn ( exception . message , exception )
            return left ( KoracaError ( SignacertError .
                   INVALID_STATUS_REQUEST , exception . message . orEmpty () ) )
     }
}
                                                                                                 
34                                                            CAPITOLO 8. SVILUPPO

8.4.2     Client
Una volta codificato il PKI Message è necessario utilizzare il SignacertClient per
aprire una connessione tramite Socket per poter inviare e ricevere dati verso e dalla
Certification Authority Signacert.
fun sendToCa ( dataToSend : ByteArray ?) : ByteArray {
    LOGGER . info ( "CA URL i s : $ { t h i s . c a U r l } \n CA p o r t i s : $ { t h i s .
        caPort }")
    try {
        Socket ( this . caUrl , this . caPort ) . use { serverSocket ->
              DataOutputStream ( serverSocket . getOutputStream () ) . use
                   { socketOut ->
                    DataInputStream ( serverSocket . getInputStream () ) .
                        use { socketIn ->
                         serverSocket . soTimeout = this . caTimeout
                         serverSocket . tcpNoDelay = true
                         socketOut . writeInt ( dataToSend !!. size + 1)
                         socketOut . write (0 x0 )
                         socketOut . write ( dataToSend )
                         socketOut . flush ()
                        val byteToRead = socketIn . readInt () - 1
                        val type = socketIn . readByte ()
                         LOGGER . info ( String . format ( "CA r e s p o n s e t y p e :%
                             d" , type ) )
                        val buffer = ByteArray ( byteToRead )
                         socketIn . readFully ( buffer )
                        if ( LOGGER . isTraceEnabled ) {
                              LOGGER . trace ( Base64 . getEncoder () .
                                   encodeToString ( buffer ) )
                        }
                         return buffer
                    }
              }
        }
    } catch ( e : IOException ) {
        LOGGER . error ( e . message , e )
        throw RuntimeException ( e . message , e )
    }
}
                                                                                                
Capitolo 9

Verifica e validazione

Questo capitolo tratta la verifica e la validazione del prodotto software.

9.1      Introduzione
L’attività di verifica e validazione sono state attuate tramite la creazione di test di:

   ∗ unità: per la verifica puntuale di classi e componenti;

   ∗ integrazione: per verificare l’efficacia dell’intero flusso applicativo;

   ∗ performance: per verificare la resilienza del software quando sottoposto a grandi
     carichi di richieste.

Per la scrittura ed esecuzione dei test di unità e integrazione è stato usato il framework
JUnit v4, mentre per i test di performance il framework TestNG.

9.1.1     Test di Unità
Il modulo signacert-connector contiene la maggior parte della logica di business
meritevole di essere verificata grazie ad una suite di test di unità.

Encoder e Decoder
I primi test sono stati scritti per verificare l’efficacia delle classi che si occupano della
codifica di una richiesta e della decodifica di una risposta.

   ∗ Encoding: i test a proposito dell’encoding sono stati fatti utilizzando parametri
     statici per la creazione di istanze di una classe rappresentante il modello di
     richiesta inviata da una Registration Authority. In seguito viene invocato il
     metodo di encoding della classe sottoposta a test SignacertRequestEncoding.
     Essendo di complicata interpretazione, l’oggetto risultante dalla codifica è soggetto
     ad una verifica manuale e visiva nel formato ASN.1 per verificare la presenza o
     l’assenza di tutti i campi richiesti facendo riferimento al documento RFC-2459;

   ∗ Decoding: è stata usata la rappresentazione in base64 di una risposta valida e
     una non valida di una Certification Authority nel caso di emissione di certificato.
     In seguito all’ottenimento del array di byte creato a partire dalla stringa si è

                                             35
36                                       CAPITOLO 9. VERIFICA E VALIDAZIONE

       invocato il metodo della classe SignacertResponseDecoding e verificata la corret-
       tezza campo per campo dell’oggetto restituito dal metodo. Sono stati creati più
       test per verificare il corretto comportamento del software nel caso di problemi e
       casi limite.

SignacertClient
La verifica dell’efficacia della classe che si occupa della comunicazione con la Certification
Authority è stata eseguita anche tramite un test di unità che, tramite l’utilizzo di
un mock della stessa Certification Authority, ha verificato anche la resilienza del
software in caso di ritardi oppure errori nella comunicazione. Infatti il mock è stato
reso configurabile nei tempi di risposta o nella restituzione di errori, per esempio di
indisponibilità, mettendo la classe sotto test in condizione di rispondere correttamente
all’eccezione.

9.1.2     Test di Integrazione
Il test di integrazione più importante verifica la comunicazione col prodotto sviluppato e
il dialogo tra quest’ultimo e una Certification Authority. Il test deve essere eseguito una
volta che il software è in esecuzione in un server(che può essere locale oppure remoto);
il cuore del test sta nella simulazione di un’interazione tra una Registration Authority
e il prodotto tramite la creazione ed esecuzione di una richiesta HTTP contenente i
parametri necessari per l’emissione, la revoca, la riattivazione e la sospensione di un
certificato.

9.1.3     Test di performance
I test di performance sono stati eseguiti paragonando KORACA (CA-PROXY) e
RACA, ovvero il software preesistente. I test sono stati parametrizzati per poter essere
cambiati nel numero di chiamate e numero di thread paralleli. Sono state prese in
considerazione le seguenti combinazioni:

     ∗ Chiamate / Numero Thread paralleli: 100/1, 100/2, 100/3, 100/4, 100/5,
       100/10, 1000/5.
I grafici prodotti rappresentano in ordine di apparizione:
     ∗ Tempo totale di risposta in minuti;

     ∗ Tempo medio di risposta in minuti;
     ∗ Utilizzo della CPU, in percentuale;
     ∗ Utilizzo della RAM, in percentuale.
9.1. INTRODUZIONE                                           37

                    Figura 9.1: Tempo totale di risposta.

                    Figura 9.2: Tempo medio di risposta.
38                                     CAPITOLO 9. VERIFICA E VALIDAZIONE

                             Figura 9.3: Utilizzo della CPU.

                            Figura 9.4: Utilizzo della RAM.

Conclusioni
In seguito ai test di performance sono state tratte le seguenti conclusioni in merito al
comportamento del prodotto software sviluppato:

     ∗ Per quanto riguarda i tempi di risposta i due software si comportano nello stesso
       modo, senza nette differenze in termini di tempo. Al crescere del numero di
       thread paralleli e mantenendo costante il numero di chiamate i tempi di risposta
       si stabilizzano tra 0.1 e 0.2. Quando invece il numero di chiamate arriva a 1000,
       i tempi si allungano notevolmente;

     ∗ In merito all’utilizzo della CPU anche in questo caso il comportamento è simile e
       piuttosto prevedibile. La crescita del numero di chiamate e del numero di thread
Puoi anche leggere