Ma configuration SBT

SBT est l’outil standard de build de l’écosystème scala ( et pas que… ).1158012

Afin de « l’acclimater » à la vie en entreprise, j’ai du faire quelques modifications. Elles sont adaptées pour les configurations des développeurs utilisant:

  • maven
  • un référentiel partagé (nexus, artifactory)

Pour info, j’ai souhaité déplacer le cache ivy dans un autre répertoire. Par défaut, c’est dans le répertoire $HOME/.ivy.

Créer le fichier sbt.boot.properties dans le répertoire $SBT_HOME/bin

Dans le fichier sbt.bat j’ai ajouté au début le fichier suivant :

 

Elasticsearch avec Docker

Comme évoqué dans un précédent article, j’ai décidé de me mettre (modestement) à Docker. Comme je devais utiliser elasticsearch pour un projet, j’ai dit pourquoi pas utiliser l’image docker. Voici les actions que j’ai réalisé et le (petit) problème vite résolu.

 

elasticdocker

Installation

Que du simple et du basique. elastic.co fournit une image officielle.

Problème de binding réseau

Si je démarre l’instance de manière classique, j’ai un petit soucis de binding réseau. En effet, l’instance Docker positionne le hostname à 172.17.0.1 et … ça occasionne quelques soucis lors de l’appel à mon cluster (ex.: timeout, impossibilité de joindre le cluster, catastrophe nucléaire,…).

Si on exécute la requête suivante : http://localhost:9200/_nodes/process?pretty on obtient :

Bref, ça ne le fait pas. Pour pouvoir utiliser cette image sans avoir à créer ma propre image, j’ai donc positionné les variables HOSTNAME, es.network.bind_host et es.network.host au démarrage de la machine.

Maintenant j’ai la configuration suivante :

Extraire les données d’une base de données relationnelle avec Spark

Me voila en train de tester Apache Spark.AAEAAQAAAAAAAAImAAAAJDcyMTQ0N2JkLWRjYzMtNDZjMy05OWQ4LTljNzFiM2M0NTg0Mw

Pour info, Spark est un projet libre du consortium Apache qui a le vent en poupe depuis quelques temps. Il permet entre autres de réaliser des opérations de type Map Reduce en mémoire

Je souhaite automatiser le chargement de données dans ELASTIC SEARCH et faire au passage un petit map reduce sur les données en entrée.

Voici ce que j’ai fait pour extraire les données d’une base relationnelle ORACLE via JDBC. Bien évidemment, ça fonctionne avec toutes les autres SGBDR accessibles via JDBC.

Configuration de Spark

J’utilise le mode « autonome » de spark, c.-à.d sans cluster hadoop.

Pour l’instant, je n’utilise que les modules streaming et sql.

Au préalable , il faut configurer la variable d’environnement SPARK_CLASSPATH et ajouter le chemin vers le driver JDBC

Je n’ai pas téléchargé la distribution car j’utilise spark au travers des librairies utilisées dans mon programme.

Développement

J’ai décidé d’utiliser le langage SCALA pour développer mon module. Pourquoi SCALA me direz vous ? Parce que ça fait quelques années que je me dis que je dois m’y mettre ( peut être est-ce trop tard ….) et que selon plusieurs commentaires que j’ai pu avoir au DEVOXX, SCALA est clairement plus adapté aux traitements réalisés par SPARK

Dépendances

Voici la configuration de mon pom.xml build.sbt :

Pour l’exemple, voici une classe « fourre tout » qui montre le chargement de Spark ainsi que l’extraction des données

Problèmes rencontrés

Gestion des champs numériques

Comme évoqué ci-dessus, j’ai eu un bug sur la gestion des NUMERIC ,

Comme moyen de contournement, j’ai (après quelques recherches sur le net) opté pour surcharger le dialecte JDBC:

et enregistré le dialecte à l’exécution

Présence du binaire winutils.exe sur windows 7 64bits

