<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Andy Hazoume</title>
 <link href="andyhazou.me/atom.xml" rel="self"/>
 <link href="andyhazou.me/"/>
 <updated>2026-06-05T05:25:22+00:00</updated>
 <id>andyhazou.me</id>
 <author>
   <name>Andy Hazoume</name>
   <email>andy.hazoume@gmail.com</email>
 </author>

 
 <entry>
   <title>Carbone Modifié T3</title>
   <link href="andyhazou.me/2026/06/05/surlignements-t3-carbone-modifie"/>
   <updated>2026-06-05T00:00:00+00:00</updated>
   <id>andyhazou.me/2026/06/05/surlignements-t3-carbone-modifie</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/assets/images/2026-06-05-altered-carbon.jpg&quot; alt=&quot;Altered Carbon.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Troisième et dernier tome de la trilogie de Richard Morgan, « Furies déchaînées » referme le cycle Takeshi Kovacs. Cette fois, Tak rentre chez lui : le Monde de Harlan, sa planète d’origine, là où tout a commencé pour lui.&lt;/p&gt;

&lt;p&gt;Contrairement à mes notes sur les deux premiers tomes, je n’ai pas relevé de citations précises cette fois. Voici plutôt les éléments qui m’ont marqué.&lt;/p&gt;

&lt;h2 id=&quot;retour-sur-le-monde-de-harlan&quot;&gt;Retour sur le Monde de Harlan&lt;/h2&gt;

&lt;p&gt;La boucle se referme : Kovacs revient sur sa planète natale, là où tout a commencé. Le décor n’est plus un terrain d’aventure parmi d’autres, c’est le sien — et ça donne au récit des airs de règlement de comptes.&lt;/p&gt;

&lt;h2 id=&quot;quellcrist-falconer-au-cœur-du-récit&quot;&gt;Quellcrist Falconer, au cœur du récit&lt;/h2&gt;

&lt;p&gt;La figure de la révolution, jusqu’ici citée et mythifiée, prend une place centrale. Elle n’est plus seulement une voix qu’on cite avant l’assaut : elle devient un moteur de l’intrigue.&lt;/p&gt;

&lt;h2 id=&quot;le-passé-de-kovacs-avant-les-diplos&quot;&gt;Le passé de Kovacs, avant les Diplos&lt;/h2&gt;

&lt;p&gt;Morgan creuse enfin l’homme derrière l’enveloppe. On croise des figures de son époque de Diplo, et de bien avant — de quoi comprendre ce qui a fait de lui ce qu’il est.&lt;/p&gt;

&lt;h2 id=&quot;linterface-homme-machine&quot;&gt;L’interface homme-machine&lt;/h2&gt;

&lt;p&gt;La techno qui m’a le plus titillé l’imagination : une interface homme-machine branchée en prise directe sur le cerveau. Un esprit humain connecté aux systèmes au point de brouiller la frontière entre l’opérateur et la machine. Vertigineux.&lt;/p&gt;

&lt;h2 id=&quot;se-battre-contre-soi-même&quot;&gt;Se battre contre soi-même&lt;/h2&gt;

&lt;p&gt;Le concept le plus fort du livre : Kovacs affronte une version de lui-même. Littéralement — une copie plus jeune, d’avant sa carrière de Diplo, lancée à ses trousses. Que reste-t-il de soi quand l’adversaire, c’est exactement ce qu’on était ?&lt;/p&gt;

&lt;h2 id=&quot;le-mystère-de-la-technologie-martienne&quot;&gt;Le mystère de la technologie martienne&lt;/h2&gt;

&lt;p&gt;Le fil rouge que j’ai toujours aimé : les Martiens, race disparue, et ce qu’ils ont laissé derrière eux. Morgan résiste à tout expliquer et préfère entretenir le merveilleux. Une belle manière de refermer la trilogie.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Carbone Modifié T2</title>
   <link href="andyhazou.me/2026/04/05/surlignements-t2-carbone-modifie"/>
   <updated>2026-04-05T00:00:00+00:00</updated>
   <id>andyhazou.me/2026/04/05/surlignements-t2-carbone-modifie</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/assets/images/2026-04-05-altered-carbon.jpg&quot; alt=&quot;Altered Carbon.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Deuxième tome de la trilogie de Richard Morgan, “Anges déchus” nous retrouvons notre Diplo préféré, Takeshi Kovacs, dans une nouvelle enveloppe. Cette fois-ci, il est plongé en pleine guerre sur Sanction IV, une planète colonisée par les humains.&lt;/p&gt;

&lt;p&gt;Au programme : aventure spatiale, guerre, technologies qui titillent l’imagination, sexe, romance, philosophie futuriste, et cette fois-ci les Martiens font leur entrée.&lt;/p&gt;

&lt;p&gt;J’ai parfois été un peu perdu, avec une impression de récit bâclé à certains passages. Certaines descriptions m’ont échappé, difficiles à visualiser. Mais le livre m’a quand même tenu en haleine jusqu’au bout.&lt;/p&gt;

&lt;h2 id=&quot;sur-le-corps-et-la-souffrance&quot;&gt;Sur le corps et la souffrance&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Travailler le corps humain au point de la destruction n’est que l’une des voies vers la supériorité…&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dans un monde où on peut changer d’enveloppe, le rapport au corps devient étrange. La souffrance physique n’est plus une limite absolue.&lt;/p&gt;

&lt;h2 id=&quot;sur-le-pragmatisme&quot;&gt;Sur le pragmatisme&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Se préoccuper du monde suivant, c’est être incapable de faire face à celui-ci de façon efficace.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kovacs reste fidèle à lui-même : ancré dans le présent, méfiant de tout ce qui détourne de l’action immédiate.&lt;/p&gt;

&lt;h2 id=&quot;sur-le-prix-à-payer&quot;&gt;Sur le prix à payer&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Dans n’importe quel projet, politique ou autre, il y a un prix à payer. Demandez toujours quelle forme il prendra, et qui s’en acquittera. Sans cela, les planificateurs du projet sentiront votre silence comme les panthères des marais sentent l’odeur du sang. Et avant de comprendre ce qui vous arrive, la personne chargée de supporter ce coût, ce sera vous. Et vous n’en aurez sans doute pas les moyens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un passage qui résonne bien au-delà de la fiction.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;La paix n’est jamais gratuite. On la paie forcément, à un moment ou à un autre. Par son opposé.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;sur-la-guerre-et-la-politique&quot;&gt;Sur la guerre et la politique&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;La guerre a un effet apaisant et simplificateur sur la politique, qui doit faire aux politiciens l’effet d’un rush de bétathanatine. On n’a plus à faire la part des choses, et on peut justifier n’importe quoi. Combattre et gagner, remporter la victoire. Tout le reste s’efface dans un grand flou blanc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Morgan reste cynique sur la nature du pouvoir. La guerre comme drogue du politicien, où tout devient binaire et justifiable.&lt;/p&gt;

