Questo articolo nasce come evoluzione dell'articolo scritto in precedenza su come creare una piattaforma di Javascript of Anything e che ti consiglio di leggere per comprendere bene il contesto.
In pratica nel precedente articolo mi ero concentrato sul disegno di un'architettura interamente basata su node.js, ora invece andrò a sostituire il broker mqtt (mosca server node.js) con un broker di tipo enterprise come Red Hat Jboss Fuse e più nello specifico la componente Apache ActiveMQ, inclusa come modulo dell'ESB stesso.
Utilizzerò inoltre la componente Apache Camel anch'essa inclusa come modulo dell'ESB Fuse per realizzare un semplice EIP (Enterprise Integration Patterns) dedicato all'integrazione tra le topic mqtt (Apache ActiveMQ) e mongoDB (Persistenza Dati)
Le componenti client le ho realizzate in node.js per simulare due generici device ed in HTML5 per simulare due generici browser client anch'essi connessi alla catena delle topic mqtt, attraverso le websocket.
Al termine dell'articolo trovi un video esplicativo su come far funzionare al meglio la demo, ti consiglio di vedere anche il video perché ti farò vedere anche alcuni accorgimenti (trucchetti) legati alla sicurezza dell'architettura che nel tutorial non ho descritto.
I contenuti dell'articolo
1. Componenti Architetturali sistema IoT
Il disegno architetturale completo è quello illustrato in figura
L'architettura prevede Red Hat Jboss Fuse come broker centrale e l'utilizzo delle componenti in esso integrate Apache Active MQ ed Apache Camel.
MongoDB come data base noSql per la persistenza dei dati.
Due client sviluppati in node.js per la pubblicazione (e ricezione) di dati tramite topic mqtt
Due webapp sviluppate in HTML5 che sfruttano le websocket per la pubblicazione (e ricezione) di dati tramite topic mqtt
Un client di integrazione (EIP) sviluppato con Spring DSL (Apache Camel) che riceve dati dalle topic e li rende persistenti sia su file che su mongoDB.
Le topic mqtt create per la demo sono quattro:
Topic MQTT
- iot.client1.messages
- iot.client2.messages
- iot.web1.messages
- iot.web2.data
Ogni client, incluso il client di integrazione, pubblica e sottoscrive le topic secondo le seguenti regole:
client 1
- pub: iot.client1.messages
- sub: iot.client2.messages
client 2
- pub: iot.client2.messages
- sub: iot.client1.messages
webapp 1
- pub: iot.web1.messages
- sub: iot.+.messages (ovvero riceve dati da tutte le topic che iniziano con “iot” e terminano con “messages”)
webapp 2
- pub: iot.web2.data
- sub: iot.# (ovvero riceve dati da tutte le topic)
eip 1
- sub: iot.# (sottoscrive tutte le topic e rende persistente su mongoDB il dato)
- sub: iot.+.messages (sottoscrive solo dati da topic che iniziano con “iot”, terminano con “messages” e persiste su file)
2. Prerequisiti funzionamento demo
Per il corretto funzionamento della demo è necessario aver installato, sulla propria macchina, le seguenti componenti
Sistema Operativo
Linux è fortemente consigliato anche se non necessario (io utilizzo Fedora 26). La demo può girare anche su macchine Windows o MAC OS.
JDK (necessario)
Sulla macchina deve essere installata la java virtual machine, consiglio di installare la JDK 1.8.
A questo link maggiori informazioni su come installare la JDK per Fedora.
Il comando per verificare l'installazione è il seguente: java -version
maven
Consiglio anche di installare maven, per fare la build della componente di integrazione (EIP) con il comando mvn clean install
A questo link maggiori informazioni su maven.
Il comando per verificare l'installazione è il seguente: mvn -version
Red Hat Jboss fuse
Ovviamente deve essere installato Red Hat Jboss Fuse, a questo link trovi tutte le informazioni su come installarlo sulla tua macchina.
Considera che fuse, sul portale Red Hat, viene fornito come pacchetto .zip
L'installazione è molto semplice, basta scompattarlo in una directory (consiglio di installarlo sotto /opt/jboss-fuse-6.3)
Per la demo utilizzerò fuse in modalità “standalone“, in un ambiente di produzione è fortemente consigliato l'utilizzo di fuse in modalità “fabric” (più info a questo link) e soprattutto è necessaria una sottoscrizione del prodotto.
node.js
Due dei cinque client di test sono stati realizzati in node.js, pertanto è necessario aver installato sulla propria macchina anche node.
Il comando per verificare l'installazione è il seguente: node -v
mongodb
La persistenza è stata implementata con mongoDB, pertanto è necessario installare anche questo dbms noSql sulla macchina target.
A questo link più informazioni su come installare mongoDB su Linux Fedora.
Il comando per verificare l'installazione è il seguente: mongo -version
Una volta terminata l'installazione di tutte le componenti necessarie, puoi iniziare a configurare l'ambiente e lanciare la demo.
3. Configurazione componenti sistema IoT
Red Hat Jboss Fuse
Una volta scompattato il prodotto e copiato sotto la directory “/opt/” è necessario abilitare l'utente amministrativo per l'accesso alla console di gestione.
Per abilitare l'utente basta modificare il file:
[InstallDir]/etc/users.properties
cercare la linea
#admin=admin,admin,manager,viewer,Operator, Maintainer, Deployer, Auditor, Administrator, SuperUser
e togliere il commento (#)
Oltre all'abilitazione dell'utente admin è necessario abilitare anche il protocollo mqtt ed il protocollo web socket per Apache Active MQ
Le Web Socket devono essere abilitate perchè l'mqtt utilizzato via browser dal client web (mqtt.js) necessita, per il corretto funzionamento, di questo protocollo attivo sul broker (mqtt over web socket).
Per abilitare i protocolli basta modificare il file:
[InstallDir]/etc/activemq.xml
cercare la linea
<transportConnector name="openwire" uri="tcp://${bindAddress}:${bindPort}"/>
ed aggiungere anche i connettori per l'mqtt (1883) e per le web socket (61614)
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883"/> <transportConnector name="websocket" uri="ws://0.0.0.0:61614"/>
Inoltre aggiungere subito dopo il tag
</transportConnectors>
Il seguente codice xml, per l'abilitazione di un utente generico all'accesso delle topic
<plugins> <simpleAuthenticationPlugin> <users> <authenticationUser username="system" password="manager" groups="users,admins"/> </users> </simpleAuthenticationPlugin> </plugins>
Dopo aver abilitato i protocolli mqtt e ws devi lanciare red hat jboss fuse da riga di comando.
Accedi alla directory [InstallDir]/bin/
e lancia il comando
./fuse
Attendi la corretta esecuzione del programma
al termine avrai la console Karaf di fuse attiva.
Ora devi abilitare le features che verranno utilizzate dal client EIP (Apache Camel) per la persistenza del dato su mongoDB e su file da topic mqtt.
Dalla console Karaf lancia i seguenti comandi
features:install camel-mongodb
features:install camel-mqtt
La configurazione di fuse è terminata, puoi chiudere tutto con il comando
exit
da console karaf.
mongoDB
In relazione a mongoDB, per il corretto funzionamento della demo, è necessario procedere con la creazione di un utente di test, lo stesso utente che poi verrà utilizzato dalla componente client EIP che si occupa della persistenza dei dati.
Lanciamo quindi la shell mongo da riga di comando:
mongo
Creiamo il nuovo database test con il comando:
use test
Ed inseriamo il nuovo utente con il comando:
db.createUser({user: "test",pwd: "test",roles: [ "readWrite", "dbAdmin" ]})
In questo mondo l'EIP potrà accedere al data base test dell'istanza mongo localhost usando utenza e password: test/test
L'EIP renderà persistenti le informazioni nella collection iot.
NB: Con mongoDB non è necessario creare le collection (equivalente delle tabelle nei db relazioni) in quanto la collection viene creata a runtime nel momento in cui viene fatta la prima insert.
4. Download e Configurazione software
Scarica il software da gitHub
Il software per eseguire la demo lo trovi sul mio account gitHub al seguente link:
https://github.com/etrusco74/iot
Non devi far altro creare una directory sul tuo pc
mkdir iot-demo
accedere alla directory
cd iot-demo
e scaricare il codice con i comandi:
git init
git clone https://github.com/etrusco74/iot.git
Al termine del download troverai la seguente struttura di directory
- camel-iot-mongo -> componente di integrazione (EIP) per fuse (Apache Camel)
- iot-client -> primo client node.js
- iot-client-2 -> secondo client node.js
- iot-server -> componente server mosca (node.js) non oggetto della seguente demo
- iot-web -> componenti client web
prima di avviare la demo dovrai fare le seguenti operazioni:
Esegui la build dell'eip con maven
accedi alla directory “camel-iot-mongo” e lancia la build maven con il comando
mvn clean install
Se tutto andrà per il verso giusto nella directory target troverai il seguenti jar
camel-iot-mongo-1.0.0-SNAPSHOT.jar
Copia il componente web sotto Apache
A questo punto devi solo copiare la componente HTML (iot-web) nella web root di Apache, con il comando:
sudo cp -r iot-web /var/www/html/
E' importante che Apache sia installato ed avviato, se non sai come fare segui questo link.
5. Esecuzione della demo
Se arrivato a questo punto? Hai fatto tutto che ti ho elencato?
Allora sei pronto per lanciare la demo, prima però che ne dici di lasciarmi un like?
Perfetto, andiamo avanti.
Come prima cosa accedi alla directory di installazione di Red Hat Jboss fuse [InstallDir]/bin/
e lancia il comando
./fuse
Attendi la corretta esecuzione del programma, poi lancia la console web amministrativa (hawtio) di fuse al link:
http://localhost:8181
Inserisci utenza e password ed accedi
Verifica che sia attivo il tab “ActiveMQ”
A questo punto inizia a lanciare i vari client, sia node.js che web, con i seguenti comandi:
cd iot-demo/iot/iot-client
node server.js
Apri un nuovo tab ed esegui i seguenti comandi:
cd iot-demo/iot/iot-client-2
node server.js
I due client inizieranno a scambiarsi informazioni.
A questo punto apri due nuovi tab del sul browser e lancia le seguenti pagine:
http://localhost/iot-web/index1.html
http://localhost/iot-web/index2.html
Tutti e quattro i client inizieranno a scambiarsi informazioni secondo le regole di sottoscrizione e pubblicazione descritte sopra.
Ora accedi alla console di fuse e verifica che effettivamente il broker stia funzionando, dal tab ActiveMQ:
A questo punto manca solo di deployare l'EIP per attivare la persistenza su mongoDB.
Accedi alla folder
cd iot-demo/iot//camel-iot-mongo/target
e copia il file camel-iot-mongo-1.0.0-SNAPSHOT.jar nella directory dei deploy di fuse:
cp camel-iot-mongo-1.0.0-SNAPSHOT.jar /opt/jboss-fuse-6.3.0/deploy/
Mi raccomando, verifica che mongoDB sia attivo prima di fare il deploy.
A questo punto accedi nuovamente alla console web di fuse, troverai un nuovo tab “Camel“, cliccaci e verifica che la rotta sia attiva e funzionante:
Fai un'ultima verifica direttamente per verificare che effettivamente l'EIP stia scrivendo su mongoDB.
Da terminale lancia i seguenti comandi:
mongo
use test
show collections
Dovresti vedere anche la nuova collection iot
verifica che il count incrementi con il comando
db.iot.count()
se lanciando il comando più volte il contatore si incrementa allora la demo sta funzionando correttamente.
Fai un'ultima verifica per vedere che anche la rotta di scrittura file nella directory stia funzionando correttamente.
Da riga di comando accedi alla folder di scrittura dei file:
cd /opt/jboss-fuse-6.3.0/work/out/iot/
digita il comando di listing
ls -la
verifica che ci siano dei file, il contenuto sarà proprio l'informazione inviata da uno dei quattro client periferici.
Complimenti, hai fatto tutto bene!
6. Videotutorial del sistema IoT
Se invece preferisci un video che ti faccia vedere passo passo come eseguire la demo del sistema IoT, allora mettiti comodo e premi play.
Nel video descrivo i passi:
- 3. Configurazione delle componenti del sistema IoT
- 4. Download e Configurazione del software
- 5. Esecuzione della demo
mentre presumo tu abbia già configurato la macchina con i prerequisiti richiesti al par. “2. Prerequisiti per il funzionamento della demo”
Durante il video ti farò vedere anche alcuni accorgimenti legati alla sicurezza che nel tutorial non ho descritto!
Che te ne pare di questa architettura? Conosci altri modi per implementare un semplice sistema IoT? Raccontami tutto nei commenti!