% !TEX encoding = UTF-8
% !TEX TS-program = pdflatex
% !TEX root = ../../tesi.tex
\subsection{JMeter - Modalità Distribuita}
Prima di descrivere la progettazione di JMeterOrchestrator, vorrei iniziare questa sezione con una panoramica del funzionamento di JMeter in modalità distribuita (cluster mode), in modo da chiarire quali azioni fossero direttamente gestite da JMeter e specificare quali procedure invece sarebbero state prese in carico dall'orchestratore. \\
JMeter quando viene eseguito in cluster mode si divide in due entità:
\begin{itemize}
	\item \textbf{Master}: la macchina, fisica o virtuale, responsabile di coordinare le macchine slave e collezionare i dati da queste prodotti.
	\item \textbf{Slaves}: le macchine, fisiche o virtuali, responsabili di generare le richieste al server di destinazione, chiamato target.
\end{itemize}
L'esecuzione di JMeter in modalità distribuita avviene con l'immissione, tramite \gls{cli} sulla macchina master, di un comando simile:\\\\
\texttt{jmeter -n -t file.jmx -R 127.0.0.1 -l risultati.csv -e -o report}\\\\
Dove i parametri possiedono il seguente significato:
\begin{itemize}
	\item \textbf{-n}: non aprire la \gls{gui}, in modo da risparmiare RAM;
	\item \textbf{-t}: indica il file da utilizzare come test;
	\item \textbf{-R}: specifica gli indirizzi IP degli slaves da usare per l'esecuzione del test;
	\item \textbf{-l}: indica dove salvare i risultati;
	\item \textbf{-e -o}: indica dove generare il report HTML.
\end{itemize}
Il master assume quindi che gli slaves esistano e il server \gls{rmi}, responsabile di ricevere le indicazione dal master, sia attivo e in stato di ricezione. Il master si assume poi la responsabilità di distribuire il file di test agli slaves, ma, eventuali file di dati (utili per specificare le credenziali degli utenti da simulare o altre configurazioni) devono essere caricati sulle macchine slaves a mano.\\
I file di test, suffissi \texttt{jmx}, non solo racchiudono le richieste da effettuare sulla macchina target ma specificano anche la configurazione del carico da applicare, richiedendo una modifica del file di test in caso si voglia aggiustare qualche parametro della Load Generation. \\
In ultimo i file generati da JMeter vengono semplicemente scritti su disco ma non consumati in qualsivoglia modo, questa caratteristica non è adatta per la realizzazione dei disposable servers, questi infatti vengono eliminati alla fine dei test, cancellando a loro volta i dati prodotti. \\
In sostanza quindi JMeter gestisce solo il coordinamento delle macchine slave, mentre sarà compito dell'orchestratore:
\begin{itemize}
	\item Assicurarsi che le macchine slave esistano (creandole eventualmente) e che abbiano il server \gls{rmi} attivo;
	\item Distribuire eventuali file di dati alle macchine slaves;
	\item Prevedere una modalità di modifica della configurazione di carico senza richiedere la riscrittura del file \texttt{jmx};
	\item Notificare l'avvenuto termine dei test, consegnando i file di risultati prodotti al team Legalmail via E-Mail.
\end{itemize}
\subsection{Principi}
Per la progettazione e successiva implementazione dell'orchestratore sono stati seguiti dei principi, o best practises, per garantire una solida codebase e una non troppo onerosa manutenzione.
\subsubsection{SOLID}
L'acrostico SOLID, descritto da <NAME>. "<NAME>" Martin\footcite{book:designprinciples} all'inizio degli anni 2000, si riferisce a cinque principi fondamentali dello sviluppo software orientato agli oggetti e sono:
\begin{enumerate}
	\item \textbf{Single Responsability Principle (SRP)}: afferma che ogni classe dovrebbe avere una ed una sola responsabilità, interamente incapsulata al suo interno. Questa caratteristica troverà riscontro tramite la realizzazione dei \textbf{components}, come verrà specificato nella sezione successiva;
	\item \textbf{Open/Closed Principle (OCP)}: afferma che un'entità software dovrebbe essere aperta alle estensioni, ma chiusa alle modifiche. Su questo principio è stata riposta molta attenzione in quanto, come spiegato nella sezione precedente, le possibili evoluzioni del prodotto sarebbero dovute risultare poco onerose da implementare;
	\item \textbf{Liskov Substitution Principle (LSP)}: afferma che gli oggetti dovrebbero poter essere sostituiti con dei loro sottotipi, senza alterare il comportamento del programma che li utilizza. Questa caratteristica è implementata di default in Python, in quanto linguaggio aderente al \gls{duck-typing};
	\item \textbf{Interface Segregation Principle (ISP)}: afferma che sarebbero preferibili più interfacce specifiche, che una singola generica. Questa principio viene rispettato con la definizione di più interfacce \textbf{actions} seppur strutturalmente simili, come verrà spiegato nelle sezioni successive;
	\item \textbf{Depedency Inversion Principle (DIP)}: afferma che una classe dovrebbe dipendere dalle astrazioni, non da classi concrete. Come indicato nella struttura del \textbf{Core} dell'orchestratore.