&lt;h2 id=&quot;sur-la-religion&quot;&gt;Sur la religion&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Je croyais que c’était le principe de la religion. Simplifier pour les non-pensants.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;La foi est une métaphore.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Votre monde est limité si vous n’y laissez aucune place pour le merveilleux.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Morgan continue son exploration critique de la religion, mais avec plus de nuance cette fois. La foi comme métaphore laisse entrevoir une certaine ouverture.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;La religion établie a contre-attaqué. Les stratégies habituelles : incorporer les Martiens dans le grand tout, réinterpréter les écritures, voire en créer de nouvelles. Si ça ne marche pas, faute de matière grise suffisante pour réussir, tout nier en l’attribuant aux forces du mal, et brûler tous ceux qui diront le contraire. Ça devrait marcher.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Face à la découverte des Martiens, la religion s’adapte. Ou pas.&lt;/p&gt;

&lt;h2 id=&quot;sur-les-rituels&quot;&gt;Sur les rituels&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Disons que certains rituels doivent être observés si l’on veut garder une relation profitable avec le monde des esprits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;moments-de-légèreté&quot;&gt;Moments de légèreté&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Vous pensez que je serais lieutenant des Impacteurs de Carrera si je me vexais si facilement ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Écoute, avec des jambes comme les miennes, n’importe qui avec un codage génétique hétéro me courrait après.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;L’humour sec de Morgan parsème le récit, offrant des respirations bienvenues.&lt;/p&gt;

&lt;h2 id=&quot;le-mantra-de-quellcrist-falconer&quot;&gt;Le mantra de Quellcrist Falconer&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Regardez la réalité en face. Puis agissez en conséquence. C’est le seul mantra que je connaisse, la seule doctrine que je puisse vous offrir, et c’est beaucoup plus difficile que vous le pensez. Parce que je vous jure, on dirait que les humains sont câblés pour faire n’importe quoi sauf regarder la réalité en face. Ne priez pas. N’espérez pas. Ne croyez pas aux dogmes centenaires, aux rhétoriques mortes. N’abdiquez pas en faveur de votre conditionnement, vos visions ou votre connerie de sens de… ce que vous voulez. REGARDEZ LA RÉALITÉ EN FACE. PUIS agissez.&lt;/p&gt;

  &lt;p&gt;— Quellcrist Falconer, Discours avant l’assaut sur Millsport&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ce passage condense toute la philosophie de la série. Pragmatisme brutal, méfiance des illusions, appel à l’action. Difficile de ne pas le souligner.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Carbone Modifié T1</title>
   <link href="andyhazou.me/2026/01/18/surlignements-t1-carbone-modifie"/>
   <updated>2026-01-18T00:00:00+00:00</updated>
   <id>andyhazou.me/2026/01/18/surlignements-t1-carbone-modifie</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/assets/images/2026-01-19-altered-carbon.jpg&quot; alt=&quot;Altered Carbon.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Carbone Modifié de Richard Morgan est un classique du cyberpunk sorti en 2002 et qui a refait surface avec la série Netflix de 2018.&lt;/p&gt;

&lt;p&gt;Le livre explore sous la forme d’un thriller, un futur dystopique où la conscience humaine peut être numérisée et transférée d’un corps à l’autre. Je ne vais pas me pencher sur un résumé du livre ni sur son analyse, mais simplement partager les passages qui m’ont marqué dans ma lecture.&lt;/p&gt;

&lt;h2 id=&quot;sur-la-société-et-la-religion&quot;&gt;Sur la société et la religion&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Qu’est-ce que la « résolution 653 » ? — Une proposition de loi en discussion à la Cour des Nations unies. Le bureau du procureur de Bay City veut assigner à comparaître une catholique en unité de stockage. Un témoin capital. Le Vatican déclare qu’elle est déjà morte et dans les mains de Dieu. Ils disent que ce serait un blasphème de la ramener.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un des concepts les plus intéressants du livre : les catholiques refusent d’être réinstanciés dans un nouveau corps. La notion d’âme étant alors remise en question, cela crée des tensions juridiques.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Le catholicisme et la tyrannie sont bons amis. Ils sont issus de la même culture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Morgan ne fait pas dans la nuance.&lt;/p&gt;

&lt;h2 id=&quot;sur-les-relations-humaines&quot;&gt;Sur les relations humaines&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Après un peu moins de deux cent cinquante ans de mariage, la politesse est l’essence principale de ma relation avec Miriam.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Que devient une relation de couple quand la mort n’existe plus ?&lt;/p&gt;

&lt;h2 id=&quot;sur-la-nature-humaine&quot;&gt;Sur la nature humaine&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Le shopping est une interaction physique, un exercice de prise de décision… un mélange entre la satiété du désir d’acquérir, l’impulsion d’acquérir de nouveau, l’envie d’explorer. Putain, c’est si humain, quand on y pense.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Je ne sais pas si c’est ironique mais ce passage m’a tellement fait sourire.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;La pensée consciente n’a pas grand-chose à voir avec le désir. Si l’on en croit les psychologues, elle n’a pas grand-chose à voir avec la façon dont nous vivons notre vie, d’ailleurs. Nous rationalisons nos actes après coup, mais les maîtres, ce sont les hormones, les gènes, et les phéromones pour le réglage fin. Triste, mais vrai.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;La personnalité n’est rien de plus que la forme passagère d’une des vagues devant soi… ou, pour ralentir le processus à une vitesse plus humaine, la personnalité est une dune. Une forme passagère qui répond au stimulus du vent, de la gravité, de l’éducation. De la carte des gènes. Tout est sujet à l’érosion et au changement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ces réflexions sur l’identité prennent une dimension particulière dans un monde où on peut changer de corps comme de chemise.&lt;/p&gt;

&lt;h2 id=&quot;sur-la-violence-et-le-pouvoir&quot;&gt;Sur la violence et le pouvoir&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Mais souvenez-vous de la faiblesse des armes. Ce ne sont que des extensions. Vous êtes le tueur et le destructeur. Vous êtes complet, avec ou sans elles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Tu veux savoir comment on fabrique un Diplo ? Je vais te l’apprendre. Ils prennent ta psyché, et ils en grillent les mécanismes de limitation de violence. Les signaux de reconnaissance de soumission, les dynamiques de hiérarchie, les loyautés au groupe. Tout ça disparaît, un neurone à la fois… pour être remplacé par une volonté consciente de faire mal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Comme tous les hommes de pouvoir, quand il parlait de prix, vous pouviez être sûr d’une chose : c’était quelqu’un d’autre qui payait.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;autres-passages&quot;&gt;Autres passages&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;L’esprit réagit de manière créative dans les situations de stress intense.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Nos sens nous donnent l’illusion de la stabilité dans l’univers et nous l’acceptons, parce que sans cette illusion, rien ne peut être accompli.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Pourquoi cela ne me surprend-il pas ? — Peut-être parce que… — Laissez tomber. C’était une figure de style.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ce dernier échange m’a fait sourire. Kovacs a cet humour assez sec à travers tout le roman.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Le MDM est-il mort ?</title>
   <link href="andyhazou.me/2025/11/07/mdm-dead"/>
   <updated>2025-11-07T00:00:00+00:00</updated>
   <id>andyhazou.me/2025/11/07/mdm-dead</id>
   <content type="html">&lt;blockquote&gt;
  &lt;p&gt;Cat article a été écrit à 70% par un humain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;MDM = &lt;a href=&quot;https://en.wikipedia.org/wiki/Master_data_management&quot;&gt;Master Data Management&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Je suis récemment tombé sur ce &lt;a href=&quot;https://www.reddit.com/r/dataengineering/comments/1oed53z/mdm_is_dead_right/&quot;&gt;post&lt;/a&gt; sur le &lt;a href=&quot;https://www.reddit.com/r/dataengineering/&quot;&gt;r/dataengineering&lt;/a&gt; :&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;I have a few, potentially false beliefs about MDM. I’m being hot-takey on purpose. Would love a slap in the face.&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Data Products contextualize dims/descriptive data, in the context of the product, and as such they might not need a MDM tool to master it at the full/edw/firm level&lt;/li&gt;
    &lt;li&gt;Anything with “Master blah Mgmt” […] Modern Data ecosystems overall is probably dead just out of sheer organizational malaise, politics, bureaucracy and PMO styles of trying to “get everyone on board” with such a concept, at large.&lt;/li&gt;
    &lt;li&gt;Even if you bought a tool and did MDM well — on core entities of your firm (customer, product, region, store, etc.) — I doubt IT/business leaders would dedicate the labor discipline to keeping it up. It would become a key-join nightmare at some point.&lt;/li&gt;
    &lt;li&gt;Do “MDM” at the source. E.g. all customers come from CRM. Use the account_key and be done with it. If it’s wrong in Salesforce, get them to fix it.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Il a tout de suite attiré mon attention, surtout que je baigne dans le MDM depuis quelques années déjà dans mon rôle actuel.&lt;/p&gt;

