JolieGraph Γ¨ il progetto descritto dalla mia tesi di laurea (UniversitΓ di Bologna, relatore Prof. Ivan Lanese). Analizza staticamente il codice sorgente Jolie, un linguaggio di programmazione orientato ai microservizi, e genera automi finiti che rappresentano ogni percorso di comunicazione tra i servizi.
Il tool esegue il parsing dei programmi Jolie usando la libreria jolie.lang, costruisce Abstract Syntax Tree e genera IDFA (Initially Disconnected Finite Automata) che catturano tutte le primitive di comunicazione: OneWay, RequestResponse, Notification, SolicitResponse. Gestisce tutti i costrutti Jolie inclusi condizionali, cicli, NDChoice, ProvideUntil, gestori di fault e procedure. L'output Γ¨ in formato DOT standard (Graphviz).
Nelle architetture a microservizi, i servizi comunicano attraverso una rete di messaggi β richieste, risposte e notifiche one-way. Al crescere del numero di servizi, comprendere il flusso di comunicazione diventa sempre piu' difficile. JolieGraph risolve questo problema analizzando staticamente il codice sorgente Jolie e generando automaticamente grafi diretti (IDFA) che rappresentano ogni possibile percorso di comunicazione.

Questo servizio Jolie riceve una richiesta notifyAll contenente una lista di destinatari, poi itera su di essi inviando una notifica one-way a ciascuno tramite un servizio esterno NotificationSender. JolieGraph analizza questo codice, attraversa l'AST e costruisce l'automa corrispondente β un grafo compatto che cattura il ciclo e tutte le primitive di comunicazione.
service NotifierService {
inputPort NotifierPort {
RequestResponse:
notifyAll(NotifyRequest)(void)
}
outputPort NotificationSender {
OneWay:
notify(NotificationRequest)
}
main {
notifyAll(request)() {
for (recipient in request.recipients) {
notify@NotificationSender({
.recipient = recipient,
.message = request.message
})
}
}
}
}L'automa generato per NotifierService ha solo 2 stati: lo stato 1 riceve la richiesta in ingresso (INPUT REQUEST), transita allo stato 2, che invia notifiche in un self-loop (OUTPUT ONE-WAY). Dopo il ciclo, la risposta viene inviata (INPUT RESPONSE) e il servizio torna allo stato iniziale. I colori degli archi codificano la direzione: blu per input, rosso per output, verde per le diramazioni.

Un servizio piu' complesso: PaymentService riceve una richiesta di pagamento, delega il controllo del credito a un servizio esterno (RequestResponse), e si dirama β se il credito e' sufficiente, conferma; altrimenti invia un alert e registra il fallimento. Questo dimostra come JolieGraph gestisce le diramazioni condizionali (if/else) e piu' output port.
service PaymentService {
inputPort PaymentPort {
RequestResponse: pay(PaymentRequest)(bool)
}
outputPort CreditChecker {
RequestResponse: check(PaymentRequest)(bool)
}
outputPort Confirmer { OneWay: confirm(string) }
outputPort AlertService { OneWay: alert(string) }
outputPort Logger { OneWay: log(string) }
main {
pay(req)(res) {
check@CreditChecker(req)(res)
if (enoughCredit) {
confirm@Confirmer(req.userId)
} else {
alert@AlertService(req.userId)
log@Logger("Payment failed for " + req.userId)
}
}
}
}L'automa del PaymentService ha 6 stati. Dallo stato 1 (iniziale), riceve la richiesta pay e delega a CreditChecker. Lo stato 4 e' il punto di diramazione: un arco va verso confirm (verde, raggiunge lo stato 6), un altro verso alert+log (il ramo else). Entrambi i percorsi convergono allo stato 5, che invia la risposta. Il grafo rende l'architettura di comunicazione immediatamente visibile β qualcosa impossibile da cogliere solo dal codice in sistemi di grandi dimensioni.

JolieGraph produce output in formato DOT standard (Graphviz), rendendolo facile da visualizzare, integrare o elaborare ulteriormente. Ogni nodo rappresenta uno stato dell'automa, e ogni arco e' etichettato con il tipo di comunicazione (INPUT/OUTPUT), la primitiva (REQUEST, RESPONSE, ONE-WAY), il nome dell'operazione, la porta di destinazione e il tipo di dato. I grafi possono essere renderizzati con qualsiasi strumento compatibile con Graphviz.
strict digraph G {
69 [ label="1" ];
64 [ label="2" ];
67 [ label="3" ];
66 [ label="4" ];
65 [ label="5" ];
68 [ label="6" ];
69 -> 64 [ label="INPUT REQUEST\npay@PaymentPort\nPaymentRequest" ];
64 -> 67 [ label="OUTPUT REQUEST\ncheck@CreditChecker\nPaymentRequest" ];
67 -> 66 [ label="OUTPUT RESPONSE\ncheck@CreditChecker\nbool" ];
66 -> 65 [ label="OUTPUT ONE-WAY\nalert@AlertService\nstring" ];
66 -> 68 [ label="OUTPUT ONE-WAY\nconfirm@Confirmer\nstring" ];
65 -> 68 [ label="OUTPUT ONE-WAY\nlog@Logger\nstring" ];
68 -> 69 [ label="INPUT RESPONSE\npay@PaymentPort\nbool" ];
}