• Non ci sono risultati.

Esempio di componente applicativo generico

3. Obiettivi ed analisi dei requisit

5.1 Componenti applicat

5.1.4 Esempio di componente applicativo generico

La figura 16 mostra un esempio di componente: la classe SensorComponent modella un componente applicativo che gestisce un sensore di un dispositivo IoT. Questa classe è annotata @AsSingleton in quanto si vuole che il container ne crei soltanto un’istanza. SensorComponent dichiara un motore tuProlog e lo marca con le annotazioni @PrologManagement e @PrologConfiguration per specificare al container come configurare l’istanza del motore.

In @PrologManagement si specifica che il server JMX di management (paragrafo 6.3.4) è fruibile attraverso richieste HTTP (adaptor) all’indirizzo IP 172.20.10.2 (host) e porta 45001 (port). Il server è attivato alla creazione del motore in quanto l’attributo lazyBoot è impostato a false. Le credenziali degli utenti amministratori del motore e le configurazioni di SSL-TLS per l’utilizzo di HTTPS sono rispettivamente indicate nei file credential.txt e ssl.properties (attributi credentialFile e

SSLconfigFile).

L’annotazione @PrologConfiguration specifica che l’occurs check deve essere disabilitato (directives) e che il file mySensorTheory.pl contiene una o più teorie logiche da caricare nel motore.

46

figura 16 – classe SensorComponent.

Il metodo configureSensor() è marcato con l’annotazione @PostConstructCall: è invocato dal container dopo che il motore Prolog è stato configurato e si occupa di ultimare la configurazione del componente. Nell’esempio si simula la registrazione al gestore di un sensore.

Il metodo lastWishes() è marcato con l’annotazione @PreMigrationSetup: questo metodo è invocato dal container prima della migrazione del motore. Nell’esempio il metodo simula il rilascio delle risorse, ovvero la de-registrazione dal gestore di un sensore.

Il metodo reload() è marcato con l’annotazione @PostMigrationSetup poiché si desidera che il container lo invochi dopo che il motore è stato migrato e prima che il componente torni ad essere operativo. Nell’esempio si simula che il componente riacquisisca le risorse necessarie per l’esecuzione, ovvero la registrazione al gestore di un sensore.

47

Il metodo dispose() è marcato con l’annotazione @OnDispose in quanto si desidera che il container lo invochi subito prima della rimozione del componente dal sistema. Nell’esempio si ipotizza che il metodo compia la de-registrazione dal gestore di un sensore.

Possono essere presenti più metodi con la stessa annotazione: il container li invoca in ordine di definizione. Il container non gestisce la consistenza delle annotazioni: è compito del programmatore annotare in modo corretto i metodi dei componenti.

5.1.5 Componente LPaaS

Un componente LPaaS è un componente applicativo che implementa due interfacce standard di LPaaS: client e configurator.

Per semplificare lo sviluppo di componenti LPaaS si è realizzata la classe astratta

alice.tuprologx.middleware.LPaaS.LPaaSComponent che implementa le interfacce client e configurator presentate nel paragrafo 4.1.1.1. Tutti i metodi delle interfacce

restituiscono una rappresentazione testuale del risultato della computazione. Nell’implementazione fornita si è scelto di utilizzare il formato JSON per la rappresentazione dei risultati[JSON]. Questa scelta semplifica la comunicazione del risultato ad un cliente remoto.

Per realizzare componenti LPaaS custom è necessario estendere la classe

LPaaSComponent e dichiarare opportunamente un motore tuProlog in base al servizio

che si vuole rendere disponibile (un esempio concreto è presentato nel capitolo 7).

5.1.5.1 Note sull’utilizzo

I componenti LPaaS sono pensati per implementare il core di un servizio LPaaS. Si è scelto di affidare al componente soltanto la gestione della lista di goal che possono essere richiesti da un cliente. La comunicazione tra entità remote, la sicurezza ed il meccanismo per l’invocazione dei metodi dei componenti dipendono da come vengono integrati i componenti LPaaS con il software che si occupa della distribuzione. Nella soluzione proposta è l’agente LPaaS (ed il relativo behaviour) ad occuparsi di tutti questi aspetti. Per maggiori dettagli si veda il paragrafo 5.3.2.

48

5.2 Il container

Il container è lo strumento che solleva lo sviluppatore dalla necessità di configurare ed istanziare manualmente i componenti applicativi. Per garantire l’indipendenza da una specifica implementazione, si è definita un’interfaccia standard (tabella 6) che ogni oggetto container deve implementare. È possibile fornire varie implementazioni che ottimizzino fattori diversi, come la gestione delle istanze dei componenti e/o le strategie di serializzazione dei motori inferenziali.

alice.tuprologx.middleware.interfaces.IComponentConfigurator

Metodo Descrizione

void setConfigFileLocation(String fileName) Imposta il path del file di configurazione del container.

String getConfigFileLocation() Restituisce il path del file di configurazione del container.

void configure() throws

ComponentConfiguratorException

Effettua il bootstrap del container configurando i componenti.

boolean isConfigured() Restituisce true se il container è stato configurato correttamente, altrimenti false. <T> T getComponent(String id) Restituisce un componente di tipo T a partire

dal suo identificatore. Se il componente richiesto è annotato @AsSingleton, il metodo restituisce l’unica istanza del componente, altrimenti restituisce una nuova istanza del componente occupandosi della

configurazione del motore inferenziale. <T> T getComponentMetaData(String id) Restituisce i metadati del componente

identificato dalla stringa id.

void removeComponent(String id) Rimuove dal container il componente identificato dalla stringa id.

void preMigrationSetup() Effettua le operazioni necessarie per effettuare la migrazione del container e dei suoi componenti.

void postMigrationSetup() throws ComponentConfiguratorException

Riconfigura il container ed i suoi componenti dopo la migrazione.

String toJSON() Ottiene una rappresentazione JSON dello

stato dei motori inferenziali dei componenti presenti nel container.

49

void fromJSON(String jsonString) Ottiene lo stato dei motori inferenziali dei componenti a partire dalla loro

rappresentazione JSON.

void destroy() Elimina tutti i componenti contenuti nel

container.

tabella 6 – interfaccia del Container.

Il container è in grado di gestire sia componenti LPaaS che non, ma si consiglia di non unire diverse tipologie di componenti in quanto tale scelta può complicare la logica applicativa del sistema che si desidera sviluppare.