&lt;p&gt;La discussion est centrée sur le fait que le MDM est “mort”, surtout dans un contexte de modern data stack.&lt;/p&gt;

&lt;p&gt;Le consensus : Le MDM en tant que concept demeure essentiel, mais les implémentations traditionnelles échouent souvent à cause de facteurs organisationnels et culturels plutôt que de limitations techniques.&lt;/p&gt;

&lt;p&gt;Ce avec quoi je suis totalement d’accord. J’ai remarqué que c’est avant tout une affaire d’hommes et de processus, plus que de technologie.&lt;/p&gt;

&lt;h2 id=&quot;un-problème-de-culture-et-non-de-technologie&quot;&gt;Un problème de culture et non de technologie&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;“It’s not about the tool, it’s about the org culture.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;Les implémentations échouent fréquemment par manque de soutien de la hiérarchie, de politiques organisationnelles adaptées et d’une incapacité à maintenir la discipline dans le temps.&lt;/li&gt;
  &lt;li&gt;Plusieurs utilisateurs ont rapporté leur expérience selon laquelle les initiatives MDM perdent souvent de leur élan après que l’excitation initiale s’est estompée.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;la-taille-et-le-contexte-sont-importants&quot;&gt;La taille et le contexte sont importants&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Les grandes entreprises sont celles qui ont le plus besoin du MDM : les entreprises du classement &lt;em&gt;Fortune 500&lt;/em&gt;, notamment celles qui réalisent des acquisitions fréquentes, considèrent le MDM comme un avantage stratégique.&lt;/li&gt;
  &lt;li&gt;Les petites organisations n’en ont peut-être pas besoin : les structures simples, disposant d’un seul CRM ou de sources de données limitées, peuvent souvent se passer d’outils MDM dédiés.&lt;/li&gt;
  &lt;li&gt;Les industries réglementées (santé, banque, finance, assurance) requièrent le MDM pour gérer les risques et la conformité.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;les-principaux-problèmes-que-résout-le-mdm&quot;&gt;Les principaux problèmes que résout le MDM&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Résolution d’entités : savoir si “le client X du système A” est le même que “le client Y du système B”.&lt;/li&gt;
  &lt;li&gt;Cohérence inter-domaines : garantir que les rapports de chaque département utilisent les mêmes dimensions analytiques (hiérarchies produits, géographiques, temporelles, etc.).&lt;/li&gt;
  &lt;li&gt;Intégration rapide des données de sociétés récemment acquises ou, dans mon entreprise, des données de GP (General Partner).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;le-piège-du-do-mdm-at-the-source&quot;&gt;Le piège du “Do MDM at the Source”&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Le point 4 de l’OP (juste utiliser le CRM ID comme source de vérité) simplifie grandement la réalité.&lt;/li&gt;
  &lt;li&gt;La plupart des grandes organisations ne disposent pas d’un seul système source de vérité pour leurs entités clés.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;“You never have a single definition of what a customer is in a company.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;défis-de-mise-en-œuvre&quot;&gt;Défis de mise en œuvre&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Discipline opérationnelle : les entreprises peinent souvent à dédier des ressources pour maintenir les systèmes MDM.&lt;/li&gt;
  &lt;li&gt;Dette technique : l’absence de MDM dès le départ transforme sa mise en place ultérieure en un projet de rattrapage coûteux et difficile à faire valider par la direction.&lt;/li&gt;
  &lt;li&gt;Limitations des outils clés en main : les solutions existantes (Informatica, Profisee, Reltio, Stibo) sont souvent perçues comme coûteuses, surdimensionnées, difficiles à intégrer et à maintenir.&lt;/li&gt;
  &lt;li&gt;Gestion du changement : le turnover des équipes peut poser problème ; les nouveaux collaborateurs sont rarement enclins à suivre rigoureusement des règles de gouvernance établies par leurs prédécesseurs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;alternatives-modernes-et-évolution-des-pratiques&quot;&gt;Alternatives modernes et évolution des pratiques&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Certaines organisations développent des solutions légères sur mesure (tables SQL, registres d’identifiants avec tables de correspondance).&lt;/li&gt;
  &lt;li&gt;Les concepts de Data Mesh contournent le MDM mais créent de nouveaux défis (comment croiser des produits de données entre domaines sans identifiant client commun ?).&lt;/li&gt;
  &lt;li&gt;Importance croissante de l’IA/ML : les LLM et couches sémantiques nécessitent des données de référence propres et cohérentes pour fonctionner efficacement.&lt;/li&gt;
  &lt;li&gt;Approches émergentes : résolution d’entités via l’analyse de graphes, algorithmes de rapprochement pilotés par l’IA.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;labsence-de-mdm-peut-avoir-des-coûts-cachés&quot;&gt;L’absence de MDM peut avoir des coûts cachés&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Sans MDM, les équipes sont souvent amenées à « réinventer la roue » à chaque nouveau projet.&lt;/li&gt;
  &lt;li&gt;Les incohérences de données sont corrigées au cas par cas, créant une charge opérationnelle continue.&lt;/li&gt;
  &lt;li&gt;Il existe un risque d’incohérences dans les indicateurs clés, les rapports aux investisseurs, les opportunités commerciales manquées, ou encore la non-conformité réglementaire.&lt;/li&gt;
  &lt;li&gt;Les migrations ERP peuvent échouer de manière catastrophique sans données de référence fiables.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Le MDM n’est pas mort. Comme tout concept lié à de la gouvernance il est difficile à appliquer.&lt;/p&gt;

