Maven incrémenter la version en cli
En ce moment je suis sur des problèmatiques de release avec mon projet maven.
Je voudrais que mon job jenkins soit capable de releaser automatiquement une version et mettre à jour les projets qui l’utilise comme dépendance.
Pour cela il y a deux petites commandes cli très utile. Mais d’abord, étudions comment structurer sont pom.xml
1 2 3 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><br /> <modelVersion>4.0.0</modelVersion><br /><br /> <groupId>com.wps.invoicing</groupId><br /> <artifactId>mp-invoicing</artifactId><br /> <version>6.1.1-SNAPSHOT</version><br /> <packaging>jar</packaging><br /><br /> <name>Marketplace Invoicing</name><br /> <url>http://maven.apache.org</url><br /><br /> <properties><br /> <majeur.version>6.1</artemis.version><br /> <patch.version>1</patch.version> </properties> </project> |
Ici, la version majeur est variabilité et ne seras changé que sur les branches de releases. Par contre, la version patch va être incrémenter programmatiquement via le JenkinsFile.
Première commande, mettre le projet en version définitive :
1 |
mvn versions:set -DnewVersion='${majeur.version}.${patch.version}' |
puis commiter les changements
1 |
mvn versions:commit |
Ensuite, il faut deploy la version sur nexus.
Maintenant que notre version N a été publier, il ne reste plus qu’a incrémenter la version patch.
1 2 |
def pom = readMavenPom file: 'pom.xml' def incrementMinor = pom.properties['patch.version'].toInteger() +1 |
Ensuite, il faut updater la propriété (toujours dans le jenkinsFile)
1 2 |
bat "mvn versions:set-property -Dproperty=patch.version -DnewVersion=${incrementMinor}" bat "mvn versions:commit" |
Puis créer la nouvelle version snapshot, commit et deploy pour que tous les nouveaux projet l’ai
1 2 3 |
mvn versions:set -DnewVersion='${majeur.version}.${patch.version}-SNAPSHOT' <br />mvn versions:commit <br />mvn deploy |
Jasper Report – Ajouter une interligne dans un tableau
Le but est de pouvoir ajouter une interligne dans un tableau. Cela peut-ête très utile, par exemple lors d’une facture et que l’on voudrais pouvoir préciser la taxe.

Pour ce faire, il faut faire des groupes dans le tableau. Don un group footer (qu’on va appeler « Group1 » car on a beaucoup d’imagination). A l’intérieur de ce groupe, on va ajouter un texteField (qui s’appel ici compléments).

