Introduction à ElasticSearch

ElasticSearch est un moteur de recherche open source développé en java. Il est basé sur la librairie Apache Lucene. Cette dernière étant assez difficile à mettre en oeuvre, ElasticSearch facilite l'utilisation de Lucene en intégrant la librairie dans une application Java modulaire, facilement configurable et capable de fonctionner en cluster.
Il suffit de quelques minutes à peine pour disposer d'un moteur de recherche clusterisé, automatiquement sauvegardé et répliqué, interrogeable via une API REST et proposant toutes les fonctionnalités d'un moteur de recherche dernière génération.

La configuration se fait très simplement, et permet de répartir automatiquement le volume des données indexées et la charge d'utilisation sur l'ensemble des machines appartenant au cluster (ici, un cluster n'est pas un ensemble de serveur, mais un ensemble de nœuds). Pour absorber plus de données ou plus de charge, il suffira d'ajouter de nouvelles machines au cluster.

Les principales fonctionnalités d'ElasticSearch
Nous avons droit à toutes les fonctionnalités d'un moteur de recherche nouvelle génération :
- les recherches par mots clés façon Google
- les recherches par combinaison de critères et de filtres
- le tri et la pagination des résultats
- la gestion des synonymes
- l'extraction de texte à partir de documents binaires (photo, pdf...)
- l'analyse et la navigation par facettes (c'est-à-dire permettre d’effectuer une recherche en fonction de multiples critères)

Système de plugins
ElasticSearch permet aussi d'ajouter facilement de nouvelles fonctionnalités au moteur de recherche grâce à des plugins.
On peut ajouter par exemple:
- des analyseurs syntaxiques
- des interfaces d'administrations
- des plugins qui permettent d'indexer différentes sources de données (bases de données relationnelles, NoSQL, annuaire LDAP, système de fichiers, flux RSS etc).

API REST
ElasticSearch dispose d'une API REST très complète permettant d'utiliser le moteur de recherche avec de simples requêtes HTTP/JSON. REST qui fournit une interface à toutes les manipulations que l’on peut faire sur Elasticsearch.

Cluster et node
Un node est une instance d'un serveur ElasticSearch. Lorsqu'on a un gros volume de données à gérer, ou penser à la tolérance de pannes, on utilise une configuration multi-nodes.
Un cluster est un ensemble de plusieurs nodes qui travaillent ensemble. Cette solution permet de gérer des grosse charges, d'avoir un travail ininterrompu dans le cas où un noeud devient inaccessible.




Equals et Hashcode : Pourquoi et comment les redéfinir

Lorsque l'on veut utiliser des objets, plus précisément des bean entités, dans des collections, il faut redéfinir les méthodes equals() et hashcode(). Il est judicieux de réfléchir à la meilleure façon de les implémenter.

find(), get(), et load()

get(), load() vs find()
- get() et load() retournent un objet.
- find() retourne un liste.

load() vs get()
-l'objet n'existe ni en base ni dans le cache:
   - load() ne retourne jamais null. Il retourne une exception.
   - get() retourne null.
-l'objet existe en base ou dans le cache:
   - load() retourne un proxy des objets dépendants (initialisation paresseuse ou lazy loading).
   - get() retourne retourne toute la grappe de l'objet (i.e. avec les objets dépendants) initialisée. Ce qui entraîne de multiple requêtes (problème du N+1 requêtes).


Hibernate : Avantages / Inconvenients

Avantages
- Génère le code SQL --> L'application est plus portable. On peut changer de base de données sans difficulté.
- Persistance transparente. On peut faire de nos classes métiers des classes persistantes sans ajout de code.
- La récupération des données est optimisé grâce à un système de caches.

Inconvénient 
- Dure de faire des requêtes complexe.

Pourquoi choisir spring ?

Le framework Spring est une boite à outils très riche permettant de structurer, d'améliorer et de simplifier l'écriture d'application JavaEE. Spring est organisé en module.
C’est d’abord un conteneur léger implémentant le design pattern IoC. Il permet de gérer plus facilement les objets et leurs dépendances.  Cela assure une plus grande flexibilité, qui comme le veux le modèle d’architecture à n-couches, rend les composants facilement interchangeable.

Spring favorise aussi l'intégration avec de nombreux autres frameworks, notamment d
ans notre cas avec Hibernate.

Pour une application structurée en trois couches, Spring trouve naturellement sont utilité :
  • la couche présentation : Spring MVC
  • la couche service : Module de Transactions et de sécurité
  • la couche accès aux données : Intégration d’Hibernate



Spring est une solution mature et complète pour couvrir toute la pile applicative du front à la persistance en passant par la couche métier.



Une bonne chose : les annotations

L'absence d'annotation rend les gros projets Spring assez compliqués à appréhender par des nouveaux venus. Le fait d'avoir la configuration séparée du code c'est un peu comme monter un meuble en ayant scotché le plan de montage sur le plafond de la pièce voisine : pas très pratique.


Bonnes pratiques de développement


Pourquoi la méthode en "V", ou de type "waterfall", en cascade, est has-been ? Les fameuses étapes spécification / conception / réalisation / validation, souffrent de problèmes chroniques :
  • Les spécifications sont définies au début du projet, alors que c'est là qu'on est sait le moins.
  • Les spécifications font rarement la différence entre ce qui est important de ce qui ne l'est pas.
  • Les activités sont compartimentées en fonction des spécialités des développeurs, ce qui pose des problèmes de répartition des tâches et limite la circulation des connaissances dans l'équipe.
Les méthodes de l'Extrem Programing ou de l'Agile, apportent un peu de bon sens à tout ça. Voici une compilation des choses à faire ou ne pas faire.

La communication
  • Le client est au centre du projet, de l'équipe). C'est le mieux placer pour définir au mieux ses besoins. Il arbitre les priorités (le product owner les défini et les planifie). Il apporte surtout ses connaissances métier à l'équipe.
  • Faire travailler tous les développeurs ensemble. Que chacun sache ce que font les autres. Faire circuler l'information. Instaurer le pair programing. S'entre-aider. Faire des revues de codes par roulement. Sans oublier les réunions quotidiennes (stand-up meeting) pour que chacun connaisse l'état du projet.
Feedback
  • Mettre en place un système d'intégration continue, style Jenkins, par jouer automatiquement une batteries de tests (unitaires et de régression), d'analyser le code, de connaitre l'état global de l'application.
  • Fournir régulièrement des livrables. Il faut pouvoir montrer au client quelque chose de fonctionnel (même partiellement, mais en état de marche), pour qu'il puisse se rendre compte de l'avancement de l'application, et préciser ou corriger ses besoins.
Simplicité
  • Il ne faut pas une spécification complète et détaillée du futur système
  • Avoir une architecture et un code ouvert à tout changement et évolution, et facilement maintenable.
Tests Unitaires
  • Aide à la conception détaillé
  • Les écrire avant le code
  • Ne doit pas passer au début 
  • Doivent passer sans erreur avant d’intégrer le code
  • Aide à la non régression, au changement de conception et au remaniement

Initialisation de classe et d'instance

Initialisation de classe

Java permet d'écrire du code d'initialisation de classe qui sera exécuté lors du chargement de la classe (en même temps que l'initialisation des champs statiques).

Ce bloc sert justement à initialiser les variables static. Il est appelé initialiseur statique.

Il est constitué d'un bloc d'instructions (entre accolades) précédé du mot-clé static.