Serveless in Java : Apache OpenWhisk

Prosegue il tour delle soluzioni Servless con Apache OpenWhisk

Apache OpenWhisk è una soluzione per realizzare servizi Servless, donata da IBM e Adobe al mondo opensource di Apache. La piattaforma, realizzata principalmente in Scala, permette la definizione di servizi in modalità Serverless, ovvero la creazione e gestione di funzioni utilizzabili per la realizzazione di un sistema che può sfruttare l’invocazione in modalità asincrona con ottime prestazioni. Lo schema architetturale adottato da Apache OpenWhisk è molto simile a quello visto con AWS Lambda e Azure Function, anche se cambia leggermente per quanto riguarda la terminologia

Abbiamo quindi i seguenti concetti

  • Action : sono le funzioni che possono essere definite e richiamate all’interno del sistema
  • Event source : sorgenti generiche di eventi, i quali possono essere iniettati nel sistema
  • Trigger : quando si verifica un determinato evento il trigger associato a quella classe di eventi scatta
  • Rule : la regola permette di associare un trigger ad un action. In questo modo quando scatta il trigger viene richiamata la corrispondente action

Le azioni, che sono quindi il cuore della piattaforma, possono essere realizzate nei seguenti linguaggi

 

Setup ambiente

Per utilizzare OpenWhisk possiamo creare un account gratuito sulla piattaforma IBM BlueMix, con una macchina Vagrant, Docker su Mac o Docker su Ubuntu. La cosa più semplice è quella di utilizzare l’implementazione cloud di IBM, che possiamo utilizzare creando un account gratuito. Per installare la console di IBM Cloud Functions possiamo quindi eseguire i seguenti comandi

Con il primo comando scarichiamo la console di IBM BlueMix (che ovviamente è molto di più rispetto a quello che stiamo vedendo) e la installiamo. Il secondo comando installa il plugin per utilizzare le Cloud Functions e con il terzo andiamo a fare il login sulla piattaforma. L’ultimo comando esegue un primo hello world sulla piattaforma, invocando l’azione di utility /whisk.system/utils/echo.

 

Hello OpenWhisk

Vediamo quindi come realizzare un semplice Hello World in Java su questa piattaforma. Come prima cosa dobbiamo sapere che l’input e l’output che avremo nella nostra funzione sarà sempre un oggetto JSON, che verrà gestito dalla libreria GSON di Google inclusa come dipendenza nel nostro progetto

Passiamo quindi alla classe d’esempio, che deve prevedere un metodo statico main, che come input e output avrà l’oggetto JSON che abbiamo detto.

Il metodo recupera il parametro nome se presente, risponde con un JSON che ha la property risposta. Come visto su AWS Lambda e Azure Function, il progetto deve creare un JAR con tutte le dipendenze, quindi dovremo utilizzare il plugin Maven Shade

quindi per creare il pacchetto JAR, l’action e invocarla possiamo utilizzare i seguenti comandi in sequenza

In questo modo la nostra action è invocabile attraverso la console di BlueMix ma possiamo anche creare un API gateway che richiami questa action. Prima di farlo dobbiamo aggiornare il nostro hello world specificando che deve essere un action di tipo web

e poi creare un API che richiami l’action

L’indirizzo fornito come output potrà quindi essere utilizzato per richiamare la nostra action attraverso una semplice chiamate HTTP

 

Sequenze

Diverse action possono essere collegate in una sequenza più lunga, dove l’output di una diventa l’input di quella successiva. Vediamo quindi un esempio di sequenza dove il primo step recupera un parametro di tipo stringa dalla request ed effettua banalmente l’uppercase

e lo aggiungiamo al nostro sistema

Il secondo step prende una stringa in input e genera un PDF che contiene come testo la stringa. In questo caso il PDF viene restituito sempre dentro all’oggetto JSON di risposta ma utilizzando l’encoding Base64

Per realizzare il PDF è stato utilizzato PDFBox che abbiamo incluso come dipendenza e che quindi sarà presente nel JAR risultante. Creiamo quindi l’action per la generazione del PDF

L’ultimo step prende come parametro d’input un PDF passato come array di byte in Base64, applica un logo in alto a destra alla prima pagina del PDF e lo ritorna in output

Anche in questo caso generiamo l’action relativa

e passiamo alla creazione della sequenza, dove dovremo appunto specificare quali action e in che ordine richiamarle

la sequenza in realtà è un wrapper che agisce come action e chiama le action che contiene. Per invocare la sequenza possiamo quindi richiamarla come una semplice action e passare il parametro iniziale di cui ha bisogno, in questo caso una stringa che sarà presente nel PDF di output

Il risultato, che evito di riportare nell’articolo per ovvi motivi, è in Base64 quindi se lo volete visualizzare dovete effettuare la decodifica.

 

Rules e Trigger

I trigger e le regole di OpenWhisk forniscono alla piattaforma la sua caratteristica event-driven. La creazione di questi elementi possono essere fatte tutte tramite la console quindi non hanno niente di specifico relativo a Java o ad altri linguaggi, però vale comunque la pena capire come definirli per poter poi agganciare delle action. Per creare un trigger che scatta ogni 20 secondi possiamo utilizzare il seguente comando

In questo modo abbiamo associato il trigger ad un feed di eventi che un action di utility che fornisce degli eventi. A questa utility alarm abbiamo detto di scattare ogni 20 secondi e che il trigger potrà partire al massimo 15 volte. Ora definiamo la regola che permette di agganciare questo trigger al nostro hello world

la regola, come già detto, lega un trigger ad una action e quindi dobbiamo riportare queste due informazioni quando la creiamo. Per vedere che il nostro hello world viene richiamato possiamo lanciare il seguente comando

 

Conclusioni

Anche Apache OpenWhisk sembra essere un’ottima soluzione per realizzare dei componenti fruibili in modalità Serverless. Nella sua versione targata IBM, ovvero IBM Cloud Functions, abbiamo un’ambiente simile a quelli visti con AWS e Azure, ma sembra essere molto interessante anche la possibilità di creare una propria versione hosted di Apache OpenWhisk visto che stiamo parlando di una completamente piattaforma opensource

https://github.com/fpaparoni/OpenWhisk