\end{enumerate} 
\subsubsection{KISS}
KISS, acronimo per \textit{Keep It Simple, Stupid}\footcite{article:drykiss}, è un principio che impone di mantenere il codice più semplice possibile. Lo scopo ultimo del codice è infatti quello di essere letto da altri umani: le aziende spendono di più per la manutenzione piuttosto che per sviluppo del software\footcite{article:maintenancesurvey}, quindi gli sviluppatori passano la maggior parte del tempo a sistemare il codice di altri piuttosto che crearne di nuovo.\\
Durante lo sviluppo dell'orchestratore quindi è stata posta molta attenzione sul \gls{refactor}, cercando di semplificare al minimo la logica di ogni parte del programma.
\subsubsection{DRY}
DRY, acronimo di \textit{Don't Repeat Yourself}\footcite{article:drykiss}, è un principio che impone di incapsulare le unità logiche applicative in modo da favorirne il riuso, evitando la ripetizione della stesura di linee di codice. \\
Ripetere in più parti della codebase la stessa funzionalità logica rende onerosa e complicata la manutenzione: la modifica di un concetto logico richiede la riscrittura di più parti dell'applicativo, rendendo difficile tracciare le modifiche effettuate.\\
Anche per questo principio è stata quindi posta molta attenzione sul \gls{refactor} in modo da evitare di incappare nell'antipattern WET, \textit{Wasting Everyone's Time}, esatto contrario del principio DRY.
\subsubsection{Immediately Repair Your Broken Windows}
Per ultimo, ma non meno importante, troviamo il \textit{Immediately Repair Your Broken Windows}\footcite{article:brokenwindow}, principio che unisce teorie dell'ambito della criminologia all'ingegneria del software. In sostanza questa teoria impone che bug, refusi di cattiva progettazione, violazione di principi di programmazione e problemi di questo tipo vadano corretti nell'immediato momento in cui vengono scoperti, in modo da ridurre al minimo il \gls{debito-tecnico}. \\
L'adozione di questo principio, oltre ad essere buona pratica in ogni situazione, assume maggiore rilevanza per il progetto di stage: essendo il tempo a disposizione molto limitato, consegnare un prodotto con bug conosciuti e magari non documentati avrebbe incattivito l'opinione sul software sviluppato, diminuendo le possibilità di adozione da parte dell'azienda e mettendo in cattiva luce la mia reputazione professionale. \\
L'obiettivo del progetto era quindi quello di avere codice, si strutturato e funzionale, ma soprattutto funzionante.

\subsection{Core}
\intro{Per la stesura dei diagrammi mostrati qui di seguito sono stati utilizzati il dizionario e le annotazioni sintattiche del linguaggio di programmazione Python.}\\\\
Il cuore di JMeterOrchestrator è stato progettato in modo da rispettare i principi elencati in precedenza e di limitarsi a ricoprire il ruolo base dell'orchestratore: il coordinamento di elementi specializzati. \\
Questi elementi specializzati prendono il nome di \textbf{actions} e sono descritti da sette interfacce che, una volta implementate, assumono le seguenti responsabilità:
\begin{itemize}
	\item \textbf{Wizard}: responsabile di normalizzare le configurazioni e/o i parametri ricevuti dall'utente in modo da essere utilizzabili dall'orchestratore. Eventualmente il Wizard si occupa anche di creare e iniettare la actions (dipendenze);
	\item \textbf{Provisioner}: responsabile di configurare le macchine slaves ed eventualmente master, tramite una potenziale creazione, per l'esecuzione dei test e, una volta terminato, di riportarle allo stato originario, con eventuale distruzione. Il processo eseguito al termine dei test prende il nome di \textit{cleanup};
	\item \textbf{Dealer}: responsabile di distribuire alle macchine slaves i file di input necessari per l'esecuzione dei test;
	\item \textbf{Parser}: responsabile di modificare la configurazione del file \texttt{jmx} secondo i parametri immessi dall'utente;
	\item \textbf{Runner}: responsabile di avviare la macchina master per l'esecuzione dei test;
	\item \textbf{Consumer}: responsabile di consumare i dati prodotti dall'esecuzione dei test;
	\item \textbf{Catcher}: responsabile di catturare eventuali errori (eccezioni) e notificarle all'utilizzatore del software.