&lt;p&gt;Le succès de sa mise en œuvre nécessite :&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;L’engagement de la direction et des ressources pérennes.&lt;/li&gt;
  &lt;li&gt;De le traiter comme un programme continu, et non comme un projet ponctuel.&lt;/li&gt;
  &lt;li&gt;D’adapter l’approche à la complexité de l’organisation.&lt;/li&gt;
  &lt;li&gt;De le considérer comme une discipline de processus métier, et non simplement comme un outil technique.&lt;/li&gt;
  &lt;li&gt;De rendre les utilisateurs métier responsables de la gouvernance des données.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La vraie question n’est pas de savoir si le MDM est nécessaire, mais si les organisations ont la maturité, l’envergure et la volonté de le mettre en œuvre correctement.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Expanding a Proxmox VM Disk on Debian</title>
   <link href="andyhazou.me/2025/10/22/expand-proxmox-vm-disk-debian"/>
   <updated>2025-10-22T00:00:00+00:00</updated>
   <id>andyhazou.me/2025/10/22/expand-proxmox-vm-disk-debian</id>
   <content type="html">&lt;blockquote&gt;
  &lt;p&gt;This post was generated largely by AI based on my notes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;1-check-the-current-layout&quot;&gt;1. Check the current layout&lt;/h2&gt;

&lt;p&gt;See how the disk and partitions are structured:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lsblk &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; NAME,FSTYPE,SIZE,MOUNTPOINT,TYPE
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;fdisk &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; /dev/sda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you resized the disk in Proxmox, it shows a larger size for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sda&lt;/code&gt; but partitions still reflect the old size.&lt;/p&gt;

&lt;h2 id=&quot;2-fix-the-gpt-table&quot;&gt;2. Fix the GPT table&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gdisk&lt;/code&gt; corrects the GPT header so it matches the new disk size.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;gdisk /dev/sda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;w&lt;/code&gt; and confirm with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;. This writes the corrected GPT to disk.&lt;/p&gt;

&lt;h2 id=&quot;3-reload-partition-table&quot;&gt;3. Reload partition table&lt;/h2&gt;

&lt;p&gt;Tell the kernel to reload the partition layout:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;partx &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; /dev/sda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;partx&lt;/code&gt; is missing, you can install &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;util-linux&lt;/code&gt; or just reboot.&lt;/p&gt;

&lt;h2 id=&quot;4-expand-the-root-partition&quot;&gt;4. Expand the root partition&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;growpart&lt;/code&gt; automatically extends partition 1 to fill all remaining
space.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;growpart /dev/sda 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The output should confirm that partition 1 has grown.&lt;/p&gt;

&lt;h2 id=&quot;5-resize-the-filesystem&quot;&gt;5. Resize the filesystem&lt;/h2&gt;

&lt;p&gt;Extend the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ext4&lt;/code&gt; filesystem to fill the new partition size:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;resize2fs /dev/sda1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This can be done online while mounted.&lt;/p&gt;

&lt;h2 id=&quot;6-verify-everything&quot;&gt;6. Verify everything&lt;/h2&gt;

&lt;p&gt;Check the new size and ensure all space is available:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt; /
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You should now see your full expanded disk space in use.&lt;/p&gt;

&lt;p&gt;To confirm integrity:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;gdisk &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; /dev/sda &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;e2fsck &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; /dev/sda1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Both should report clean results.&lt;/p&gt;

&lt;p&gt;The Debian root filesystem now uses the entire expanded Proxmox disk.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Gestion des conflits de dépendances avec Maven</title>
   <link href="andyhazou.me/2025/04/08/maven-dependencies-conflicts"/>
   <updated>2025-04-08T00:00:00+00:00</updated>
   <id>andyhazou.me/2025/04/08/maven-dependencies-conflicts</id>
   <content type="html">&lt;p&gt;Lorsqu’on travaille avec des projets Java, on utilise souvent des librairies (dépendances) qui viennent avec leurs propres dépendances; c’est ce qu’on appelle des dépendances transitives. Il est très fréquent pour des librairies de dépendre de différentes versions d’une même dépendance, ce qui peut conduire à des conflits de versions. Ces conflits peuvent provoquer des erreurs à la compilation ou au runtime, rendant le diagnostic difficile. Maven fournit une stratégie claire pour résoudre ce genre de conflits.&lt;/p&gt;

&lt;p&gt;Maven résout les conflits de dépendances en utilisant la stratégie de la définition la plus proche (aussi appelée chemin le plus court) :&lt;/p&gt;

&lt;ol class=&quot;indented-list&quot;&gt;
  &lt;li&gt;La version utilisée est celle de la dépendance qui est la plus proche de la racine de l’arbre de dépendance.&lt;/li&gt;
  &lt;li&gt;Si deux dépendances en conflit sont au même niveau, la première déclarée dans le POM est utilisée.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dans l’exemple suivant, la librairie &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;library-A:1.0&lt;/code&gt; sera utilisée car elle se retrouve au niveau 1 (directement déclarée dans le POM), même si &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;library-B&lt;/code&gt; dépend d’une version plus récente.&lt;/p&gt;

&lt;p&gt;Déclaration des dépendances :&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.example&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;library-A&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.example&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;library-B&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Arbre des dépendances :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;my-app
├── library-A:1.0         (depth 1)
└── library-B:2.0         (depth 1)
    └── library-A:2.0     (depth 2)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;identification-des-conflits&quot;&gt;Identification des conflits&lt;/h2&gt;

&lt;p&gt;Pour identifier les conflits de dépendances, on peut examiner l’arbre de dépendances soit directement dans l’IDE ou via la commande :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mvn dependency:tree
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pour un diagnostic plus détaillé, utilisez l’option verbose :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mvn dependency:tree -Dverbose
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cette commande fournit une vue claire de l’arbre complet des dépendances, ainsi que les versions utilisées et celles qui sont omises pour cause de conflit.&lt;/p&gt;

&lt;h2 id=&quot;résolution-des-conflits-avec-dependencymanagement&quot;&gt;Résolution des conflits avec dependencyManagement&lt;/h2&gt;

&lt;p&gt;Une bonne pratique pour résoudre les conflits de dépendances est d’utiliser le tag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/code&gt;. Cette section donne plus de contrôle sur les versions utilisées dans le projet sans ajouter directement les dépendances.&lt;/p&gt;

&lt;p&gt;Par exemple ici &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;library-A&lt;/code&gt; sera utilisée dans sa version &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2.0&lt;/code&gt; à travers tout le projet, peu importe les versions rencontrées dans les déclarations transitives :&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.example&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;library-A&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Il est important de noter que déclarer une dépendance dans &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/code&gt; ne l’ajoute pas au projet. Il faudra toujours la déclarer dans la section &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;dependencies&amp;gt;&lt;/code&gt;, mais sans préciser de version :&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.example&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;library-A&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Pas besoin de spécifier la version ici --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;utilisation-des-exclusions&quot;&gt;Utilisation des exclusions&lt;/h2&gt;

