11 octobre 2009

La persistance applicative comme un aspect

Dans le développement d'une application on pense souvent très tôt à la solution de persistance. Certains ont même une idée tellement précise du « modèle physique des données » — terminologie qui est une drôle de façon se se rassurer —, qu'ils vont à terme jusqu'à contraindre le comportement de l'application ou du système pour se conformer au schéma de la base. Ainsi du genre de réponses « on ne peut pas faire ce que vous demandez, à cause des clefs étrangères qui sont déclarées dans la base ». Ah… Et pourquoi ne pas faire des batchs d'audit et de rattrapage ? Et pourquoi ne pas gérer des états de mes données ? Et pourquoi ne pas laisser les transitions se faire de façon asynchrone ? Et surtout : si vous vous appuyez sur des clefs étrangères pour assurer l'intégrité métier de mes données, vous me faites plutôt penser que vous n'avez pas compris mon métier !
Quel métier se résume à des contraintes techniques d'intégrité ? (contraintes que du reste les DBAs font la plupart du temps sauter en production afin d'améliorer les perfs).

Cependant je ne veux pas reparler ici de centrer les objectifs du cycle de développement sur les processus métier, je considère que c'est acté.

Non, je voudrais parler de persistance.

Il y a des cas où les processus métier sont suffisamment simples pour être embarqués dans une application transactionnelle, où il n'y a pas ou quasiment pas d'existant, bref, où on a la latitude pour développer. Pléthore de frameworks de persistance viennent en sus à notre rescousse, on peut citer Hibernate (https://www.hibernate.org/) dans les premiers.

Pourtant nombre d'entre nous continuent de vouloir poser le schéma de la base, quand bien même serait-il un mapping naïf des propriétés des objets Java, dès le commencement.

Pourquoi ne pas simplement développer l'application ? On met toutes les données en mémoire, et on optimisera ensuite ! J'ai juste besoin dans un coin d'un compteur transactionnel pour mes états métier (ben, oui), compteur que je peux implémenter par un synchronized tout bête, et je fais mouliner le reste avec des classes ad hoc.

Plus tard, quand j'aurai besoin de partager mes données sur un cluster, ou de performances, ou tout simplement de sauvegardes parce que j'aurai à mettre en place un PRA (Plan de reprise d'activité, en gros comment remettre d'aplomb un deuxième système informatique si le premier vient de calancher, par exemple suite à un incendie), alors là, oui, je me pencherai sur la persistance. Mais c'est un aspect de l'application, au même titre que la sécurité ou les logs. Ce n'en est pas le cœur ni le socle ; ce n'est pas fondamental : l'absence de persistance des données, dans le sens général, n'empêche pas l'application de tourner.

D'ailleurs combien, parmi ceux qui pensent de suite à la solution de persistance, le font réellement parce qu'ils envisagent un PRA ou des performances maximales ? Non, le plus souvent la couche de persistance est envisagée comme une nécessaire façon de réaliser une application. Dans d'autres domaines on sait s'affranchir de ce genre de préjugés : les compilateurs dégagent, avec Ruby ou Groovy et l'aide des IDEs, les descriptions XML sont supplantées par des conventions ou des annotations, le besoin de hardware diminue grâce au cloud, on se fiche de l'OS parce qu'on fait du web, etc.

La couche technique de persistance n'est pas nécessaire dans une application. En revanche la couche logique de manipulation simple des données, notamment avec des verrous voire des états, et des vérifications d'intégrité, oui.
Et il y aura toujours moyen plus tard d'orchestrer tout ça et d'y ajouter les aspects désirés.

Pour finir, l'approche que je décris vise à éjecter la problématique de la persistance lorsqu'on se centre sur du développement applicatif. Pour d'autres types de réalisations, par exemple techniques, la question de la persistance se rencontre évidemment dès le début du chemin.

06 octobre 2009

svn://svn+ssh

Ceci sera un post légèrement cryptique pour les non informaticiens.

C'est juste pour me rappeler… comment accéder à Subversion par SSH avec clefs…

Sur le serveur : SSH. Permettre l'authentification par clefs.

Dans /etc/ssh/sshd_config :
RSAAuthentication yes

PubkeyAuthentication yes

AuthorizedKeysFile %h/.ssh/authorized_keys
Dans les ~/.ssh/ des intéressés, fichier authorized_keys avec une ligne par clef publique acceptée, du genre :
ssh-rsa AAAAB3Nz(…)PMRJl8=

ssh-rsa AAAAB3Nz(…)PM60l8==

ssh-rsa AAAAB35u(…)rT62zA== dandriana@ordinateur
Pour produire des clefs publiques, ssh-keygen sous Unix et Puttygen sous Windows. Si Puttygen, une fois la clef publique créée, l'exporter au format OpenSSH pour pouvoir l'utiliser sur un serveur Unix.

C'est lors de la génération des clefs qu'est demandée la « passphrase », mot de passe qui active la clef privée.

Sur le serveur : Subversion. Vu qu'on va faire du svn+ssh, pas besoin de lancer svnserve, donc.

Sur le client : SSH.

Sous Unix, clefs privées et publiques à mettre dans ~/.ssh. En général leurs noms respectifs sont « id_rsa » (-rw-------) et « id_rsa.pub » (-rw-r--r--). Connexion en : ssh -l <username> -i </path/to/private/key>

Sous Windows, clefs à mettre chais pas où, tellement c'est sécurisé. Faire pointer Putty dessus.

Rappel : les clefs publiques « xxx.pub » sont destinées à être fournies publiquement : envois par e-mail, publication dans un blog…

En revanche les clefs privées sont à protéger absolument. Elles sont plus précieuses que le mot de passe (« passphrase ») qui les active.

Sur le client : agent SSH. Pour éviter d'avoir à s'authentificer à chaque fois.

Sous Unix, ssh-agent :
exec ssh-agent bash

ssh-add </path/to/private/key>
Sous Windows, Pageant.

ssh-agent et Pageant peuvent être lancés au démarrage pour gagner du temps. Cela dépend de l'usage qu'on en a.

Sur le client : Subversion+SSH.

Sous Unix, déclarer dans son .profile une variable d'environnement SVN_SSH, du genre :
export SVN_SSH="ssh -l <username> -i </path/to/private/key>"
Si ça ne fonctionne pas, voir ~/.subversion/config.

Sous Windows, après une installation de la version de CollabNet de Subversion, j'ai mis ceci dans C:\Documents and Settings\<user>\Application Data\Subversion\config :
[tunnels]
ssh=<C:\path\to\>PLINK.EXE -l <username> -i <C:\path\to\private\key>