A ce stade, lorsque vous allez générer le pdf, la ligne sera afficher uniquement tout en bas du tableau, comme un footer.
Et c’est ici que réside l’astuce, il faut définir le group1 comme étant la concaténation de tous les champs de la colonne. Ainsi, chaque nouvelle ligne sera considéré comme un nouveau group et l’interligne sera répété.
En bonus, je vous met la définition du groupe de donnée (subDataSet) .
1 |
<subDataset name="FACTURE_LIGNE_DETAIL" uuid="d6f6b8e3-dd07-442d-a637-1f0536066d26"><br /><parameter name="PIECE" class="com.fdilogbox.artemis.jreport.bean.marketplace.StandardReportParam"/><br /><field name="reference" class="java.lang.String"/><br /><field name="description" class="java.lang.String"/><br /><field name="quantite" class="java.lang.String"/><br /><field name="unitOfMeasure" class="java.lang.String"/><br /><field name="prixUnitaireHT" class="java.lang.String"/><br /><field name="montantTotalHT" class="java.lang.String"/><br /><field name="tauxTaxe" class="java.lang.String"/><br /><field name="complements" class="java.lang.String"/><br /><group name="Group1"><br /><groupExpression><![CDATA[$F{reference}+$F{description}+$F{quantite}+$F{unitOfMeasure}+$F{prixUnitaireHT}+$F{montantTotalHT}+$F{tauxTaxe}+$F{complements}]]></groupExpression><br /></group><br /></subDataset> |
Read More
Mettre à jour tous les dépot git d’un répertoire
Voici une petite astuce qui me permet de mettre à jour tous les dépots git d’un répertoire. Pratique quand on a plein de sous-dépot.
1 2 3 |
# For use in a shell: # Download this file to /usr/local/bin/git-pull-recursive, then chmod 755 it to install git-pull-recursive find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull" \; |
Read More
Quelle base pour stocker 100 million de ligne ? – part 2 : Mysql vs PostgreSql
Étude technique
Comment choisir la base de donnée
Dans notre besoin, une base de donnée clés / valeur correspondrait à notre attente car nous aurions besoin d’une clé (id de la base alfresco) et d’une valeur (les métas du document).
En soi, une base de donnée relationnelle peut tout à fait faire le job : une colonne ‘alfrescoID’ indexée et une colonne ‘metadata’. Les dernières versions de bases relationnelles permettent d’avoir des colonnes de type json et donc introduisent le paradigme ‘document storage’ puisqu’il devient possible de requêter du json.
Avant de choisir le paradigme de la base de données dont nous avons besoin (relationnelle / clés/valeur / document / graph), il est important de savoir ou l’on doit se situer sur le théorème de CAP. Si nous n’avons pas besoin de partitionnement, une base relationnelle suffirait.
Comment savoir si une base relationnelle a besoin de partitionnement ? La réponse est simple : Si les indexes ne tiennent pas en RAM, les performances sont dégradés et on a besoin de les partitionner. A partir du moment où il y a besoin de partitionnement, il vaut mieux quitter les bases SQL conventionnelles pour aller vers les bases NOSQL.
Condition du benchmark
Pour le benchmark, nous allons comparer 2 bases relationnelles : mysql 5.8 (dernière version) et postgre 10.3 (dernière version).
Je vais générer 100 000 lignes, avec une colonne ‘dbid’ qui correspond a l’id dans la base alfresco et une colonne ‘data’ qui contiendra un json ~2MO.
L’idée est de vérifier l’empreinte mémoire utilisée par la base pour stocker les dbid/métadonnée d’un document.
Si l’empreinte mémoire est trop grande, il faudra songer à utiliser des bases NoSQL.
Les tests seront effectués sur un serveur avec les caractéristiques suivantes :
- OS : windows server 2012 à jour
- RAM : 64Go
- Proc : 4 proc a 2.39GhZ
- SSD 1To
C’est parti !
Étape 1 : installation
Installer un serveur postgresql 10 à été très facile, double clique sur l’exe, suivant -> suivant et tout fonctionne très bien.
Pour installer le serveur MySql c’est beaucoup plus laborieux, il faut installer toutes les dépendances .net
Étape 2 : Mesure de l’empreinte mémoire à vide
Je profite de ce chapitre pour dire qu’il est très difficile de mesurer l’empreinte mémoire utilisée par un service sous Windows.
Je m’y suis pris de trois manières différentes, mais aucune ne retourne le même résultat. Nous allons en étudier 2 des trois afin de ne pas noyer la lecture d’informations.
Méthode 1 : taskmanager
Ici on peut remarquer 2 choses :
1) A vide mysql consomme 340Mo , c’est probablement du au fait qu’il utilise .NET
2) postgresql utilise 8Mo et crée 2 processus par CPU, il est multi-threadé .
Methode 2 : moniteur de ressources
Ce que je ne comprends pas, c’est que les données (plage de travail) ne correspondent pas avec ce qui est affiché dans le taskmanager. enfin, passons !
L’avantage du moniteur, c’est qu’il te donne la ram allouable au processus (validation) et la mémoire réellement utilisée (plage de travail).
Pour mysql on voit que le processus a 498Mo de ram réservé pour lui et qu’il en utilise 368Mo.
Pour postgresql, si on additionne tout on est à 11.2 Mo de ram réservé et qu’il en consomme 246 Mo
Conclusion
Il semblerait que la méthode avec le moniteur de ressource soit plus fiable.
Étape 3 : Import des données (100 000 lignes)
Alors là, première surprise, avec un fichier JSON qui représente les méta-données d’un document, valide à la norme RFC, je peux l’importer dans une colonne JSON de postgresql mais impossible de l’importer dans une colonne json mysql, il lui trouve une erreur de syntaxe…
J’utiliserai donc un champ text afin de stocker le json pour mysql.
/!\ Les temps d’import sont ralentis par rapport a la réalité car le serveur mysql et postgre sont sur le même disque SSD. Donc ils sont potentiellement à multiplier par 2
L’import ayant commencé vers 15h13 et fini a 15h18 pour postgresql et 15h19 pour mysql.
-> mysql prend ~20/30% (a la louche) de temps en plus que postgresql sur l’insertion massive.
Wait … 1 minute de plus pour mysql et 30% de perf en moins ? Il y a pas quelque chose qui cloche ?
Si, postgresql a fini d’écrire sur le disque, donc la minute de plus qu’a pris Mysql, elle est a multiplier par 2.
Je dis 30% car j’ai vu la bar de progression qui était à 70% quand postgresql a terminé.
Étape 4 : Mesure de la mémoire après import de 100 000 lignes
Méthode 1 : taskmanager
Mysql : 469Mo
Postgresql : 8.3Mo (aucun changement)
Méthode 2 : moniteur de ressources
Mysql : 480Mo réellement utilisé
Postgre : 257 Mo réellement utilisé
Étape 5 : Import des données (1 000 000 lignes)
Import a débuté à 15:21.
Je suis allé au toilette et je suis revenu a 16h05,
l’import postgresql était terminé, pas celui de mysql …
16h17 : mysql vient de terminer l’import, encore une fois, il faut penser à multiplier le delta par 2 car il était tout seul à écrire.
Étape 6 : Mesure de la mémoire après import de 1 000 000 lignes
Mysql : 520Mo réellement utilisé
Postgre : 302 Mo réellement utilisé
Étape 7 : Vitesse de lecture
Faisons un « select count(*) from meta.metadata; »
mysql : 234 ms
postgre : 187ms
Postgresql est plus performant de 21% par rapport a mysql pour faire un count(*)
Étape 8 : Analyse des chiffres
100 000 lignes
Les chiffres bruts (du moniteur de ressource, que je juge plus fiable), PostgreSQL consomme 2 fois moins de ram que Mysql.
Si on s’intéresse aux delta des chiffres :
- mysql prend 140 Mo pour indexer 100 000 lignes
- postgresql prend 11 Mo pour indexer 100 000 lignes.
Ici c’est encore pire, mysql consomme 10 fois plus de ram que postgre pour les indexes.
1 000 000 lignes
Pour les chiffres brut, postgresql prend a peu près 2 fois moins de ram que mysql.
Quand on regarde le delta :
mysql prend 180Mo RAM pour stocker 1M lignes
postgre prend 56Mo RAM pour stocker 1M lignes
Postgresql consomme 3.2 fois moins de ram que Mysql.
Étape 9 : Conclusion
On se rend compte que la taille des indexes n’est pas linéaire. On voit que passé un certain cap il doit se passer de la compression en ram. A priori une base relationnelle simple, comme mysql suffirait pour stocker les métas des documents de 100 000 000 documents.
En revanche, l’étude met en exergue la supériorité de postgresql sur mysql en terme de performances
- vitesse d’écriture : +30%
- vitesse de lecture : +20 %
- Consommation RAM : 2 fois moins d’espace total
- les indexes consomment 3 fois moins de ram
- multithreadé bien géré.
Quelle base pour stocker 100 million de ligne ? – part 1 : théorie
Expression du besoin fonctionnel
L’objectif est d’être capable de stocker 100 000 000 documents avec alfresco. On sait déjà que la base de donnée alfresco ne tiendra jamais la charge. Le but est donc de déléguer le stockage des méta-données à une base externe (laquelle ?) afin de décharger la base alfresco.
Il y a aussi un moteur d’indexation (solr) qui indexe tous les documents et qui effectue la recherche sur les méta-données. Ainsi le rôle de la base de donnée est de stoker la donnée et pas d’effectuer des recherches.
Une requête Solr renverra des ID de base de donnée mysql correspondant à cette recherche.
Pour soulager la base alfresco, il faudrait une seconde base de donnée qui fasse le mapping entre l’id de la base alfresco et les méta-donnée du document.
Théorie sur les bases de données
Théorème de CAP
Dans ce chapitre, nous allons faire un peu de théorie et étudier le théorème de CAP.
Consistency
C = Consistence = La donnée est fiable. Après un insert ou un update, quand on fait un read, on est certain que la donnée soit à jour.
Availability
A = Availability = Le fait que la base de donnée soit rapide à répondre (haute vitesse d’accès à la donnée).
Partitioning
P = Partitioning = Quand on a des grosses base de données, un seul serveur ne suffit plus pour tout stocker, il faut partitionner la donnée sur plusieurs serveurs.
Le théorème de CAP dit qu’il est possible d’avoir seulement 2 de ses trois choses.
Les bases de données relationnelles (postgresql, mysql) sont des bases de données CA (la donnée est rapide d’accès et toujours fiable) mais se scale très mal. Le partitioning n’est pas impossible, mais l’overhead de partitioning coute très cher.
A partir du moment il faut commencer à avoir un cluster, il faut songer à des bases de données AP ou CP.
Par exemple, mongoDB est une base de donnée CP : Elle est capable d’être clusterisée sans payer de gros overhead, et la donnée est toujours consistante. Après un update, la donnée est tout de suite mise à jour sur tous les clusters. Le coût a payer pour cela est une vitesse de lecture diminuée (availability).
D’un autre côté, il y a Cassandra : une basse de donnée AP. C’est à dire que Cassandra se clusterise très bien tout en gardant des vitesses d’accès comparables à des bases de données relationnelles. Le contre-coup à cela, c’est qu’un update peut mettre du temps à se propager aux clusters. Un appel read, juste après un update, peut ne pas renvoyer la donnée updatée mais l’ancienne valeur. L’ajout / modification / suppression de donnée devient asynchrone.
Pour les bases de données AP et CP, le fait d’être transactionnelle coute plus cher aussi. Garantir une transaction à travers tous les clusters est plus difficile que sur une seule machine.
Les différents modèles de base de données
Différents modèles de bases de données vont être étudier dans ce chapitre, pas seulement les bases SQL conventionnelles, mais aussi les bases noSql (not only sql)
Relationnel
Ce sont les plus connues, elles ont été évoquées plus haut. Les bases de données relationnelles fonctionnent avec des jointures. Le principe est d’éviter à tout prix de dupliquer la données. Pour cela, on va utiliser des jointures pour lier les données entre elles. On dit que les entités ont des relations entre elles (1 to n, n to 1, n to m, 1 to 1).
L’avantage de ce type de bases de données est que la donnée n’est pas dupliquée, elle prend moins de place sur disque. Le désavantage est que les relations entre les entités sont fortes, c’est pour cela que ce genre de base de données est difficile à scaller.
Clés / valeur
Ce genre de base de données est très adapté pour les technologies de caches. A partir d’une clé, on est capable de récupérer des données.
Le problème de ces bases de données est qu’on ne peut pas faire de requête avec critère de sélection, par exemple : « Donne moi toutes les clés qui contiennent un chat ». Ou alors si c’est possible, cela coute extrêmement cher en performance.
Document
Ce sont ces bases que je préfère. MongoDB est une base de données orientée document.
Avec ces bases de données, il faut penser complètement différemment des bases relationnelles. Par exemple, il ne faut pas avoir peur de dupliquer la donnée, et faire des relations entre les tables coute cher en performance car les notions de lazy loading n’existent pas (encore ?).
Ce type de base est très approprié si le produit n’est pas figé et que le modèle de donnée est amené à souvent évoluer.
L’approche est de faire des POJO en java, et les envoyer a la base de donnée qui les sérializera en json. On pourra faire des requêtes sur des propriétés json, etc …
Graph
Celles-ci, je les connais moins, j’ai un petit peu joué avec neo4J mais j’ai très vite été déçu du produit (par exemple il est difficile de stocker des HashMap). Il existe des domaines (notamment en statistique) où se représenter la donnée sous forme de graph permet une plus grande exploitation de la donnée, notamment en cherchant des voisins pas trop éloignés d’un nœud. C’est très utilisé pour les algorithmes de recommandation.
vt#3
Pour ce troisième lot d’articles à lire, les sujets seront un peut plus varié que la simple programmation.
Qu’est-ce que l’observabilité d’un programme ?
Towards Secure System Graphics: Arcan and OpenBSD
Comment faire une grosse application en javascript
Read Morevt#2
Voici un lot de 3 articles intéressants que j’ai lu cette semaine. On peut voir que je me suis intéressé au websocket :
BEM (CSS) : https://blog.eleven-labs.com/fr/retour-d-experience-sur-bem/
Server Side Event ou Websocket ? https://www.smashingmagazine.com/2018/02/sse-websockets-data-flow-http2/
RabbitMq chat post mortem : http://alvaro-videla.com/2011/05/rabbitmq-chat-post-mortem.html
Read More
VT#1
Dans se nouveau concept, je vais regroupé les articles qui m’intéresse et que je m’oblige a lire pour faire ma veille technologique.
Je vous fais ainsi partagé ma veille technologique.
Les résolvers angular : https://blog.nathanaelcherrier.com/2017/11/29/angular-les-resolvers/
Vim n’a pas besoin de multi-curseur : https://medium.com/@schtoeffel/you-don-t-need-more-than-one-cursor-in-vim-2c44117d51db
Les id auto-incrémenté sont une mauvaise idée, il faut plutôt utilisé les UUID : https://www.clever-cloud.com/blog/engineering/2015/05/20/why-auto-increment-is-a-terrible-idea/
Faites attention avec les UUID en tant que clé primaire : https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439
Read More
[PoC] installation de Nagios pour superviser une application HTTP avec docker
Ressources utilisé :
Superviser un hôte Linux via NRPE
https://blog.nicolargo.com/2007/10/surveiller-vos-serveurs-linux-avec-nagios-et-nrpe.html
[Tuto] Nagios: Introduction au fichiers de configurations de Nagios
http://blog.nicolargo.com/wp-content/uploads/2011/03/ebook-nicolargo-nagios-v1.0.pdf
http://djibril.developpez.com/tutoriels/perl/ecrire-facilement-plugin-nagios-perl/
1. Pré-requis
1.1 Script bash qui démare un container nagios superviseur :
1 2 3 4 5 6 7 8 |
#!/bin/bash docker pull jasonrivers/nagios:latest docker run --name nagios4 \ -v /home/morgan/dev/docker/nagios/data/etc/:/opt/nagios/etc/ \ -v /home/morgan/dev/docker/nagios/data/var:/opt/nagios/var/ \ -v /home/morgan/dev/docker/nagios/data/custom-plugins:/opt/Custom-Nagios-Plugins \ -p 80:80 jasonrivers/nagios:latest |
1.2 un autre container qui contiens votre application http
1.3 Commande docker pour connaitre les ip :
docker network inspect bridge | jq
2. Mise en place de l’environnement
2.1 Pour chaque container docker supervisé, il faut installé un serveur NRPE :
apt-get install nagios-nrpe-server
2.1.1 Configurer pour autorisé a se connecter à notre serveur nagios de supervision
nano /etc/nagios/nrpe.cfg
1 |
allowed_hosts=<ip du container nagios> |
2.1.2 Si iptable est installé, autorisé les requete NRPE
iptables -A INPUT -p tcp --dport 5666 -j ACCEPT
2.1.3 Automatisé le démarrage de NRPE :
update-rc.d nagios-nrpe-server defaults
2.1.3 redémaré le service
service nagios-nrpe-server restart
2.1.4 Pour vérifier que cela fonctionne, connecter vous sur le container <nagios>
1 2 |
cd $NAGIOS_HOME ./check_nrpe -H <ip_container a supervisé> |
3. Exécuter une commande de supervision
3.1 sur le container supervisé, créer une nouvelle commande en éditant le fichier nrpe.cfg
vim /etc/nagios/nrpe.cfg
3.2 En dessous des commandes déjà existantes, ajouté :
command[check_home]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /home
Ici, le statue du service que nous allons créer plus tard sera en WARNING (-w), s’il reste moins de 20% (20) d’espace disque disponible et le statue sera CRITICAL (-c) s’il reste moins de 10% (10) d’espace libre.
3.3 Redémarer pour que la nouvelle commande soit prise en compte :
service nagios-nrpe-server restart
3.4 Executer la commande depuis le container nagios
1 2 |
cd $NAGIOS_HOME ./check_nrpe -H <ip_container a supervisé> -c check_home |
4. Superviser plusieurs containers
4.1 Dans le container nagios :
Dans le dossier objects nous allons créer un dossier linux_servers, c’est dans ce dossier que nous allons configurer toutes nos machines linux à superviser.
Puis nous allons éditer le fichier nagios.cfg se trouvant dans $NAGIOS_HOME/etc et nous allons donc rajouter la ligne:
1 2 |
#Dossier serveurs Linux cfg_dir=/opt/nagios/etc/objects/linux_servers |
Commenter la ligne qui surveille le serveur locale :
1 2 |
# Definitions for monitoring the local (Linux) host #cfg_file=/opt/nagios/etc/objects/localhost.cfg |
Maintenant dans le dossier linux_servers, nous allons créer trois fichiers:
linux_hosts.cfg, linux_hostgroups.cfg et linux_services.cfg
linux_hosts.cfg
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#### LINUX HOST DEFINITIONS ###### define host{ use linux-server host_name nagios alias Serveur Nagios address 172.17.0.3 } define host{ use linux-server host_name packkm alias PackKM-5.2 address 172.17.0.2 } |
linux_hostgroups.cfg
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#### LINUX HOSTGROUPS DEFINITIONS #### define hostgroup { hostgroup_name linux_servers alias Serveurs Supervision Linux members nagios } define hostgroup { hostgroup_name linux_clients alias Pack client sous Linux members packkm } |
linux_services.cfg
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#### LINUX SERVICES DEFINITIONS #### define service { use generic-service host_name * service_description ping check_command check_ping!100.0,20%!500.0,60% } define service { hostgroup_name web-internet use generic-service service_description HTTP check_command check_http!-p 8080 } |
Mettre en place un environement de dev pour rust
Installer rust et les outils tiers
curl https://sh.rustup.rs -sSf | sh
installer les sources
rustup component add rust-src
Installer racer pour l’autocompletion
cargo install racer
installer raincorn pour le parsing
cargo install --git https://github.com/RustDT/Rainicorn --tag version_1.x
rustfmt pour le formattage
1 |
[crayon-603c360d0f27a613595604 lang="sh" decode="true" inline="1" ]cargo install rustfmt-nightly |
[/crayon]
Configurer eclipse :
Directory : ~/.cargo
rust src directory : $(rustc --print sysroot)/lib/rustlib/src/rust/src
Racer : ~/.cargo/bin/racer
Read More