&lt;p&gt;Parfois, vous pourriez avoir besoin d’exclure explicitement une dépendance transitive. Par exemple, si &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;library-B&lt;/code&gt; dépend d’une version de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;library-A&lt;/code&gt; qui n’est pas compatible avec votre code :&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.example&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;library-B&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.example&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;library-A&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/exclusion&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;cas-pratiques&quot;&gt;Cas pratiques&lt;/h2&gt;

&lt;p&gt;Les conflits de dépendances ne sont pas forcément à résoudre. Le projet peut compiler et fonctionner comme il se doit avec des conflits de dépendances que Maven gère selon les règles mentionnées plus haut. Toutefois pour des soucis de cohérence il faut parfois s’assurer d’utiliser la bonne version.&lt;/p&gt;

&lt;p&gt;Par exemple, dans un projet Spring, on peut rencontrer différentes versions de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spring-core&lt;/code&gt; (par transitivité). Il est recommandé d’utiliser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/code&gt; afin de s’assurer d’utiliser une même version à travers tous les composants Spring.&lt;/p&gt;

&lt;p&gt;On peut aussi rencontrer des problèmes lorsqu’une nouvelle version d’une librairie apporte des changements non compatibles avec des versions antérieures. Dans ce cas il faut :&lt;/p&gt;

&lt;ul class=&quot;indented-list&quot;&gt;
  &lt;li&gt;identifier les dépendances utilisant la nouvelle version&lt;/li&gt;
  &lt;li&gt;mettre à jour le code avec la nouvelle API&lt;/li&gt;
  &lt;li&gt;ou utiliser les &lt;strong&gt;exclusions&lt;/strong&gt; et dépendre explicitement de l’ancienne librairie&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;outils-supplémentaires&quot;&gt;Outils supplémentaires&lt;/h2&gt;

&lt;p&gt;Pour une analyse plus poussée de vos dépendances, utilisez la commande :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mvn dependency:analyze
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cette commande identifie les dépendances utilisées mais non déclarées, ainsi que celles déclarées mais non utilisées, ce qui vous aide à optimiser votre POM.&lt;/p&gt;

&lt;h2 id=&quot;utilisation-des-bom-bill-of-materials&quot;&gt;Utilisation des BOM (Bill of Materials)&lt;/h2&gt;

&lt;p&gt;Pour les projets complexes, l’utilisation d’un BOM peut grandement simplifier la gestion des versions :&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-dependencies&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.7.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span class=&quot;nt&quot;&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span class=&quot;nt&quot;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cela importe toutes les versions de dépendances compatibles définies par Spring Boot, évitant ainsi de nombreux conflits potentiels.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>La Règle des 37%</title>
   <link href="andyhazou.me/2025/03/17/regle-37-pourcent"/>
   <updated>2025-03-17T00:00:00+00:00</updated>
   <id>andyhazou.me/2025/03/17/regle-37-pourcent</id>
   <content type="html">&lt;p&gt;La règle des 37% trouve son origine dans le “problème du secrétaire”, un classique de la théorie d’arrêt optimal. Dans ce problème, un recruteur doit embaucher un secrétaire parmi un nombre fini de candidats qu’il rencontre un par un. Après chaque entretien, il doit décider immédiatement : embaucher ce candidat ou passer au suivant, sans possibilité de rappel.&lt;/p&gt;

&lt;p&gt;Le défi est que le recruteur ne peut pas attribuer une note absolue aux candidats, seulement les comparer entre eux. La question devient donc : quelle stratégie adopter pour maximiser les chances de sélectionner le meilleur candidat?&lt;/p&gt;

&lt;p&gt;La stratégie optimale, démontrée mathématiquement, consiste à:&lt;/p&gt;

&lt;ol class=&quot;indented-list&quot;&gt;
  &lt;li&gt;Observer (sans choisir) les 37% premiers candidats&lt;/li&gt;
  &lt;li&gt;Identifier le meilleur candidat de ce groupe initial&lt;/li&gt;
  &lt;li&gt;Ensuite, sélectionner le premier candidat qui surpasse cette référence&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Le chiffre 37% correspond plus précisément à 1/e, où e est le nombre d’Euler (≈ 2,718). Cette formule garantit une probabilité de 37% de sélectionner le meilleur candidat possible - ce qui est le maximum atteignable dans ce contexte.&lt;/p&gt;

&lt;p&gt;Cette règle s’applique à diverses situations impliquant des choix séquentiels: recherche immobilière (explorer 37% des options disponibles avant de prendre une décision), recrutement (évaluer 37% des candidatures avant de commencer à embaucher), ou rencontres (consacrer 37% du temps disponible à explorer avant de s’engager).&lt;/p&gt;

&lt;p&gt;La règle fonctionne de manière optimale lorsque le nombre total d’options est connu à l’avance, les décisions sont irréversibles, et l’objectif est uniquement de trouver la meilleure option.&lt;/p&gt;

&lt;p&gt;J’ai découvert cette règle dans le livre &lt;a href=&quot;https://amzn.eu/d/aOFENnk&quot;&gt;Algorithms to Live By&lt;/a&gt;. Elle offre un cadre structuré pour aborder les décisions séquentielles et éviter deux erreurs communes: choisir trop tôt par impatience ou trop tard par perfectionnisme.&lt;/p&gt;

&lt;p&gt;Le chiffre 37% constitue donc un point de référence précis et efficace pour les situations de choix séquentiels où l’on ne peut pas revenir en arrière.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Creating SSL Certificate in Nginx Proxy Manager</title>
   <link href="andyhazou.me/2025/02/17/ssl-certificates-npm-letsencrypt-cloudflare"/>
   <updated>2025-02-17T00:00:00+00:00</updated>
   <id>andyhazou.me/2025/02/17/ssl-certificates-npm-letsencrypt-cloudflare</id>
   <content type="html">&lt;p&gt;If you self-hosted and/or have a homelab, you’ll need to expose some services to the Internet. This guide provides step-by-step instructions for creating SSL certificates for your services in &lt;a href=&quot;https://nginxproxymanager.com/&quot;&gt;Nginx Proxy Manager (NPM)&lt;/a&gt;. 
We’ll use &lt;a href=&quot;https://letsencrypt.org/fr/&quot;&gt;Let’s Encrypt&lt;/a&gt; as the certificate authority and &lt;a href=&quot;https://www.cloudflare.com/fr-fr/&quot;&gt;Cloudflare&lt;/a&gt;’s DNS validation method.&lt;/p&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;

&lt;ul class=&quot;indented-list&quot;&gt;
  &lt;li&gt;Nginx Proxy Manager installed and running&lt;/li&gt;
  &lt;li&gt;A domain managed through Cloudflare&lt;/li&gt;
  &lt;li&gt;Access to your Cloudflare admin dashboard&lt;/li&gt;
  &lt;li&gt;DNS records properly set up in Cloudflare&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;getting-the-cloudflare-api-token&quot;&gt;Getting the Cloudflare API Token&lt;/h2&gt;

&lt;p&gt;First, create an API token that NPM will use to validate your domain ownership. From your Cloudflare dashboard:&lt;/p&gt;