\end{itemize} 
\begin{figure}[H]
	\centering
	\includegraphics[width=13cm]{immagini/interfaces}
	\caption{Diagramma delle interfacce}
	\label{img-diagramma-interfacce}
\end{figure}
Come si può vedere dal diagramma delle classi, queste interfacce sono strutturalmente molto simili: espongono due metodi (al più tre per il \textit{Provisioner}) con firme quasi identiche. Questa differenziazione è stata pensata in modo da rispettare il principio di segregazione delle interfacce (ISP), in modo da rendere immediato al lettore del codice con quale unità logica si stesse confrontando.\\
Il costruttore di tutte le \textit{actions} è senza parametri facilitarne l'iniezione. \\
L'orchestratore, rappresentato dalla classe \textit{JmeterOrchestrator} presenta un'interfaccia molto semplice e propone il pattern \gls{dinje}:
\begin{figure}[H]
	\centering
	\includegraphics[width=6cm]{immagini/coreclass}
	\caption{Classe JmeterOrchestrator}
	\label{img-classe-core}
\end{figure}	
Le varie actions possono essere infatti "iniettate" dall'utente, sia esso fisico o un'altra componente software, tramite il passaggio di parametri al metodo \texttt{fire} o direttamente dal \textit{Wizard} che, in base alla sua implementazione, può essere in grado di crearle. L'utilizzo del pattern \gls{dinje}, oltre a rendere la classe funzionale ed estensibile, permette di rispettare al meglio i concetti OCP e DIP.\\
Il coordinamento effettuato dall'orchestratore è descritto dal seguente diagramma di sequenza:
\begin{figure}[H]
	\centering
	\includegraphics[width=13cm]{immagini/coresequence}
	\caption{Diagramma di sequenza del flusso dell'orchestratore}
	\label{img-core-seqeunce}
\end{figure}
Come si può vedere dal diagramma, alcune \textit{actions}, pur essendo indipendenti, possono necessitare di parametri ricavati da \textit{actions} eseguite precedentemente:
\begin{itemize}
	\item \textbf{Dealer}: può necessitare dei dati del \textit{Provisioner} per conoscere gli identificativi degli slaves ai quali distribuire i files;
	\item \textbf{Parser}: può necessitare dei dati del \textit{Provisioner} per conoscere gli identificativi degli slaves e del \textit{Dealer} per conoscere eventuali modifiche da effettuare al file \texttt{jmx};
	\item \textbf{Runner}: può necessitare dei dati del \textit{Provisioner} per conoscere gli identificativi di master e slaves, dei dati del \textit{Parser} per capire dove recuperare il file \texttt{jmx};
	\item \textbf{Consumer}: può necessitare dei dati del \textit{Runner} per capire dove recuperare i file di risultato prodotti.
\end{itemize}
Gli ultimi attori della progettazione sono rappresentati dai \textbf{components}: unità logiche utilizzate da più \textit{actions}, ma indipendenti da queste ultime, realizzati in modo da avvicinarsi ai principi SRP e DRY.\\
Nelle sezioni seguenti verranno presentate, in forma descrittiva, le \textit{actions} e i \textit{components} implementati per dare significato al prodotto sviluppato. La forma descrittiva è usata in modo da non rivelare troppo i dettagli implementativi delle varie componenti.
\subsection{Actions}
Le \textit{actions} sono raggruppate secondo la loro interfaccia.
\input{capitoli/capitolo-3/actions}
\subsection{Components}
Le funzionalità logiche dell'applicativo sono incapsulate all'interno di classi (annotate in \gls{camelcase}) o moduli (annotati in \gls{snakecase}) e sono così denominate:
\begin{itemize}
	\item \textbf{gzipper}: modulo per la compressione, in formato \texttt{gzip} di file e cartelle;
	\item \textbf{JmxParser}: classe per la gestione delle modifiche ai file \texttt{jmx};
	\item \textbf{LocalMasterRunner}: classe che incapsula la logica d'esecuzione di JMeter;
	\item \textbf{SCPDealer}: classe che incapsula la logica di distribuzione dei files agli slaves via \gls{scp};
	\item \textbf{SCPExecutor}: classe per l'invio di comandi \gls{scp};
	\item \textbf{shell\_helpers}: modulo contenenti funzioni di aiuto per l'esecuzione di comandi sulla \gls{shell};
	\item \textbf{SMTPMailer}: classe che semplifica l'invio delle mail tramite protocollo \gls{smtp};
	\item \textbf{SSHCommandExecutor}: classe che semplifica l'invio di comandi \gls{ssh};
	\item \textbf{TerraformWrapper}: classe per l'esecuzione dei comandi di Terraform direttamente da Python;
	\item \textbf{yaml\_injector}: classe per l'injection delle \textit{actions} tramite YAML.
\end{itemize}
I moduli e le classi descritte possono essere visti come dei \gls{wrapper} di librerie presenti \gls{out-of-the-box} in Python, in modo da semplificarne l'utilizzo e la leggibilità seguendo il principio KISS.
\subsection{Diagramma dipendenze actions-components}
Il diagramma descrive le dipendenze tra le varie \textit{actions} e i \textit{components}, in modo da offrire una visione ad alto livello della collaborazione tra le classi sopracitate.
\begin{figure}[H]
	\centering
	\includegraphics[height=\textheight]{immagini/actionscomponents}
	\caption{Diagramma delle dipendenze tra actions e components}
	\label{img-actioncomponents}
\end{figure}
\section{Implementazione}
Il \textit{core} di JMeterOrchestrator è stato implementato come un \textit{Python Package}\footcite{article:pypackage}. \\
La struttura del package è rappresentata di seguito.
\begin{figure}[H]
	\centering
	\includegraphics[width=6cm]{immagini/implementation}
	\caption{Implementazione del package JMeterOrchestrator}
	\label{img-implementation}
\end{figure}
\subsection{Command Line Interface}
Per l'utilizzo del package è stata sviluppata una \gls{cli} tramite la libreria Python Click\footcite{site:click}, in modo da facilitare l'accesso alle funzionalità della libreria.\\
L'interfaccia utilizza lo \textbf{YamlCliWizard} e permette di specificare nei parametri il file \gls{yaml} dal quale prelevare la configurazione. \\
La \gls{cli} presenta due modalità d'esecuzione:
\begin{enumerate}
	\item \textbf{Standard}: dove l'output viene stampato direttamente sulla \gls{shell} d'esecuzione e quest'ultima viene bloccata fino alla fine del processo;
	\item \textbf{Silent}: dove l'orchestratore viene eseguito in background e l'output stampato in un file specificato tramite parametro dall'utente.
\end{enumerate}
\subsection{Graphical User Interface}
Per facilitare la gestione di più scenari di test, allo stato attuale un'istanza dell'orchestratore può eseguire un solo file di test alla volta, si è deciso di sviluppare una piccola \gls{gui}, utilizzabile via browser e implementata tramite Flask\footcite{site:flask}. \\
Lo sviluppo di un'interfaccia grafica inoltre permette di migliorare l'accessibilità al package, permettendo anche a utenti non avvezzi all'utilizzo di una \gls{shell} di utilizzare il prodotto senza particolari complicazioni.\\
La \gls{gui} amplia le funzionalità della libreria:
\begin{itemize}
	\item Permette l'archiviazione dei file di test all'interno del \gls{filesystem} del server che ospita il software, in modo da semplificare la ripetibilità dell'esecuzione degli scenari di test;
	\item Permette la categorizzazione dei file di test in scenari: entità composte da file di test e istanza di JMeterOrchestrator, in modo da poter eseguire più file di test contemporaneamente.
	\item Permette l'avvio e la terminazione anticipata dell'esecuzione dell'orchestratore;
	\item Permette di scegliere quale \textit{provisioner} utilizzare, tra \textbf{EnsureProvisioner} e \textbf{TerraformAwsProvisioner};
	\item Permette di visualizzare l'output dell'orchestratore direttamente sull'interfaccia web.
\end{itemize}
La \gls{gui} è il componente che verrà effettivamente installato all'interno dell'infrastruttura aziendale.
\begin{figure}[H]
	\centering
	\includegraphics[width=\textwidth]{immagini/guihome}
	\caption{Screenshot pagina Home della GUI}
	\label{img-guihome}
\end{figure}
\begin{figure}[H]
	\centering
	\includegraphics[width=6cm]{immagini/guicreate}
	\caption{Screenshot pagina creazione scenario della GUI}
	\label{img-guicreate}
\end{figure}
 \begin{figure}[H]
 	\centering
 	\includegraphics[width=\textwidth]{immagini/guishow}
 	\caption{Screenshot pagina visualizzazione scenario della GUI}
 	\label{img-guishow}
 \end{figure}