Si comme moi vous avez le bug référencé sur le JIRA du projet, il suffit de télécharger le binaire winutils.exe, puis de positionner la variable d’environnement au démarrage en mettant le bon chemin ( attention, il faut un sous répertoire « bin’ .

And now, something completely different

Outre les difficultés liées à l’apprentissage simultané de plusieurs technologies, on y arrive. Le projet est bien documenté.

Maintenant, je vais créer plusieurs indicateurs et faire un chargement dans Elasticsearch. Je décrirai ça dans un prochain article

 

 

Comment customiser une image Docker

Je suis actuellement en train de me mettre sur Docker. En résumé (Wikipedia le fait mieux que moi), Docker est une solution libre de virtualisation qui optimise le déploiement des applications en virtualisation un peu tout l’OS, la base de données, le serveur d’application et soyons fous le poste de développeur.

Au Devoxx 2015, c’était le sujet Hype du moment.

J’ai décidé de me lancer sur ce sujet car je suis en train d’expérimenter quelques technos (MQTT entre autres) et les installations m’exaspèrent…

Bon voila mon problème, pour faire un POC, j’ai voulu installer rabbitmq et ajouter quelques configurations supplémentaires

  • Activation du plugin mqtt
  • Activation de la console d’administration
  • Paramétrage d’un utilisateur pouvant accéder à la console

Pré requis

vérifier que docker est bien installé sur votre poste.

Perso, j’utilise pour cela Debian (what else ) 8.0.

Construction de l’image

Dans le fichier Dockerfile

En résumé, j’utilise l’image Docker officielle rabbitmq, j’ajoute deux variables d’environnement spécifiant les utilisateurs et je lance une commande permettant d’activer le support de mqtt

Ensuite, il suffit de construire l’image dans le répertoire crée

Et voilà, il ne reste plus qu’à exécuter un container basé sur cette image

Conclusion

on peut voir que l’ajout de fonctionnalités supplémentaires est assez facile avec docker. L’exemple est volontairement simpliste. Il existe également docker-compose qui permet de faire la même chose ( et + encore) en étant beaucoup plus puissant dans la gestion des dépendances

 

 

Premiers pas avec Cassandra

Lors de la conférence BIG DATA PARIS 2015, j’ai rencontré l’éditeur de la base NoSQL CASSANDRA (DATASTAX). J’ai pu échanger avec eux sur leur solution et les avantages.Cassandra_logo.svg_
Il y a pas mal de choses qui m’ont séduites:

  • Le mode colonne
  • L’interfaçage CQL qui ressemble un peu au SQL
  • L’UPDATE qui gère l’insertion si la ligne n’existe pas
  • La scalabilité linéaire
  • L’interface graphique du OpsCenter
  • Leur documentation que je trouve bien foutue

Après avoir eu les yeux qui ont brillé, le retour à la réalité m’ a permis de voir que pas mal de restrictions existaient:

  • Certaines briques permettant l’intégration ( apache camel, logstash,…) ne permettent pas de se connecter à cassandra. Il faut le faire via leur API
  • Datastax ne fournit pas une solution de reporting intégrée comme mongodb. On peut utiliser JasperReports pour cela.
  • On ne peut pas générer automatiquement une colonne via le mode d’interfaçace CQL. On peut néanmoins contourner le problème via une MAP

Bref, plein de petits détails qui je pense vont à mon avis être oublié dès lors que je maitriserai un peu plus la technologie.

Je ne vais pas mettre d’exemple dans cet article car je n’ai pas encore trop de matière. Je le ferais sans doute dans un prochain article.

Si vous voulez en savoir un peu plus, allez sur leur site, c’est très bien expliqué.

Créer des batchs avec JAVABATCH – JSR352

Je suis actuellement en train de tester la JSR 352 ( ou JAVA BATCH). Cette API est une des nouveautés de la spécification JAVA EE 7.  Elle permet ( entre autres ) de lancer des BATCHS depuis un serveur JEE.

the-evolution-of-java-ee-7_5252edf90af4c_w1500

 

Mais vous allez me dire : il y a SPRING BATCH ! Oui, JAVA BATCH est une standardisation de JAVA BATCH avec l’ intégration du moteur dans un serveur JEE. D’ailleurs, SPRING BATCH est désormais compatible avec cette API.

Ce dernier offre la possibilité de contrôler l’état des jobs à travers l’outil d’administration du serveur via le JOB REPOSITORY.

jsr352-schematic

Pour ceux qui connaissent SPRING BATCH et le monde chatoyant des ETL, le concept de la JSR 352 sera assez simple à appréhender :

Un batch est spécifié avec un job qui a plusieurs steps qui sont découpés en étapes de lecture, de transformation et de chargement (ETL).

Avantages

Les principaux avantages à faire tourner les batchs dans un contexte JEE ( si si il y en a ) sont les suivants :

  • On peut utiliser l’outillage du serveur pour monitorer les jobs
  • On dispose de toute la stack JEE (CDI, JPA, JTA,JAX-RS,…) pour développer des batchs
  • Un batch peut être déclenché de plusieurs manières (script, service REST,…)
  • Par rapport aux solutions ETL du marché, on peut avoir des tests unitaires, de la qualimétrie de code avec SONARQUBE,…

Inconvénients

C’est une V1. Il y a encore des choses à améliorer ( gestion des properties par ex)

Définition d’un job

Le job se définit par un fichier XML

Les références des différents élements font appel aux références des beans CDI développés. Dans mon exemple, je n’ai pas utilisé de processor car je ne devais pas transformer les données. J’ai cependant eu besoin de séparer les différents traitements en les parallélisant dans des partitions. Pour déterminer les données de chaque partition, j’ai utilisé un mapper.

Le reader

On voir dans l’exemple que l’injection se fait par CDI. Il faut spécifier le scope Dependent pour que les beans soient accessibles dans le contexte BATCH.

La récupération des données se fait via la méthode open(). Logiquement , on doit récupérer toutes les données à ce moment. Ca peut être problématique avec des très grosses volumétries . Dans ce cas on pourra privilégier le lazy loading.

La lecture de chaque item (ex. une ligne ) se fait dans la méthode readItem().  L’une des choses que je trouve un peu dommage dans l’API BATCH est le manque de générique. En effet, ça aurait été un peu plus « sympa » d’avoir une classe AstractItemReader<T> qui paramètre la méthode readItem().

Le writer

De la même manière on spécifie le writer

Sur l’utilisation de la méthode writeItems(), j’ai la même remarque que pour la méthode readItem() . Un peu de générique, ça n’aurait pas été du luxe….

Le mapper

La propriété « PROP » définie dans le fichier XML et utilisée dans le reader est définie pour chaque partition. Les différentes partitions sont stockées dans un partitionPlan.

Démarrage du batch

Le batch peut se démarrer  de la manière suivante

Ce code peut être appelé depuis une servlet, un service REST …..

Monitoring

Pour suivre l’exécution du batch on peut utiliser les outils du serveur d’applications. Sous glassfish on peut utiliser la commande asadmin.

On peut également utiliser les beans JMX pour monitorer les jobs.

Conclusion

La stack JSR 352 est assez simple à utiliser. Elle est certes perfectible ( absence de générique, gestion des propriétés assez compliquée de prime abord) mais fait le boulot.

Par rapport aux autres solutions (spring batch) elle permet la supervision des batchs via les outils du serveur d’application et peut facilement s’intégrer dans une application JAVAEE.

Intégrer la base adresse nationale dans Elasticsearch

L’état fourni désormais via sa plateforme OPENDATA son référentiel des adresses du territoire français.

Si vous souhaitez avoir plus d’informations sur la démarche OPENDATA, vous pouvez consulter cette page.

Cette base est issue des données de l’IGN, de la poste, des collectivités territoriales ou encore de la communauté openstreetmap.

Chaque adresse contient le nom normalisé ainsi que les coordonnées .

Voici le descriptif des données.

Les cas d’utilisation de ces données sont nombreux. L’un deux pourrait être de les utiliser dans les recherches d’adresses. Il faudrait charger ses données dans un moteur de recherche (ELASTICSEARCH par ex.)  et de rechercher la présence d’une adresse avec pondération selon plusieurs critères ( avec filtres, recherches complexes ) et d’obtenir l’adresse normalisée et les coordonnées géographiques .

Je vais essayer de décrire les actions que j’ai réalisé pour intégrer ces données.

Architecture mise en œuvre

Présentation1

Les fichiers CSV sont placés dans un répertoire. L’archive téléchargeable contient un fichier CSV par département.

LOGSTASH joue ici pleinement le rôle d’un ETL.

Configuration LOGSTASH

La configuration est assez simple. Il suffit de savoir configurer le plugin CSV de LOGSTASH.

 ELASTICSEARCH

Le mapping généré par LOGSTASH est assez basique mais permet déjà de réaliser pas mal de requêtes. On peut également brancher KIBANA pour analyser plus finement les données.

Voici un exemple de recherche que l’on peut exécuter :

J’essaierai dans un prochain article e brancher kibana sur cet index pour avoir plus de stats.

Avoir un projet à la fois sur GIT et SVN

Je dois avoir un projet à la fois sur GIT et SVN.git_logo

pour faire simple, je dois faire un pull de git , modifier le code et pouvoir faire des commit sur SVN.Voila comment j’ai géré. Ce n’est sûrement pas « l’état de l’art » , mais ça fonctionne.

Checkout du code depuis SVN

Création du référentiel GIT

Ajout du référentiel distant

Commit et push sur les référentiels

On pousse sur le référentiel distant GIT

On fait maintenant un commit sur le référentiel SVN

Et voila, j’ai mon projet branché sur deux systèmes de source. Bien évidemment, tout est fait pour travailler principalement avec GIT. Le commit dans SVN n’est la que pour assurer une compatibilité avec subversion.

Mettre en oeuvre rapidement l’ autocomplétion avec Elasticsearch

Le mécanisme d’auto complétion peut se réaliser assez facilement dans elasticsearch avec les suggestions.

Voici un exemple simple d’auto complétion

Prérequis

Voici un schéma de démo que j’ai crée et des exemples

Création de l’index

Configuration de l’autocomplétion

Il faut assigner un champ de type completion dans le mapping

Test

Insertion des données

Exemple de recherche

Requête

Résultat

J’essaierai dans un prochain article d’intégrer une auto complétion plus intelligente , basée sur les phrases notamment.

Insérer des données issues d’un fichier CSV dans ELASTICSEARCH

Un cas que j’ai du implémenter avec le même schéma que précédemment:

workflow

Prendre des fichiers CSV en entrée et les insérer facilement dans ELASTICSEARCH au fil de l’eau.  J’ai donc utilisé LOGSTASH pour réaliser cette manipulation.

Cet outil sert à la base comme agrégateur de logs. Il est désormais un mini ETL .

Configuration de LOGSTASH

Explication
Dans le champ input, je spécifie ou est le fichier, ou est l’indicateur de parcours et ou est-ce que je démarre la lecture du fichier

Dans le champ filter , j’ enlève la ligne d’en-tête, puis dans l’élément csv, je spécifie les colonnes et supprime les champs techniques

Enfin, dans l’élément output, j’indique les coordonnées du serveur elasticsearch

Exécution
Il faut d’abord exécuter elasticsearch. Puis démarrer l’instance logstash comme suit :