&lt;ol class=&quot;indented-list&quot;&gt;
  &lt;li&gt;Navigate to &lt;strong&gt;API Tokens&lt;/strong&gt; in the menu&lt;/li&gt;
  &lt;li&gt;Click &lt;strong&gt;Create Token&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Select &lt;strong&gt;Custom Token&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Configure these settings:
    &lt;ul&gt;
      &lt;li&gt;Name: “MyHomeLab-ApiToken” (or any descriptive name)&lt;/li&gt;
      &lt;li&gt;Permissions: Zone → DNS → Edit&lt;/li&gt;
      &lt;li&gt;Zone Resources: Your specific domain(s)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Create and copy your token&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;setting-up-the-certificate-in-npm&quot;&gt;Setting Up the Certificate in NPM&lt;/h2&gt;

&lt;p&gt;Now let’s create the SSL certificate in Nginx Proxy Manager:&lt;/p&gt;

&lt;ol class=&quot;indented-list&quot;&gt;
  &lt;li&gt;Go to your NPM dashboard&lt;/li&gt;
  &lt;li&gt;Navigate to &lt;strong&gt;SSL Certificates&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Click &lt;strong&gt;Add SSL Certificate&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Configure the certificate:&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;domain-settings&quot;&gt;Domain Settings&lt;/h3&gt;

&lt;ul class=&quot;indented-list&quot;&gt;
  &lt;li&gt;Primary domain: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;example.com&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Wildcard domain: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.example.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;dns-challenge-configuration&quot;&gt;DNS Challenge Configuration&lt;/h3&gt;

&lt;ul class=&quot;indented-list&quot;&gt;
  &lt;li&gt;Check “Use a DNS Challenge”&lt;/li&gt;
  &lt;li&gt;DNS Provider: Cloudflare&lt;/li&gt;
  &lt;li&gt;API Token: Paste your Cloudflare token&lt;/li&gt;
  &lt;li&gt;Propagation Time: 120 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click Save and NPM will:&lt;/p&gt;

&lt;ul class=&quot;indented-list&quot;&gt;
  &lt;li&gt;Verify your domain through Cloudflare&lt;/li&gt;
  &lt;li&gt;Generate the SSL certificate&lt;/li&gt;
  &lt;li&gt;Set up automatic renewal&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;security-tips&quot;&gt;Security Tips&lt;/h2&gt;

&lt;p&gt;A few important security notes:&lt;/p&gt;

&lt;ul class=&quot;indented-list&quot;&gt;
  &lt;li&gt;Limit the API token to only the domains you need&lt;/li&gt;
  &lt;li&gt;Keep your API token secure&lt;/li&gt;
  &lt;li&gt;Check certificate renewal status periodically&lt;/li&gt;
  &lt;li&gt;Review NPM logs for any certificate issues&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Terror in Resonance</title>
   <link href="andyhazou.me/2025/01/30/terror-in-resonance"/>
   <updated>2025-01-30T00:00:00+00:00</updated>
   <id>andyhazou.me/2025/01/30/terror-in-resonance</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/assets/images/2025-01-30-terror-in-resonance.png&quot; alt=&quot;Logo de la version internationale de l&apos;anime.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Terror in Resonance est une série d’animation japonaise de 11 épisodes produite par le studio MAPPA en 2014. L’histoire nous plonge dans un Japon contemporain, marqué par les séquelles de la Seconde Guerre mondiale.&lt;/p&gt;

&lt;p&gt;Au cœur de l’intrigue se trouve un programme gouvernemental secret visant à améliorer artificiellement l’intelligence humaine. Pour mener à bien cette expérience, une vingtaine d’enfants de moins de 5 ans ont été enlevés. Suite à un mystérieux accident, le programme a brutalement pris fin, laissant derrière lui de nombreuses zones d’ombre.&lt;/p&gt;

&lt;p&gt;Des années plus tard, deux survivants de ce programme, connus uniquement sous les numéros 9 et 12, réapparaissent à Tokyo. Sous le pseudonyme de Sphinx, ils orchestrent une série d’attentats dans la capitale japonaise. Fait notable, leurs actions terroristes se distinguent par une caractéristique surprenante : elles ne font pratiquement aucune victime. Au fil des épisodes, on découvre que leur véritable objectif est de révéler au grand jour l’existence de ce programme qui a façonné leur destin.&lt;/p&gt;

&lt;p&gt;Un personnage particulièrement marquant de la série est le détective Shibazaki. Son investigation est rythmée par les énigmes laissées par Sphinx, créant un jeu du chat et de la souris intellectuel qui ajoute une dimension supplémentaire à l’intrigue.&lt;/p&gt;

&lt;p&gt;Le scénario, bien que comportant quelques incohérences dans sa construction, parvient à maintenir l’intérêt du spectateur tout au long des 11 épisodes grâce à ses mystères et ses rebondissements.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Monday Mornings Haïku</title>
   <link href="andyhazou.me/2023/11/28/monday-mornings-haiku"/>
   <updated>2023-11-28T00:00:00+00:00</updated>
   <id>andyhazou.me/2023/11/28/monday-mornings-haiku</id>
   <content type="html">&lt;p&gt;Monday mornings suck&lt;/p&gt;

&lt;p&gt;those grumpy faces can tell&lt;/p&gt;

&lt;p&gt;blaming you for it&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Late Night Haïku</title>
   <link href="andyhazou.me/2023/11/22/late-night-haiku"/>
   <updated>2023-11-22T00:00:00+00:00</updated>
   <id>andyhazou.me/2023/11/22/late-night-haiku</id>
   <content type="html">&lt;p&gt;3 am in my bed&lt;/p&gt;

&lt;p&gt;my eyes are still wide opened&lt;/p&gt;

&lt;p&gt;with thrillers in my head.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Context Switching and Task Interruptions</title>
   <link href="andyhazou.me/2022/05/08/context-switching-task-interruption"/>
   <updated>2022-05-08T00:00:00+00:00</updated>
   <id>andyhazou.me/2022/05/08/context-switching-task-interruption</id>
   <content type="html">&lt;p&gt;&lt;em&gt;As a professional developer, I often get some deeply focused sessions of work, especially when I’m programming. One thing I’ve noticed is the difficulty to resume after I get interrupted from those sessions. My role also requires me to be involved in more than one project, thus jumping from one task to another not necessarily related. It’s hard, without a strategy to quickly get back into an interrupted work in progress.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This difficulty has been studied and explained by cognitive scientists and psychologists. It’s called &lt;em&gt;context switching&lt;/em&gt;. In this post I share their findings and my comprehension of the subject and give some strategies to reduce the impact of the inevitable.&lt;/p&gt;

&lt;h2 id=&quot;computers-vs-humans&quot;&gt;Computers vs Humans&lt;/h2&gt;

&lt;p&gt;It all started with the word &lt;em&gt;multitask&lt;/em&gt;, invented by IBM in 1985 to describe a computer capability.&lt;/p&gt;

&lt;p&gt;A multitask operating system is designed to work on multiple tasks but not at the same time. It works briefly on the first task, then saves the system state for that task. The interrupted task moves to the end of the queue and the system switches to the next task until all the assigned tasks are considered done. This operation is so fast that we have the impression that all the tasks are executed at the same time. The process of storing the state in order to pause the task and resume another is called context switch. A context switch can also occur as the result of an &lt;a href=&quot;https://en.wikipedia.org/wiki/Interrupt&quot;&gt;interrupt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can find similarities between how computers multitask and how humans “multitask”. For humans, multitasking means &lt;a href=&quot;https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7075496/&quot;&gt;trying to perform two or more tasks concurrently, which typically leads to repeatedly switching between tasks (i.e., task switching) or leaving one task unfinished in order to do another.&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;what-is-context-switching-&quot;&gt;What is Context Switching ?&lt;/h2&gt;

&lt;p&gt;Context switching, also called task switching, is to jump from one task to another unrelated task, causing a mental shift resetting the working memory. Context switching is a consequence of multitasking.&lt;/p&gt;

&lt;p&gt;It happens when for example you’re writing an email to explain an issue and get interrupted for a support task by instant messaging. Or when you’re writing technical documentation and paused for a code review.&lt;/p&gt;

&lt;h2 id=&quot;what-causes-context-switching&quot;&gt;What causes Context Switching?&lt;/h2&gt;

&lt;p&gt;Context switching can be caused by something as simple as self interruptions (not motivated to pursue the task on hand, boredom, need to take a break etc.). Other triggers are external events like a shoulder tap, a question from a colleague or a simple disruption like a notification.&lt;/p&gt;

&lt;p&gt;For developers, it can be a pull request which interrupts a programming task or multiple upcoming unrelated meetings. Unforeseen events related to ongoing projects can also be sources of context switching (changes in a task priority, blockages due to unavailable resources etc.).&lt;/p&gt;

&lt;p&gt;And last but not least, there’s the myth that multitasking makes us overachievers, efficient and high performers. Our contemporary work culture values and rewards multi-taskers and responsiveness and our digital tools don’t help.&lt;/p&gt;

&lt;p&gt;No wonder that at the end of the day most of us feel exhausted and drained.&lt;/p&gt;

&lt;h2 id=&quot;the-cost-of-context-switching&quot;&gt;The Cost of Context Switching&lt;/h2&gt;

&lt;p&gt;As you may have guessed, context switching has a cost (as for &lt;a href=&quot;https://en.wikipedia.org/wiki/Context_switch&quot;&gt;computers&lt;/a&gt;). We may think that we’re getting more done by accepting more and more tasks and by switching between them but it’s counterproductive. The American Psychological Association (APA) found in a &lt;a href=&quot;https://www.apa.org/topics/research/multitasking&quot;&gt;study&lt;/a&gt; that it leads to a 40% decrease of an employee’s productive time.&lt;/p&gt;

&lt;p&gt;Context switching impacts our mental energy, our brain and even our memory. Even your IQ can be impacted. A &lt;a href=&quot;http://discovery.ucl.ac.uk/1465496/&quot;&gt;study by the University of London&lt;/a&gt; found a decrease in IQ for participants who multitasked during complex cognitive tasks.&lt;/p&gt;

&lt;p&gt;Another study conducted by Gloria Mark, a Professor from University of California Irvine found that &lt;a href=&quot;https://www.fastcompany.com/944128/worker-interrupted-cost-task-switching&quot;&gt;it takes up to 23 minutes to refocus our effort after just one interruption&lt;/a&gt;. This leads to more stress, working faster to get more done, thus makes us superficial thinkers.&lt;/p&gt;

&lt;p&gt;To study the effects on developers in more detail, &lt;a href=&quot;https://link.springer.com/article/10.1007/s11219-010-9104-9&quot;&gt;Chris Parnin and his colleagues&lt;/a&gt; made an exploratory analysis of 10000 programming sessions recorded from 86 programmers using Eclipse and Visual Studio, and a survey of 414 programmers. They found that a programmer takes between 10-15 minutes to start editing code after resuming work from an interruption. It’s less than the 23 minutes mentioned earlier but no less important. Also, when interrupted during an edit of a method, only 10% of times did a programmer resume work in less than a minute. And finally, developers only get one uninterrupted 2-hours session per day.&lt;/p&gt;

&lt;p&gt;It seems context switching cannot be totally avoided. Especially in modern software development, when you’re part of a team and involved in agile projects. But how can we manage to reduce its impact?&lt;/p&gt;

&lt;h2 id=&quot;how-to-reduce-the-impact-of-context-switching&quot;&gt;How to reduce the Impact of Context Switching?&lt;/h2&gt;

&lt;p&gt;On the developer’s desk, there are a few things to do in order to reduce context switching. It’s important to have a “where was I?” strategy in case of interruptions. What I found helpful is to quickly jot down keywords linked to the context of the interrupted task. It reduces the load on my working memory and the time it takes to resume the task. It’s also good to adopt best practices in development like clean code (clearly named variables, methods, classes, well organised code, etc.). That way, the code itself can help resume the programming session.&lt;/p&gt;

&lt;p&gt;Some IDEs like Eclipse have a set of tools to improve resumption of development tasks.One of those plugins is &lt;a href=&quot;https://www.eclipse.org/mylyn/&quot;&gt;Mylyn&lt;/a&gt;. It integrates various task trackers such as Bugzilla, Mantis, JIRA.&lt;/p&gt;

&lt;p&gt;When you mark that you are working on a given task, Mylyn activates the context including the various files opened during analysis and development.&lt;/p&gt;

&lt;p&gt;On a more macro level, it’s important to work on how your day is scheduled. For example, you can batch together linked tasks, meetings. Our common advice is also to schedule the more important tasks first in the morning or at the end of the day. The thing here is to have a dedicated, not interruptible period of time. It’s also important to learn how to prioritise. You can ask your manager for help if needed.&lt;/p&gt;

&lt;p&gt;If your role requires responsiveness, you need to figure out what level of responsiveness you need to provide. You can also adopt asynchronous communication. When balanced with synchronous communication, It can improve the developing experience and leads to more quality responses.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In this post I’ve tried to give more insights on context switching and task interruptions and how they impact knowledge workers, especially developers. Psychologists have studied context switching, and found it can negatively impact our productivity and also our mental health in many ways… However it’s important to note that not all interruptions are a big loss. Switching tasks is unavoidable and sometimes can even increase developers productivity in some cases. In fact it all depends on the context in which it occurs. If a colleague working on the same project as you interrupts to exchange ideas about the task at hand this can be a productive interruption.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Handling API access token refresh with Caffeine</title>
   <link href="andyhazou.me/2022/01/04/access-token-refresh-caffeine"/>
   <updated>2022-01-04T00:00:00+00:00</updated>
   <id>andyhazou.me/2022/01/04/access-token-refresh-caffeine</id>
   <content type="html">&lt;p&gt;There are numerous resources on the Web on how to handle external API access tokens. One thing they have in common is the best practice that consists in storing the token internally in order to avoid unnecessary refreshes. I was recently confronted with this at work.&lt;/p&gt;

&lt;p&gt;Our application needed to make authenticated requests to an external Web API. At first we implemented our client to make a call to the authorization server to retrieve the access token before performing the actual request. We were making unnecessary calls to the auth server. We eventually got a call from the team in charge of the saas, with a suggestion to limit those calls.&lt;/p&gt;

&lt;p&gt;We decided to use a cache system to store the access token until it expires.&lt;/p&gt;

&lt;p&gt;We chose &lt;a href=&quot;https://github.com/ben-manes/caffeine&quot;&gt;caffeine&lt;/a&gt;, “a high performance, near optimal caching library”. Caffeine is for Java applications and is well integrated with popular frameworks like Spring, Apache Camel or Quarkus …&lt;/p&gt;

&lt;p&gt;Caffeine can be added via Maven :&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.github.ben-manes.caffeine&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;caffeine&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.9.2&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then we simply had to write an access token handler :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AccessTokenHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoadingCache&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AccessTokenHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AccessTokenHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Caffeine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
				&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;maximumSize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
				&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;expireAfterWrite&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Duration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ofMinutes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
				&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestAccessToken&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
	
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;synchronized&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AccessTokenHandler&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AccessTokenHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getAccessToken&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;external-api-access-token&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;requestAccessToken&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;//TODO Retrieve access token from Auth server	&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AccessTokenHandler&lt;/code&gt; is a Singleton providing a single access to the token cache.&lt;/p&gt;

&lt;p&gt;In the private constructor we build a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadingCache&lt;/code&gt; with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maximumSize&lt;/code&gt;  of 1, which expires 59 minutes after write. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;requestAccessToken()&lt;/code&gt; Function is used to refresh the access token from auth server.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AccessTokenHandler&lt;/code&gt; provides a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getAccessToken()&lt;/code&gt;method to retrieve the cached access token value. The cache is then used as the main facade and we only call the authentication server after the access token is expired.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Swagger Codegen</title>
   <link href="andyhazou.me/2021/09/10/swagger-codegen"/>
   <updated>2021-09-10T00:00:00+00:00</updated>
   <id>andyhazou.me/2021/09/10/swagger-codegen</id>
   <content type="html">&lt;p&gt;Récemment au travail, nous avions eu besoin de connecter à l’API REST d’un SAAS, le progiciel autour duquel nous effectuons nos développements. La documentation de l’API nous a été fournie sous forme de spécification Swagger. Nos développements se faisant essentiellement en Java, nous avons donc besoin d’implémenter un client d’API REST en Java. La méthode naïve aurait été de partir du Swagger et de tout construire manuellement à partir de la description des modèles, des opérations etc. mais la tâche me semblait plutôt fastidieuse.&lt;/p&gt;

&lt;p&gt;Après quelques recherches, j’ai découvert &lt;a href=&quot;https://swagger.io/docs/open-source-tools/swagger-codegen/&quot;&gt;Swagger Codegen&lt;/a&gt;. Il s’agit d’un utilitaire qui permet la génération automatique de clients d’API REST, de stubs de serveurs et de documentation, et ce à partir d’une spécification &lt;a href=&quot;https://github.com/OAI/OpenAPI-Specification&quot;&gt;OpenAPI&lt;/a&gt;. Plusieurs langages et frameworks sont supportés dont Java.&lt;/p&gt;

&lt;p&gt;Swagger Codegen est téléchargeable sous forme de fichier .jar et peut se lancer en ligne de commande avec un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java -jar&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;java -jar swagger-codegen-cli-2.2.1.jar generate -i specification-api-swagger.json -l java rest-client/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;La spécification de l’API avec laquelle on doit communique est sous forme de fichier .json qu’on peut télécharger depuis la page HTML de la documentation Swagger. Elle est passée à la commande avec l’argument &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-i&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-l&lt;/code&gt; est utilisé pour spécifier le langage dans lequel l’on souhaite générer le code pour notre client REST.&lt;/p&gt;

&lt;p&gt;Et voilà! Swagger Codegen nous génère un projet Java Maven bien structurée avec les POJO représentant le modèle de donnée, les utilitaires pour effecturer les appels d’API, la gestion de l’authentification et même la document Javadoc, … Ce projet peut désormais servir de base pour démarrer l’implémentation de notre client REST et permettre d’aller plus vite.&lt;/p&gt;

&lt;p&gt;Pour plus d’infos : &lt;a href=&quot;https://swagger.io/docs/open-source-tools/swagger-codegen/&quot;&gt;https://swagger.io/docs/open-source-tools/swagger-codegen/&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>First post</title>
   <link href="andyhazou.me/2020/08/28/first-post"/>
   <updated>2020-08-28T00:00:00+00:00</updated>
   <id>andyhazou.me/2020/08/28/first-post</id>
   <content type="html">&lt;p&gt;Lorem ipsum dolor amet tousled viral art party blue bottle single-origin coffee cardigan, selvage man braid helvetica. Banh mi taxidermy meditation microdosing. Selvage cornhole YOLO, small batch vexillologist raclette VHS prism sustainable 8-bit ugh semiotics letterpress disrupt pop-up. Celiac shabby chic ugh, jianbing whatever kitsch tattooed edison bulb kogi irony etsy.&lt;/p&gt;

&lt;p&gt;Franzen polaroid hammock iceland blue bottle woke disrupt tilde kale chips raw denim ramps vaporware before they sold out irony. Narwhal vaporware offal shaman celiac kinfolk activated charcoal salvia lomo irony readymade normcore. Yr activated charcoal kombucha, man braid whatever biodiesel hella crucifix adaptogen bicycle rights small batch skateboard mixtape. Hot chicken sustainable green juice 90’s. Ennui kickstarter hella pug, meggings man bun shaman messenger bag. Chambray adaptogen kombucha pug affogato, kogi green juice distillery ugh banh mi.&lt;/p&gt;

&lt;p&gt;VHS roof party waistcoat cold-pressed, street art wolf master cleanse affogato franzen. Shaman iceland pour-over intelligentsia typewriter tilde, pitchfork copper mug. Wayfarers kickstarter adaptogen vinyl beard kombucha. Organic pinterest master cleanse, mixtape fam gentrify lo-fi kogi.&lt;/p&gt;

&lt;p&gt;Salvia blue bottle fanny pack mlkshk normcore YOLO viral umami four dollar toast skateboard. Chambray taxidermy slow-carb street art chartreuse. Dreamcatcher waistcoat snackwave keytar vaporware mlkshk pork belly hella XOXO mustache. Tattooed semiotics edison bulb, disrupt polaroid craft beer vape enamel pin bespoke flannel letterpress brooklyn subway tile copper mug. Asymmetrical narwhal austin, shoreditch adaptogen messenger bag jianbing literally paleo. Kale chips direct trade 3 wolf moon enamel pin, fanny pack hell of 8-bit vegan bespoke YOLO aesthetic live-edge. Retro succulents before they sold out whatever bushwick.&lt;/p&gt;

&lt;p&gt;Actually hella you probably haven’t heard of them quinoa try-hard la croix. Street art schlitz actually hell of pour-over air plant. Post-ironic franzen brunch mumblecore readymade. Food truck photo booth polaroid, gochujang vegan street art yr before they sold out man bun. Tilde selfies chia pitchfork everyday carry post-ironic mumblecore sartorial VHS master cleanse activated charcoal biodiesel williamsburg cronut jean shorts. Poutine helvetica keffiyeh butcher pop-up.&lt;/p&gt;
</content>
 </entry>
 

</feed>
