Tuxitecte

Maven + Alfresco : Format de livraison




Bonjour à tous !

Cette fois ci, il est temps de parler du format de livraison de votre projet. Vous me direz, il nous parle depuis plusieurs post du format AMP et maintenant il veut nous livrer autre chose ? C'est un peu ça... Suivant les projets, la distribution des rôles, les équipes et les bonnes pratiques de l'entreprise, le format de livraison va être simple ou bien très très complexe!

Prenons le cas classique, d'un côté une équipe de développement et de l'autre une équipe d'exploitation. Le premier est en charge de créer le produit, l'autre est en charge d'installer le produit et de vérifier qu'il fonctionne tout au long de sa durée de vie.

La question : Quel est le format d'échange du produit entre ces deux équipes ?
Ps : on ne tiendra pas compte ici de toute la documentation à fournir à l'équipe de production...

Listons un peu les différents cas possibles :
  • un (des) AMP(s) : Pour l'équipe de développement c'est le format le plus simple. En effet c'est le format de sortie de notre projet ! Il suffit donc de récupérer le fichier .amp et de l'envoyer ! Bien entendu si notre projet est constitué de plusieurs AMPs, on enverra l'ensemble des AMPs. Dans ce cas de figure, c'est l'équipe de production qui est en charge de générer le WAR de l'application en utilisant le script fourni par Alfresco.
  • un WAR : Ici, c'est l'équipe de développement qui a la responsabilité de créer le war. Ils doivent intégrer les différents modules dans le war Alfresco par défaut. L'équipe de production n'aura simplement qu'à installer l'application.
  • un WAR + AMP : Dans ce cas de figure, l'équipe de production demande à avoir l'application + les AMPs.
  • Autre : Ici vous pouvez inventer tout ce qui vous passe par la tête. Si vous travaillez dans des gros projets, ou dans des entreprises de grandes tailles, je pense que vous avez de très beaux exemples!
Comme vous pouvez le voir, les exemples ne manquent pas ! C'est même plutôt le contraire. La question que l'on se pose alors :
Comment créer ces nouveaux formats de distribution dans notre projet AMP ?.

L'idée comme d'habitude consiste à lancer une commande Maven et d'attendre le résultat attendu. Ne jamais oublier que le développeur est censé être un fainéant ^^ .

Dans les lignes ci-dessous, je vais vous présenter 2 approches pour générer autre chose que votre AMP. Ces approches se basent sur un nouveau projet Maven appelé alf-war-osecm.

Remarque : Cette approche n'est pas très conforme à la philosophie Maven mais effectue le travail désiré.

Création d'un nouveau projet AMP

Définir la structure

Créez un répertoire avec pour nom : alf-war-osecm
Ajoutez y un fichier pom.xml avec pour valeur


xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
fr.opensourceecm
alf-war-osecm
pom
0.1
Alfresco AMP Open Source ECM
Open Source ECM - Extension




Intégrer l'outil dans un repository
Dans ce projet, on va utiliser le Module Management Tool d'Alfresco. Ce module est disponible dans le répertoire bin d'une installation standard Alfresco. Il est aussi disponible ici : http://wiki.alfresco.com/wiki/Community_Edition_file_list_3.3. Donc dans un premier temps, nous allons installer dans notre repository ce fichier avec la commande :

call mvn install:install-file -Dfile=alfresco-mmt.jar -DgroupId=org.alfresco.sdk -DartifactId=mmt -Dversion=3.3 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true


On effectuera cette commande, dans le répertoire où se situe notre fichier. Il nous sera ainsi possible de le retrouver via le mécanisme de dépendance maven classique.


Créer un nouveau WAR Alfresco
Maintenant, comme le titre l'indique, je souhaite générer un WAR avec l'ensemble des AMPs. Il faudra intégrer l'ensemble des AMPs dans un War Alfresco. Ce processus va se décomposer en 4 parties.
  • Définition des propriétés : Dans cette partie, on va initialiser des propriétés qui nous serviront au cours des autres parties.
  • Import des pré-requis : On va installer notre répertoire de travail avec le war et l'outil Alfresco.
  • Import des AMPs : Dans notre répertoire de travail, on va créer un sous-répertoire qui aura pour fonction de contenir l'ensemble des AMPs à intégrer.
  • Génération du war : Ici, on va lancer une ligne de commande pour intégrer les AMPs
  • (Optionnel) Installer dans un repository : Après la génération, on peut éventuellement ajouter une phase d'installation du war généré dans notre repository.

Définition des propriétés
On va définir 4 propriétés
  • work.dir : répertoire de travail
  • amps.dir : répertoire de dépôts des amps
  • mmt.jar : nom du fichier Module Management Tool
  • alfresco.war : Application Alfresco




livraison
amps
mmt.jar
alfresco.war



Import des pré-requis
Via le plugin maven-dependency-plugin nous allons réaliser le goal copy lors de la phase de prepare-package. Plus simplement, on veut copier un ensemble de dépendances (alfresco.war + outil Alfresco) dans notre répertoire de travail.


org.apache.maven.plugins
maven-dependency-plugin


war-copy-requisites
prepare-package

copy




org.alfresco.sdk
alfresco-community-war
3.3
war
${project.build.directory}/${work.dir}
${alfresco.war}


org.alfresco.sdk
mmt
3.3
jar
${project.build.directory}/${work.dir}
${mmt.jar}








Import des AMPs
Tout d'abord, on va ajouter un bloc dependencies à notre pom.xml. Dans notre cas, les dépendances de ce bloc seront :
  • fr.opensourceecm:alf-amp-osecm:amp:0.0.5
  • org.alfresco.sample:SDK-CustomWizard:amp:1.0
On aura ainsi dans notre pom.xml



fr.opensourceecm
alf-amp-osecm
0.0.5
amp


org.alfresco.sample
SDK-CustomWizard
1.0
amp





Ensuite, toujours via le plugin maven-dependency-plugin nous allons réaliser le goal copy-dependencies lors de la phase de prepare-package. Plus simplement, on veut copier l'ensemble des AMPs (défini en dépendance) dans un sous-répertoire de travail {amps.dir}.


org.apache.maven.plugins
maven-dependency-plugin


war-copy-amp
prepare-package

copy-dependencies


amp
${project.build.directory}/${work.dir}/${amps.dir}
false
true
true







Génération du war
Via le plugin exec-maven-plugin, nous allons réaliser le goal exec lors de la phase de package. Autrement dit, on veut réaliser le même comportement que le batch apply-amps.bat(ou .sh) mais via Maven.


org.codehaus.mojo
exec-maven-plugin
1.1


war-create
package

exec




java

-jar
${project.build.directory}/${work.dir}/${mmt.jar}
install
${project.build.directory}/${work.dir}/${amps.dir}
${project.build.directory}/${work.dir}/${alfresco.war}
-directory





Maintenant, il est possible de lancer la commande maven

mvn clean package


pour avoir dans le repertoire work.dir le fichier alfresco.war contenant l'ensemble des dépendances AMP définis dans notre pom.xml.

(Optionnel) Installer le war en local
Si vous souhaitez installer ce war dans votre repository local (et ainsi pouvoir créer des dépendances dans des buts de tests ou d'intégration), voici la configuration à ajouter dans votre phase de build :


org.apache.maven.plugins
maven-install-plugin
2.3


war-install
install

install-file


${project.build.directory}/${work.dir}/${alfresco.war}
${project.groupId}
${project.artifactId}
${project.version}
war
test
true
true






Avec la commande

mvn clean install

vous pouvez installer votre nouveau war. Bien entendu, vous pouvez modifier les différents paramètres pour correspondre à vos besoins...

Remarque : idem avec la phase deploy à quelques paramètres près... ^^



Créer un format de livraison personnalisé
Maintenant, nous allons nous intéresser à la création d'un format de livraison personnalisé. Dans mon cas, je souhaite
  • créer un fichier .zip avec
  • un dossier racine ..
  • un sous dossier amps contenant mes amps
  • un sous dossier application contenantt un alfresco.war (avec les amps déjà intégré)
Pour faire le travail, je vais utiliser le plugin maven-assembly-plugin. Ce plugin sert à créer des formats de distribution personnalisés. La configuration de ce plugin se fait en 2 temps : Création d'un fichier de description et Ajout dans le pom.xml

Création d'un fichier de description
Ce fichier de description définit le résultat attendu c'est à dire quels sont les répertoires à créer, les formats des fichiers, les droits, l'encoding... On peut en fait définir beaucoup de paramètres!
Dans notre cas, nous allons créer un fichier osecm-assembly.xml dans le répertoire alf-war-osecm\src\assembly. Ce fichier contiendra la configuration suivante :


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
production

zip

${project.groupId}.${project.artifactId}.${project.version}


target/${work.dir}
unix
/application

${alfresco.war}





/${amps.dir}

org.alfresco.sample:SDK-CustomWizard
fr.opensourceecm:alf-amp-osecm






Comme on peut le voir, il reprend la configuration attendue dans mon besoin.

Ajout dans le pom.xml
Maintenant, on doit définir dans le fichier pom.xml la déclaration de ce nouveau fichier. On ajoute donc le plugin maven-assembly-plugin avec pour configuration.



maven-assembly-plugin


src/assembly/osecm-assembly.xml





Lancer l'assemblage
Finalement, je peux lancer la commande Maven :

mvn clean assembly:assembly



pour assembler mon format de distribution. On retrouve ainsi dans le répertoire target le fichier alf-war-osecm-0.1-production.zip prêt à être envoyé !

Remarque : l'utilisation de ce plugin peut s'avérer être gourmand en mémoire. Pour résoudre ce problème augmentez les valeurs de MAVEN_OPTS dans vos variables d'environnements.
Lire la suite...

Maven + Alfresco : Relations entre AMPs



Hello World !

Cette fois ci je vais essayer de vous expliquer les relations multi-modules AMP et comment on peut les gérer avec Maven et dans Alfresco aussi...

Introduction

La problématique est la suivante :
Dans un projet multi-AMP, comment modéliser les relations et comment organiser notres (ou nos) projets Maven ?

Admettons que nous voulons créer un projet comprenant 3 AMPS : A, B, C

Avant toute chose, quelles sont les relations qui existent entre ces 3 AMPS ? Sont ils dépendants les uns par rapport aux autres ? Quels sont les relations induites ?

Ensuite, quel est le format de livraison de notre application ? S'agit il d'un WAR, d'un AMP unique, d'un ensemble d'AMP, d'un format particulier de livraison....

Suivant les réponses de chacune des questions, il faudra mettre en place une politique différente! et bien entendu une configuration des projets Maven différents !

On peut retrouver plusieurs cas d'utilisation.
  • Les relations simples : Autrement dit il s'agit des mêmes dépendances que l'on a déjà vu depuis que l'on a commencé nos projets. Dans notre cas, les modules A, B et C sont indépendants mais notre serveur de production a besoin de ces 3 modules pour répondre aux besoins des utilisateurs. Par exemple, il peut s'agir d'intégrer le module de RM d'Alfresco, le module SharePoint d'Alfresco et notre propre module comprenant nos personnalisation.
  • Les dépendances (faibles et fortes) : Dans ce cas de figure, l'un des modules a besoin d'un autre module pour fonctionner. Un exemple simple est la liaison qui peut exister entre un modèle de données et des actions associés à ce modèle de données. Si le modèle n'existe pas et n'est pas installé alors B ne peut fonctionner. Si B est modifié alors il modifie le comportement de A.
Comment modéliser (et tester!) ces relations dans notre projet ?

Les relations simples

Reprenons notre module alf-amp-osecm

Actuellement, notre module ne possède que des dépendances vers des librairies déjà présent dans le war Alfresco. Cela ne pose aucun problème puisque le démarrage de notre serveur jetty s'effectue avec le war d'Alfresco.

Or maintenant je souhaite tester mon module avec la présence d'un autre module. Pour exemple, je vais prendre le module SDK-TaggingSample (créé et transformé précédemment en module - cf. post ici). L'idée est d'ajouter ce module dans Alfresco.war, de packager mon module puis de lancer jetty pour qu'il prenne en compte mon module.

Pour ajouter mon module on va ajouter dans le pom.xml de mon projet alf-amp-osecm, le quadruplet ci-dessous entre les balises //dependencies> dans la profil webapp



org.alfresco.sample
SDK-TaggingSample
amp
1.0



A ce stade, on pourrait se dire, c'est bon on lance la commande maven :

mvn clean integration-test -P webapp,clean-jetty -DskipTests=true

et on a un Alfresco démarré avec nos 2 modules. Et bien non... Cela serait trop simple !

En effet, le format AMP est un format un peu particulier qui n'est reconnu par Maven que grâce au plugin : maven-amp-plugin. Or ici on a ajouté une dépendance avec un AMP ! La question qui se pose c'est comment maven sait il quoi en faire et sait il l'intégrer dans le war "explosé" nécessaire à jetty ? La réponse est bien entendu NON !

La solution réside dans la déclaration d'un nouveau plugin : maven-dependency-plugin. Ce plugin comme son nom l'indique nous permet de manipuler les dépendances et donc les artefacts et donc les AMP ! On va ainsi configurer ce plugin afin qu'il prenne en compte notre dépendance et l'installer dans le war.

Comment ? et bien via la configuration ci-dessous que l'on intégrera dans le profil webapp (dans mon cas, il se trouve maintenant dans le projet alf-sdk. Factorisation oblige ! Par contre la déclaration de dépendance se situe dans mon pom.xml)



org.apache.maven.plugins
maven-dependency-plugin


unpack-amps
process-resources

unpack-dependencies


amp
${build.directory}/${webapp.name}
META*





org.alfresco.maven.plugin
maven-amp-plugin
3.0.2





On note que ce plugin va prendre toutes les dépendances de type AMP et va exécuter le goal : unpack-dependencies dans le répertoire ${build.directory}/${webapp.name}. En d'autre terme il va installer l'AMP comme le ferait (presque) l'outil de management des modules.

Ensuite, on doit ajouter un bloc testRessource toujours dans le profil Webapp.


true
.

module.properties

alfresco/module/${project.groupId}.${project.artifactId}



Ce bloc est nécessaire dès que l'on veut intégrer plusieurs AMP dans un war (ce qui est notre cas ici).

Maintenant on peut lancer la commande :

mvn clean integration-test -P webapp,clean-jetty -DskipTests=true

et vérifier (après quelques minutes) de la prise en compte de nos 2 AMPS !

C'est beau la technologie !

Les dépendances

Maintenant intéressons nous aux dépendances. Dans ce cas de figure je ne souhaite pas que mon application démarre si mon module n'a pas toutes les dépendances nécessaires. On aurait alors une application instable qui pourrait endommager des données !! (ce que je ne souhaite évidemment pas...).

Comment définir ces dépendances fortes entre mes modules ?

Reprenons l'exemple précédent. Suite à des modifications importantes de mon code, je souhaite créer une liaison forte entre mon projet et le projet SDK-TaggingSample. Pour cela il y a un mécanisme défini dans l'AMP et disponible via le fichier module.properties (situé à la racine de notre projet).
En fin de ce fichier, il suffit de rajouter la ligne ci-dessous pour créer une dépendance :

module.depends.org.alfresco.sample.SDK-TaggingSample=0.1-*

A noter le formalisme simple :
  • module.depends : pour définir une dépendance du module
  • . ou nom du module : pour identifier le module
  • X.X - Y.Y : Pour déterminer la porté du module à prendre en compte (entre X.X et Y.Y). Notre module dépend du SDK-TaggingSample à partir de la version 0.1. (A noter la possibilité de mettre le caractère * pour signifier n'importe lequel)
Pour de plus amples informations : wiki.alfresco.com

Vous pouvez maintenant démarrer l'application via la commande Maven :

mvn clean integration-test -P webapp -DskipTests=true

Comme vous pouvez le voir, rien à changer! C'est déjà ça. Mais ce que l'on aimerait là, c'est de vérifier que notre mécanisme anti-démarrage fonctionne bien. Pour cela vous avez deux choix.
Soit
  • Vous modifiez le numéro de version dans le fichier module.properties pour avoir par exemple : module.depends.org.alfresco.sample.SDK-TaggingSample=99.99-*
  • Vous supprimer la dépendance dans la partie dependencies du pom.xml.
Dans ces deux cas, relancer l'application et vous vous apercevrez dans la console d'une jolie stackTrace vous interdisant de démarrer l'application si la dépendance n'est pas respectée !


Et les projets Maven multi-modules ?

Maven permet de créer des projets multi-modules. Si vous ne connaissez pas l'idée qui se cache derrière, je ne serai vous conseillez de lire ceci. Sinon pour simplifier les choses, admettons que votre projet se décompose de 2 AMPS. Ces 2 AMPS possèdent une dépendance forte l'un envers l'autre. Ce que vous cherchez c'est un seul pom.xml vous permettant de construire (faire un build) des 2 projets en même temps. En d'autre termes, je lance une commande mvn clean install, cette commande va être exécuté sur les 2 projets ! On va encore plus loin dans l'héritage et dans les principes Maven ! Pour la pratique on verra cela un peu plus tard ^^

Voilà c'est fini pour aujourd'hui !

Mavenisez bien !

PS :

Les sources du projet alf-sdk sont disponibles ici : http://www.box.net/shared/exremqsr0m


Les sources du projet alf-amp-osecm sont disponibles ici : http://www.box.net/shared/dzige0nchr

Lire la suite...

Maven + Alfresco : SDK Samples



Bienvenue !

Dans la série découverte de Maven par la pratique, je vous propose aujourd'hui un exercice assez simple.
Vous devez passer les exemples (samples) du SDK Alfresco en projet AMP !

A quoi cela sert il me direz vous ? Pas à grand chose si ce n'est de faire des exercices et de voir les avantages et les limites de cette approche. Cela parmet aussi de comprendre les différents mécanismes Maven pour builder, tester et intégrer les projets Samples.

Pour information, vous pouvez retrouver les informations sur le SDK à cette adresse : http://wiki.alfresco.com/wiki/Alfresco_SDK_3.3

Actuellement, j'ai réussi la migration des samples suivants :
  • SDK Custom Dialog
  • SDK Custom JSP
  • SDK Custom Login
  • SDK Custom Wizard
  • SDK Tagging Sample
Chacun des samples héritent du projet alf-sdk permettant ainsi :
  • Lancer les tests unitaires : mvn clean test
  • Installer le projet dans le repository local : mvn install
  • (Ré)Initier la base de données/: mvn clean -P clean-jetty
  • Relancer l'application : mvn integration-test -P webapp
Si vous avez suivi les précédents posts, vous devriez être capable de faire la même chose. Sinon n'hésitez pas à voir les sources de chacun des projets que j'ai réalisé.

A très vite pour de nouvelles aventures !
Lire la suite...

Maven + Alfresco : Jetty, Boostrap et Profil



Bonjour à tous !

Cette fois ci je vais vous présenter comment on peut "bootstapper" (initialiser) des données lors de l'installation de notre AMP et comment on peut le tester facilement.

1. Bootstrap

Tout d'abord, il y a plusieurs façons de créer un bootstrap
  • soit par des fichiers XML,
  • soit programmatiquement (via une sorte de patch...).

L'avantage de la première approche est sa simplicité ! En effet, un bootstrap XML n'est rien d'autre que l'équivalent de l'import/export disponible dans Alfresco Explorer. Vous savez les flèches vertes sur un dossier dans l'écran des détails... Bref... pour simplifier on exporte des noeuds sous format XML pour ensuite les (ré)intégrer dans une autre instance Alfresco. L'exemple typique est le passage d'un serveur de Test (responsabilité équipe de développement) vers un serveur de production (responsabilité équipe d'exploitation). Sur le serveur de DEV, l'équipe de développement a créé une arborecence projet spécifique qui doit être installé sur le serveur de PROD automatiquement. Ceci doit être effectué lors de la première installation de notre AMP sur le serveur de PROD.

La limite de cette approche vient du fait que seule la création d'objet est possible. On ne peut supprimer ou transformer...

L'avantage de la seconde approche est sa richesse ! En effet, on a accès à l'ensemble des services Alfresco plus (éventuellement) les services de notre projet. On peut donc effectuer tout ce que l'on veut.. On peut réorganiser une arborescence, effectuer une modification massive d'un ensemble d'objet ou encore transformer des contenus...

L'inconvénient : Il faut s'avoir coder :o/ et connaître en partie les services Alfresco.

Je vais m'intéresser par la suite à la première approche. Je m'intéresserai à la deuxième approche dans un prochain post..

1.1 Boostrap via XML
Donc en premier, je vais vous expliquer l'approche par un fichier XML.
Dans notre exemple de bootstrap, je veux créer 4 espaces : un espace BASE DOCUMENTAIRE + 3 sous-espaces PROJET 1, PROJET 2 et PROJET 3. Ces espaces ont été créés précédemment avec une instance d'Alfresco de TEST préalablement installé. Maintenant je veux le mettre en place sur mon projet et donc dans mon AMP pour que chaque instance installant cet AMP puisse aussi avoir ces répertoires.

1.2 Export
Tout d'abord j'exporte les répertoires de mon instance de TEST (via l'action export), puis je télécharge le fichier ACP généré en local afin d'extraire le fichier XML.
Mon fichier XML a pour nom spaces.xml (orginal...). Pour plus d'informations sur l'IMPORT/EXPORT : http://wiki.alfresco.com/wiki/Export_and_Import

1.3 Intégration dans le projet
Je vais ensuite déposer ce fichier dans le nouveau répertoire /alf-amp-osecm/src/main/config/bootstrap. Actuellement, ce fichier est orphelin et ne sera pas pris en compte. Il faut donc définir sa prise en compte par Alfresco (et donc par Spring...).
Pour cela, on va créer un nouveau fichier qui a pour nom boostrap-context.xml dans le répertoire /alf-amp-osecm/src/main/config/context



parent="module.baseComponent">












/${spaces.company_home.childname}
alfresco/module/fr.opensourceecm.alf-amp-osecm/bootstrap/spaces.xml






Pour résumer comment comprendre ce fichier ?
Litterallement, voilà ce qu'il veut dire :
On crée un bean Spring identifié par osecm.bootstrapSpaces héritant du bean module.baseComponent. Ce bean sert à Importer. Il s'applique pour le module fr.opensourceecm.alf-amp-osecm (notre AMP), à partir de la version 0.0.4. Le traitement du bean (donc de l'import) ne s'effectue qu'une seule fois (donc au premier démarrage du module). Il prend pour paramètre un "bootstrapViews" lié à notre fichier. Ce bootstrapView va nous permettre de créer notre arboresence en tant que sous-espace de {spaces.company_home.childname}.

C'est simple non ? ;o)

1.4 Création du projet
Maintenant que nous avons notre bootstrap, il n'y a plus qu'à le tester ! On effectue donc un package de notre AMP via la commande


mvn clean install

On peut ainsi retrouver dans le répertoire target de notre projet, le fichier alf-amp-osecm-0.0.4.amp qui sera alors possible d'intégrer dans Alfresco.war.
Effectuez un copier/coller du fichier alf-amp-osecm-0.0.4.amp vers le répertoire amps du répertoire d'installation d'un Alfresco.
Lancez ensuite le script d'installation des amps dans le répertoire d'installation d'un Alfresco : apply_amps.bat
A la fin de celui ci, vous avez un nouveau alfresco.war mis à jour avec votre module.
Vous pouvez maintenant lancer Alfresco et vérifier l'intégration du module !


2. Lancer et Tester Alfresco via Maven


Si vous avez suivi l'ensemble de mes posts sur l'intégration Alfresco/Maven, vous vous êtes rendu compte que cela pouvait prendre beaucoup de temps d'intégrer un AMP dans Alfresco... Copier/coller c'est bien mais c'est un peu rébarbatif à la longue...
L'idée pour améliorer ce processus serait de lancer une commande Maven pour démarrer un Alfresco...

Comment ?
Et bien via l'utilisation de nouveaux plugins : jetty et maven-war!

Jetty est un container HTTP leger (un peu du même style que Tomcat...) qui va nous permettre de lancer un Alfresco via Maven tandis que le plugin maven-war va nous permettre de créer le war de test de notre application.

Pour faire simplement, on désire créer un alfresco.war "déployé/explosé" dans un sous-répertoire de target (via le plugin maven-war) et qui sera ensuite lancé comme une application web (via le serveur Jetty).

Attention on y va !

2.1 Profil

En fait la majorité du travail de configuration s'effectue au niveau du pom.xml de notre projet AMP. On va créer ce que l'on appelle un PROFIL.
Un profil maven est un ensemble d'action rendu optionnel ou non par l'utilisateur lors de l'execution d'une commande Maven. On peut le voir comme une instruction conditionnelle commandée par l'utilisateur. Dans le cas présent, on cherche à démarrer un Alfresco afin de vérifier que le boostrap a fonctionné. On cherche aussi de manière générale à vérifier le fonctionnement de notre AMP.

Néanmoins, avant de créer notre profil, nous avons besoin de créer quelques fichiers de propriétés.


2.2 Le fichier jetty-env.xml
Avant toute chose, on définit le fichier jetty-env.xml. Il permet de configurer la connexion à la base de données via Jetty. Pour cela, on va créer un nouveau fichier jetty-env.xml dans le répertoire /alf-amp-osecm/src/test/properties/local/





jdbc/dataSource


jdbc:mysql://localhost/${alfresco.db.name}
${alfresco.db.username}
${alfresco.db.password}





2.3 Le fichier application.properties
Qui dit nouvel environnement dit forcément nouvelle configuration de l'entrepôt de données. Nous allons créer pour cela un nouveau fichier application.properties que nous allons ajouter dans le répertoire : /alf-amp-osecm/src/test/properties/local
Cet ensemble de clé/valeur va être ensuite utilisé dans le pom.xml en tant que référence ainsi que dans le fichier dev.properties


webapp.name=alfresco-jetty
alfresco.data.jetty=alf_data_jetty
alfresco.data.location=./alf_data_jetty
alfresco.db.driver=org.gjt.mm.mysql.Driver
alfresco.hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
alfresco.db.url=localhost
alfresco.db.name=alfjetty
alfresco.db.username=alfresco33
alfresco.db.password=alfresco
webapp.log.level=error
webapp.log.dir=
module.log.level=debug

2.4 Le fichier dev.properties
Ici nous allons créer un fichier dev.properties que nous allons ajouter dans le répertoire : /alf-amp-osecm/src/test/properties/local Ce fichier va faire le lien entre les variables définies dans application.properties et la configuration alfresco défini dans le fichier dev-context.xml. Lors de la création de notre war, ce fichier va venir écraser le fichier dev.properties précédemment défini.


dir.root=${alfresco.data.location}
index.recovery.mode=AUTO
integrity.failOnError=true
db.test.name=${alfresco.db.name}
db.username=${alfresco.db.username}
db.password=${alfresco.db.password}
db.host=${alfresco.db.host}
db.port=${alfresco.db.port}
db.driver=${alfresco.db.driver}
db.url=jdbc:mysql://${db.test.host}:${db.test.port}/${db.test.name}
hibernate.dialect=${alfresco.hibernate.dialect}

2.5 Les propriétés
Maintenant nous pouvons attaquer la configuration de notre pom.xml. Tout d'abord nous allons déclarer une propriété : env Cette propriété est définie après le bloc de déclaration du projet et avant le bloc de déclaration des dépendances.



local
alfresco-jetty


2.6 Création du profil
Comme le titre l'indique, nous allons maintenant créer un bloc profil que l'on va appeller webapp. Son goal par défaut sera jetty:run-exploded (autrement dit lancement de l'application war déployé/explosé que l'on aura créé). Ce bloc est à ajouter en fin de notre pom.xml mais avant la balise fermante project.




webapp


src/test/properties/${env}/application.properties

jetty:run-exploded


... CF. POINTS SUIVANTS...





true
src/test/resources

alfresco/desktop/*.*



true
src/test/properties/${env}
alfresco/extension

dev.properties






org.alfresco.sdk
alfresco-community-war
3.3
war





A noter plusieurs points :
Tout d'abord on a ajouté un FILTRE via la fichier application.properties. Il va nous permettre d'utiliser l'ensemble des variables définies dans ce fichier dans le reste du pom.xml et plus précisément dans notre profil.

On a ajouté ensuite en tant que dépendance alfresco-community-war c'est à dire l'application Alfresco Explorer. Bien entendu, on l'aura préalablement ajouté à notre repository Maven local via la commande

call mvn install:install-file -Dfile=alfresco.war -DgroupId=org.alfresco.sdk -DartifactId=alfresco-community-war -Dversion=3.3 -Dpackaging=war


Après on a ajouté des testResource qui vont nous permettre
  • de ne pas prendre en compte les desktops actions présents dans l'AMP (Pour rappel ils sont simplement nécessaires pour les tests unitaires dans Eclipse)
  • de prendre en compte les paramètres de l'entrepôt de donnée spécifique à Jetty via le fichier dev.properties.


2.7 Configurer plugin maven-war
Le plugin maven-war va nous permettre de déployer le war alfresco et d'ajouter nos fichiers de configuration.



org.apache.maven.plugins
maven-war-plugin
2.0.2


it
package

exploded


true




false
${project.build.directory}/${webapp.name}

false

licenses/**


${project.build.testOutputDirectory}
WEB-INF/classes
true

**



src/test/properties/${env}
WEB-INF
true

jetty*






On note dans les ressources que l'on veut
  • Ajouter l'ensemble des fichiers de configuration de src/test/resource/alfresco/* (équivalent à ${project.build.testOutputDirectory})
  • Ajouter le fichier jetty-env.xml pour la prise en compte du paramètre JNDI de la base de données.


2.8 Configurer plugin jetty

Le plugin maven-jetty va nous permettre de lancer l'application alfresco et prendre en compte les sources de notre projet.



org.mortbay.jetty
maven-jetty-plugin
6.1.22


it
integration-test

run-exploded


/${webapp.name}
${project.build.directory}/${webapp.name}
10


8080
60000







mysql
mysql-connector-java
5.0.3
provided




On notera en dépendance le driver mysql.

2.9 Lancer l'application

Maintenant vous êtes fin prêt à lancer Alfresco via une commande Maven


mvn clean integration-test -P webapp


Pour information, on utilise un profil en ajoutant à la commande le paramètre -P suivi du nom du profil à prendre en compte. Si vous ne voulez pas jouer les tests, ajouter à la fin le paramètre -DskipTests=true.

Quelques minutes plus tard si tout se passe bien, vous pouvez ouvrir un navigateur internet et tapez l'adresse http://localhost:8080/alfresco-jetty/
Vous vous apercevez alors de la présence d'une arborescence BASE DOCUMENTAIRE!

Well Done !

3. Extras

Généralement, un test de bootstrap ne fonctionne pas du premier coup ! Or qui dit bootstrap dit forcément installation unique au premier démarrage. Si on veut retenter une nouvelle fois, il serait donc utile de remettre à zéro notre application.

Comme vous êtes familier avec les profils et la configuration de plugin, je vous propose en petit extra le profil clean-jetty qui vous permettra de mettre à zero le contexte jetty.
A vous de le placer judicieusement dans le fichier pom.xml et de l'améliorer!



clean-jetty



maven-clean-plugin
2.4

true


target

war/**


**



alf_data_jetty

oouser/**






org.codehaus.mojo
sql-maven-plugin
1.4



mysql
mysql-connector-java
5.0.3



org.gjt.mm.mysql.Driver
jdbc:mysql://localhost/
root
admin
true



drop-db-jetty
pre-clean

execute


true
drop database IF EXISTS alfjetty



create-db-jetty
clean

execute


true
create database alfjetty default character set utf8 collate utf8_bin









Rendez vous pour le prochain épisode qui sera consacré à la gestion des versions des AMPS + Patchs Java !

A++

PS : L'ensemble des sources du projet sont téléchargeables à cette adresse : http://www.box.net/shared/bpcx8kl7dn
Lire la suite...

Maven + Alfresco : Test Unitaires



Bonjour tout le monde!

Cette fois ci il je vais essayer de vous faire partager mon approche des tests unitaires avec Maven lors de la création d'un AMP.
Bien entendu qui dit TEST, dit CODE! Donc à vos claviers!

Objectif :

En tant que développeur et intégrateur mon objectif est double :
  • Tout d'abord je veux pouvoir lancer les tests unitaires Alfresco dans Eclipse. Je tiens à conserver mon debugger :o) pour suivre la création de mon code.
  • Ensuite je veux pouvoir lancer l'ensemble de mes tests unitaires via Maven. Ainsi lorsque je voudrais créer une version de mon AMP, il devra passer obligatoirement les tests! Il s'agit d'un gage de qualité évident.
Donc comment faire ?
Si vous avez suivi mes 2 précédents posts ici et ici, nous avons en notre possession deux AMP (enfin... 2 projets MAVEN pour être précis...).
  • En premier, alf-sdk. Il s'agit d'une sorte de PARENT-AMP qui contient l'ensemble des dépendances du SDK Alfresco ainsi que l'ensemble des plugins pour créer un AMP.
  • En second, alf-amp-osecm. Il s'agit de l'AMP que l'on est entrain de créer et de faire évoluer. Il a pour parent le alf-sdk.

Nous allons modifier ces 2 projets pour mettre en place des tests unitaires.

1. Mettre à jour ALF-SDK

Tout d'abord on va mettre un peu à jour le pom parent. Les principales modifications ont lieu au niveau des balises build.
  • maven-compiler-plugin et maven-resources-plugin. Ils ont reçu des paramètres pour l'encoding.
  • maven-eclipse-plugin a été installé. Nous allons voir dans le prochain point pourquoi...




4.0.0
fr.opensourceecm
alf-sdk
pom
3.3C
Maven - Alfresco SDK 3.3C
Super POM Maven Alfresco SDK 3.3C



....





true
src/main/resources

**README-*



true
src/main/config
alfresco/module/${groupId}.${artifactId}

**README-*







org.apache.maven.plugins
maven-eclipse-plugin
2.8


org.springframework.ide.eclipse.core.springnature


org.springframework.ide.eclipse.core.springbuilder






org.apache.maven.plugins
maven-resources-plugin
2.2

UTF-8





org.apache.maven.plugins
maven-compiler-plugin

1.6
1.6
UTF-8
true





org.alfresco.maven.plugin
maven-amp-plugin
3.0.2
true


false

alfresco/extension/**,alfresco/module/**










Une fois modifié, vous pouvez installer et déployer cet artefact en local avec une simple commande maven

mvn clean install

Dans notre repository, nous avons désormais accès au module fr.opensourceecm:alf-sdk:pom:3.3C
Les projets héritant de cet artefact obtiendront automatiquement les mises à jour.

2. Mettre à jour notre projet AMP

Maintenant nous allons ajouter une action Alfresco + une classe de test pour la tester.
Pour rappel, une action est une unité de travail sur l'entrepôt de données. Il peut être exécuté via une règle ou directement par l'utilisateur via l'interface.
  • Dans notre cas, l'action effectue simplement la création d'un sous-espace par rapport à l'espace qui lance une action.
  • La classe de test va démarrer un contexte Alfresco (création d'un store), créer un espace, lancer une action sur cet espace et vérifier la création d'un sous-espace.

2.1 Ajout d'une action Alfresco
Dans le répertoire /alf-amp-osecm/src/main/java/fr/opensourceecm/alf/amp/osecm/actions/, j'ajoute l'action : sampleActionExecuter.java


package fr.opensourceecm.alf.amp.osecm.actions;

import java.util.List;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;

public class sampleActionExecuter extends ActionExecuterAbstractBase{

private FileFolderService fileFolderService;

private final String FOLDER_TEST_NAME = "FolderTest";

@Override
protected void executeImpl(Action arg0, NodeRef actionUponRef) {
List listNodeRef = fileFolderService.listFolders(actionUponRef);
fileFolderService.create(actionUponRef, FOLDER_TEST_NAME + "_" + listNodeRef.size(), ContentModel.TYPE_FOLDER);
}

@Override
protected void addParameterDefinitions(List arg0) {
// TODO Auto-generated method stub

}

public void setFileFolderService(FileFolderService fileFolderService) {
this.fileFolderService = fileFolderService;
}
}



A noter que pour créer notre sous-espace, on se sert du FileFolderService et que le nom de notre espace sera la concatenation de : FolderTest et du nombre de dossiers présents.

2.2 Ajout d'un test unitaire
Dans le répertoire /alf-amp-osecm/src/test/java/fr/opensourceecm/alf/amp/osecm/actions, j'ajoute le test : sampleActionExecuterTest.java


package fr.opensourceecm.alf.amp.osecm.actions;

import junit.framework.Assert;

import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.BaseAlfrescoTestCase;
import org.junit.Test;

public class sampleActionExecuterTest extends BaseAlfrescoTestCase {

protected NodeRef companyHomeRef;
protected NodeRef rootFolderTestRef;
protected final String rootFolderTestName = "ROOTFOLDERTEST";

@Test
public void testIntegrerFluxCreationParAction() throws Throwable {

// Création d'un répertoire de test dans le store de test.
rootFolderTestRef = serviceRegistry.getNodeService().createNode(
rootNodeRef, ContentModel.ASSOC_CHILDREN,
ContentModel.TYPE_FOLDER, ContentModel.TYPE_FOLDER).getChildRef();

//Lancement de l'action de création d'un sous-répertoire.
Action action = serviceRegistry.getActionService().createAction("createFolderTest-action");
serviceRegistry.getActionService().executeAction(action,rootFolderTestRef);

//Vérification de la présence du sous-répertoire.
Assert.assertEquals("ERREUR LORS DE LA RECHERCHE", 1, serviceRegistry.getNodeService().getChildAssocs(rootFolderTestRef).size());
}
}


Ici j'attire votre attention sur le fait que cette classe de test étend la classe BaseAlfrescoTestCase. C'est dans cette classe que le contexte Alfresco est démarré et que le store de test est créé. Dans ma classe, je me contente de créer un espace de test afin de lancer mon action et de vérifier le résultat.

2.3 Configuration du pom.xml

Notre POM.XML va bien entendu évolué suite à l'intégration de ce code java. En effet, Maven a besoin de savoir les dépendances nécessaires pour compiler ces classes. Il s'agit
  • alfresco-repository-3.3 pour l'appel aux services Alfresco
  • org.springframework.beans-3.0.0 pour l'appel du context Spring
  • junit pour le test unitaire.

Notre pom.xml devient alors :




fr.opensourceecm
alf-sdk
3.3C

4.0.0
alf-amp-osecm
jar
0.0.3
Alfresco AMP Open Source ECM
Open Source ECM - Extension



org.alfresco.sdk
alfresco-repository-3.3
3.3
community
provided


org.alfresco.sdk
org.springframework.beans-3.0.0
3.3
community
provided


junit
junit
4.7
test





REMARQUE IMPORTANTE : Le packaging est JAR ! Il ne faut pas le mettre en AMP (c'est un petit "trick" à faire pour configurer le projet dans Eclipse...)

2.4 Configuration du workspace eclipse
Généralement (et si vous avez bien suivi les instructions précédentes) vous n'avez encore jamais ouvert Eclipse pour faire les manipulations précédentes ! Je reconnais... c'est difficile. ;o) Mais il faut savoir qu'un projet Maven généré n'est pas intégrable directement dans Eclipse!En effet ce n'est pas prévu pour ! Il n'existe pas de fichier .classpath ou .project et ni de répertoire .settings qui permettent de configurer votre projet dans Eclipse.
Néanmoins Maven possède un plugin pour créer automatiquement l'ensemble de ces fichiers de configuration. Il s'agit du maven-eclipse-plugin défini précédemment dans le pom parent.

Pour créer cette configuration, tapez une commande dans le répertoire racine du projet maven créé.

mvn eclipse:eclipse


Automatiquement, les fichiers maven-eclipse.xml, .project et .classpath ont été créé ainsi que les répertoires .settings et .externalToolBuilders (et éventuellemnt target).

Remarque : A noter pour les utilisateurs de Spring IDE que le projet va posséder la nature de projet Spring par défaut.


Remarque : Si vous avez déjà intégré le projet dans eclipse ou si vous voulez supprimer la configuration eclipse, tapez la commande suivante :

mvn eclipse:clean


2.5 Import du projet dans eclipse
Vous pouvez maintenant lancer un eclipse (3.5R2 Galilleo pour ma part) et importer le projet dans votre Workspace.
Le projet ressemble alors à l'image ci-dessous :




Remarque : Si vous n'avez pas cette configuration, vérifiez bien que vous avez lancé la commande eclipse alors que le packaging du pom est à JAR. En effet, si on lance la commande eclipse alors qu'il s'agit d'un AMP, le plugin va construire une autre arborescence qui n'est pas celle que l'on attend pour développer.


2.6 (Re)Définition des beans spring
On va maintenant modifier la déclaration des beans spring pour chaque partie de notre AMP afin d'améliorer la lisibilité du code. Pour cela nous allons spécialiser un répertoire. Il s'agira du répertoire context.

Donc dans le répertoire \alf-amp-osecm\src\main\config, créez un répertoire context puis créez 3 fichiers :

actions-context.xml













model-context.xml








alfresco/module/fr.opensourceecm.alf-amp-osecm/model/ecmModele.xml






Cette déclaration comme son nom l'indique va nous permettre de définir le modèle de données. A noter que dans mon précédent post, j'avais remplacé fr.opensourceecm.alf-amp-osecm par {groupID} et {artifactId}. Or ici, je souhaite qu'Eclipse soit capable de le comprendre lors d'une compilation. En effet Maven est le seul capable de remplacer ces valeurs! Donc on doit le mettre en dur... A noter cependant que le groupId et l'artifactId doivent être généralement définis dès le début de la construction de votre AMP.
REMARQUES
Je profite du refactoring pour simplifier le nom du fichier de configuration de mon modèle de données.

Maintenant, on va créer le fichier
webclient-context.xml






alfresco/module/fr.opensourceecm.alf-amp-osecm/ui/ecm-web-client-config.xml





Cette déclaration comme son nom l'indique va nous permettre de définir la configuration du client web.
REMARQUES
Je profite du refactoring pour simplifier le nom du fichier configuration du client web


Dans le répertoire \alf-amp-osecm\src\main\config, modifiez le fichier :
module-context.xml








Ce fichier va nous servir à référencer l'ensemble des déclarations Spring nécessaire à notre module. Dans notre cas pour récapituler, notre module comporte : un modèle de données, une action et une configuration du client web.

2.7 Définition de notre environnement de test
Maintenant nous allons définir et configurer l'entrepôt de données de test (c'est à dire on va définir où vont être stocker le content-store et le lucene-indexes ainsi que les paramètres de configuration de la base de données).

Pour cela dans le répertoire /alf-amp-osecm/src/test/resources/alfresco/extension/ (créez les répertoires manquants si nécessaire) créez le fichier

dev.properties

dir.root=./alf_data
index.recovery.mode=AUTO
integrity.failOnError=true
db.name=alf33Test
db.username=alfresco33
db.password=alfresco
db.host=localhost
db.port=3306
db.driver=org.gjt.mm.mysql.Driver
db.url=jdbc:mysql://${db.host}:${db.port}/${db.name}
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect

Ce fichier permet de définir l'ensemble des propriétés de notre environnement de test. Dans mon cas, j'ai installé et configuré une base de données MySQL.
Pour plus d'informations sur comment configurer un environnement, n'hésitez pas à télécharger le pdf suivant : Manuel de configuration et Installation d'Alfresco 3.3

Ensuite dans le même répertoire, vous devez créer le fichier
dev-context.xml






classpath:alfresco/repository.properties
classpath:alfresco/domain/transaction.properties


classpath*:alfresco/module/*/alfresco-global.properties

classpath*:alfresco-global.properties
classpath:alfresco/extension/dev.properties



SYSTEM_PROPERTIES_MODE_OVERRIDE




hibernate.dialect
hibernate.query.substitutions
hibernate.jdbc.use_get_generated_keys
hibernate.default_schema





Ce bean va nous permettre de prendre en compte le fichier de propriétés précédemment créé. Il s'agit d'un bean Spring qui vient écraser la précédente déclaration faite dans Alfresco uniquement pour notre phase de test.

REMARQUES
Dans cette étape, vous pouvez rajouter un répertoire /alf-amp-osecm/src/test/resources/alfresco/desktop qui contiendra les desktop ations Alfresco par défaut (disponible dans le sdk). Apparemment il n'arrive pas à les avoir dans mon environnement...
Dans cette étape, vous pouvez aussi rajouter un fichier log4j.properties dans le répertoire /alf-amp-osecm/src/test/resources pour déterminer les niveaux de logs.

2.8 Modifier le pom.xml
Nous avons maintenant un environnement prêt à être testé et packagé sous format AMP.
Il faut donc modifier dans le pom.xml de notre projet, la valeur du packaging à amp.

2.9 Lancer le packaging

Maintenant votre projet doit ressembler à l'image ci dessous :




Le projet est maintenant complet, vous pouvez lancer le packaging via la commande

mvn clean package


Si tout se passe bien, vous voyez apparaitre le fameux et tant convoité BUILD SUCCESSFULL et si vous faîte attention à la console, vous avez l'affichage du résultat des tests du style
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

Si c'est le cas vous avez votre premier AMP testé par Maven.

FELICITATION !

Ainsi, dans le répertoire target du projet, vous avez votre AMP packagé : alf-amp_osecm.0.0.3.amp que vous pouvez installer sur votre instance Alfresco.


2.10 Lancer le test via Eclipse
Comme je le disais au tout début, j'ai aussi envie de pouvoir utiliser Eclipse pour pouvoir débugguer mon application si nécessaire. Je lance donc via Junit mon test et vérifie le résultat.


Objectifs atteints !


C'est fini pour aujourd'hui ! C'est déjà pas mal je pense...
Si vous avez des questions, une remarque ou un bug/une amélioration à signaler par exemple, n'hésitez pas à poster un commentaire.


Pour cette partie, je tiens à remercier G.Tournier pour son aide et ses conseils.
Sans lui les noeuds Alfresco seraient sans doute encore un grand mystère pour moi.

A la prochaine !

PS :

L'ensemble des sources du projet alf-amp-osecm sont téléchargeables à cette adresse : http://www.box.net/shared/374lms3ogv

L'ensemble des sources du projet alf-sdk sont téléchargeables à cette adresse : http://www.box.net/shared/oevx14hy8n
Lire la suite...

Maven + Alfresco : SDK, dépendances et héritage


Hello,

Cette fois ci, je vais discuter de l'intégration du SDK et des dépendances dans la création d'un AMP.

Pour petit rappel, une dépendance est généralement une bibliothèque de classes packagée sous forme de jar. Si un programme informatique se sert d'une dépendance il doit au moment de son execution savoir où trouver ce jar pour pouvoir l'utiliser.

Dans le cas d'Alfresco, le SDK regroupe l'ensemble de dépendances nécessaires pour pouvoir utiliser et lancer une application Alfresco.

Pour gérer ses dépendances, il n'existe pas qu'un seul mode mais plutôt deux.

En mode classique,

Il faut d'abord télécharger le SDK Alfresco et le dezipper dans un répertoire.

Ensuite dans Eclipse, on doit effectuer l'opération "Importer un projet existant" (généralement le projet SDK AlfrescoEmbedded) dans le répertoire ALF_SDK_HOME\lib

Dans le projet AMP via Eclipse, on configure le Java Build Path c'est à dire lorsque l'on se retrouve dans l'interface de configuration, dans l'onglet Project, on doit ajouter le projet précédemment importé.

Une fois toutes ces étapes passées, on peut utiliser le SDK dans Eclipse. Les liens et dépendances sont alors disponibles pour l'auto complétion et la compilation des sources par Eclipse...

En mode Maven

Dans ce mode là, il faut que l'ensemble du projet SDK AlfrescoEmbedded soit intégré dans un repository Maven 2 (celui de son poste de travail, celui de l'entreprise ou un repository distant).

Pour information, Alfresco possède maintenant son propre repository à l'adresse suivante : Alfresco Nexus/Maven Néanmoins, à l'heure de création de ce billet, il ne possède pas l'ensemble des artefacts du SDK.

Donc pour pouvoir résoudre les dépendances, il faut définir et identifier dans le pom.xml de notre projet d'AMP l'ensemble des dépendances (groupID, ArtifactID, version, classifier).

Lorsque le pom.xml est complet et exhaustif, il devient possible de compiler et tester l'application via Maven.

Et la configuration Eclipse dans tout cela ?? Et bien il est aussi possible via une commande eclipse:eclipse de régénérer la configuration Eclipse.... Mais cela sera pour plus tard si vous le voulez bien...

En tout cas c'est cette deuxième méthode que je vais essayer de vous présenter.


Procédure pour mettre en place le SDK dans un repository Maven 2 et l'utiliser pour construire un AMP

Remarque et avertissement :
Attention cette procédure est loin (très loin même...) d'être la plus propre ou la plus esthétique. Elle ne respecte pas forcément très bien les principes de base de Maven. Il faut donc l'utiliser avec précaution !


1. Intégrer le SDK d'Alfresco en local


Comment répertorier les dépendances ?
Via un petit projet écrit en java et compilé grâce à Maven (quand on veut faire du Maven autant le faire partout...).

Le principe ?
Lister l'ensemble des jar présents dans le projet SDK et les intégrer dans notre repository via un script (.bat ou .sh)

Le code ?


package fr.opensourceecm;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class AlfrescoMavenSDKCreator {

public static String isWindows = "O";

public static String pathToSDK = "D:\\opt\\JM-Alfresco\\SDK\\3.3C\\lib\\server";
public static String sdkGroupId = "org.alfresco.sdk";
public static String sdkVersion = "3.3";
public static String sdkClassifier = "community";
public static String mavenLocation = "call mvn";

private static final String ln = System.getProperty("line.separator");

private static void execute() {

String nomFichier = null;

FileWriter fout1 = null;
FileWriter fout2 = null;
try {

showVariables();

System.out.println("Voulez-vous modifier ces paramètres (O/N) ? ");
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
String reponse = in.readLine();
if (reponse.toUpperCase().equals("O")) {
System.out.println("Windows (O/N) ? ");
isWindows = in.readLine();
System.out.println("PATH SDK ? ");
pathToSDK = in.readLine();
System.out.println("Version d'Alfresco ? ");
sdkVersion = in.readLine();
System.out.println("GroupID ? ");
sdkGroupId = in.readLine();
System.out.println("emplacement de Maven (binaire) ? ");
mavenLocation = in.readLine();
System.out.println("classifier (labs/enterprise) ? ");
sdkClassifier = in.readLine();
}

if (isWindows.toUpperCase().equals("O")) {
nomFichier = "maven-sdk-install-files.bat";
} else {
nomFichier = "maven-sdk-install-files.sh";
}

File file1 = new File("maven-dependencies.txt");
fout1 = new FileWriter(file1, false);
BufferedWriter out1 = new BufferedWriter(fout1);

File file2 = new File(nomFichier);
fout2 = new FileWriter(file2, false);
BufferedWriter out2 = new BufferedWriter(fout2);

if (isWindows.toUpperCase().equals("O")) {
out2.write("cd " + pathToSDK + ln);
out2.write(ln);
} else {
out2.write("#!/bin/bash" + ln);
out2.write(". /etc/profile" + ln);
out2.write(ln);
out2.write("cd " + pathToSDK + ln);
out2.write(ln);
}

ArrayList listingFiles = getFiles(pathToSDK);

for (File file : listingFiles) {

String librairieNameJar = file.getName();
String librairieName = librairieNameJar.substring(0,
librairieNameJar.length() - 4); // moins ".jar"

out1.write("" + ln);
out1.write(" " + sdkGroupId + "" + ln);
out1.write(" " + librairieName + "" + ln);
out1.write(" " + sdkVersion + "" + ln);
out1.write(" " + sdkClassifier + "" + ln);
out1.write(" test" + ln);
out1.write("
" + ln);

out2.write(mavenLocation + " install:install-file" +
" -Dfile=" + file.getPath().substring(pathToSDK.length() + 1) +
" -DgroupId=" + sdkGroupId +
" -DartifactId=" + librairieName +
" -Dversion=" + sdkVersion +
" -Dpackaging=jar" +
" -Dclassifier=" + sdkClassifier +
" -DgeneratePom=true" +
" -DcreateChecksum=true" + ln) ;

out1.flush();
out2.flush();
}
fout1.close();
fout2.close();

System.out.println("Les fichiers ont été générés : ");
System.out.println(file1.getAbsolutePath());
System.out.println(file2.getAbsolutePath());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

private static void showVariables() {
System.out.println("This utils is going to generate two files");
System.out.println("");
System.out.println("Le programme va s'ex�cuter avec les paramtres suivants :");
System.out.println("- pathSDK : " + pathToSDK);
System.out.println("- Windows : " + System.getProperty("os.name"));
System.out.println("- GroupID Alfresco : " + sdkGroupId);
System.out.println("- version d'Alfresco : " + sdkVersion);
System.out.println("- classifier : " + sdkClassifier);
System.out.println("- emplacement de Maven (binaire) : " + mavenLocation);
}

private static ArrayList getFiles(String root) {
ArrayList listeFichiersJar = new ArrayList();
getFilesRec(listeFichiersJar, root);
return listeFichiersJar;
}

private static void getFilesRec(ArrayList listeFichiersJar, String root) {
File f = new File(root);
File[] listFiles = f.listFiles();
for (int i = 0; i < listFiles.length; i++) {
if (listFiles[i].isDirectory()) {
getFilesRec(listeFichiersJar, listFiles[i].toString());
} else if (listFiles[i].getName().endsWith(".jar")) {
listeFichiersJar.add(listFiles[i]);
}
}
}

public static void main(String[] args) {
(new AlfrescoMavenSDKCreator()).execute();
}
}


L'exécution de ce petit programme en ligne de commande ou via l'interface Eclipse créé deux fichiers.

Le premier fichier (un fichier .bat) permet d'installer les dépendances dans le repository.
Ce fichier lance un ensemble d'appel maven du type :
call mvn install:install-file -Dfile=alfresco-core-3.3.jar -DgroupId=org.alfresco.sdk -DartifactId=alfresco-core-3.3 -Dversion=3.3 -Dclassifier=community -Dpackaging=jar
Comme vous pouvez le voir sur cet exemple, il y a comme qui dirait un petit souci de numéro de version ! En effet, cette commande va créer un fichier avec le nom : alfresco-core-3.3-3.3-community.jar Peu mieux faire n'est il pas... C'est pour cela que je considère que c'est pas très beau... Je me suis posé un TODO pour essayer de résoudre ce problème (ou bien attendre qu'Alfresco créé un pom.xml avec l'ensemble des dépendances ;o) ).

Le second fichier permet de créer l'ensemble des déclarations des dépendances trouvées. Elles sont ensuite facilement intégrables dans un fichier pom.xml
Ce fichier regroupe l'ensemble des déclarations du type :


org.alfresco.sdk
alfresco-core-3.3
3.3
community
test

Toutes les dépendances ont un scope TEST. En effet Alfresco possède déjà l'ensemble de ses bibliothèques. Il n'est donc pas nécessaire de les ajouter lors de la création de notre AMP. Par contre on en aura besoin pour tester le module.

Maintenant comment utiliser ses dépendances ?
Un point fort de Maven est sa capacité d'héritage entre artifact(plugin). Ainsi un artifact peut dépendre d'un autre par héritage comme c'est un peu le cas pour les classes Java.

Dans cette optique, l'une des idées est de considérer le SDK Alfresco comme étant le père de notre projet d'AMP. Ainsi toutes les dépendances du SDK seront aussi disponibles pour le projet fils. Si en plus on joue sur les scopes de chacune des dépendances alors on arrive à avoir un système assez précis.

2. Création du projet Super Pom Alfresco SDK

1. Création d'un projet Maven 2
Via une ligne de commande :

mvn archetype:create -DgroupId=fr.opensourceecm -DartifactId=alf-sdk -Dpackagename=fr.opensourceecm.alf.sdk

je crée l'ensemble de l'arborescence d'un projet Maven 2 de type jar.

2. Nettoyage
Je supprime les sous-répertoires des répertoires src/main/java et src/test/java afin de supprimer les classes par défaut générées.

3. Modification du pom
Maintenant je reprends les valeurs du fichier maven-dependencies.txt et je les ajoute entre les balises depedencies.
Je modifie le pom.xml pour créer l'artifact : fr.opensourceecm:alf-sdk:pom:3.3C.
Sachant que ce projet va devenir un projet parent, celui ci doit automatiquement être de package pom.
Finalement je rajoute la configuration des plugins pour l'étape de build.
On obtient ainsi un fichier du type :



4.0.0
fr.opensourceecm
alf-sdk
pom
3.3C
Maven - Alfresco SDK 3.3C
Super POM Maven Alfresco SDK 3.3C




alfresco-public-snapshots
http://maven.alfresco.com/nexus/content/groups/public-snapshots

true
daily



alfresco-public
http://maven.alfresco.com/nexus/content/groups/public




alfresco-public
http://maven.alfresco.com/nexus/content/groups/public


alfresco-public-snapshots
http://repository.sourcesense.com/nexus/content/groups/public-snapshots

true
daily






org.alfresco.sdk
alfresco-core-3.3
3.3
community
test


org.alfresco.sdk
alfresco-deployment-3.3
3.3
community
test

...

org.alfresco.sdk
mysql-connector-java-5.1.7-bin
3.3
community
test


org.alfresco.sdk
dom4j-1.6.1
3.3
community
test


org.alfresco.sdk
ehcache-core-2.0.0
3.3
community
test

...

org.alfresco.sdk
org.springframework.beans-3.0.0
3.3
community
test


org.alfresco.sdk
org.springframework.context-3.0.0
3.3
community
test

...





true
src/main/resources


true
src/main/config
alfresco/module/${groupId}.${artifactId}






org.apache.maven.plugins
maven-compiler-plugin
2.2

1.6
1.6




org.alfresco.maven.plugin
maven-amp-plugin
3.0.1-SNAPSHOT
true


false







4. Installation et déploiement du projet
Une simple commande maven suffit maintenant pour créer notre artefact;

mvn clean install

Dans notre repository, nous avons désormais accès au module fr.opensourceecm:alf-sdk:pom:3.3C

Remarque Importante !
Si vous utilisez la version 3.3C (comme moi ici), il manque un jar important dans les dépendances : config.jar. Cette référence contient l'ensemble des fichiers de configuration d'Alfresco. Il est donc important de l'avoir! Pour information dans le SDK de la version 3.3, il s'agit d'un répertoire et non d'un jar. Il faut donc créer un jar de ce répertoire pour ensuite le mettre en tant que dépendance dans notre pom.xml.



org.alfresco.sdk
alfresco-config
3.3
community
test




Mise à jour du projet AMP alf-amp-osecm

1. Modification du pom.xml
Maintenant, nous pouvons modifier le fichier pom.xml de notre fichier pour prendre en compte le parent. Il est à noter que l'on a ajouté le bloc parent en premier pour définir l'héritage.




fr.opensourceecm
alf-sdk
3.3C

4.0.0
alf-amp-osecm
amp
0.0.2
alf-amp-bdj
Open Source ECM - Extension

On s'aperçoit désormais que le pom devient beaucoup plus court. Les informations concernant les dépendances et les plugins à mettre à utiliser lors du build ont été hérités du projet SDK. C'est cela la magie de l'héritage!

2. Création de l'AMP
Maintenant nous avons tout pour créer notre module. Il n'y a plus qu'à lancer la commande :

mvn clean package

On peut ainsi retrouver dans le répertoire target de notre projet, le fichier alf-amp-osecm-0.0.2.amp qui sera alors possible d'intégrer dans Alfresco.war.

3. Intégration
Effectuez un copier/coller du fichier alf-amp-osecm-0.0.2.amp vers le répertoire amps du répertoire d'installation d'un Alfresco.
Lancer ensuite le script d'installation des amps dans le répertoire d'installation d'un Alfresco : apply_amps.bat
A la fin de celui ci, vous avez un nouveau alfresco.war mis à jour avec votre module.

4. Lancer Alfresco
Vous pouvez maintenant lancer Alfresco et vérifier l'intégration du module.


Voici selon moi, comment on peut faire un peu plus de Maven avec Alfresco.

Dans le prochain post, on explorera comment mettre en place des tests avec Maven.


PS :

L'ensemble des sources du projet alf-sdk sont téléchargeables à cette adresse : http://www.box.net/shared/2zpgm3fcag

L'ensemble des sources du projet alf-sdk-osecm (pour la création des fichiers de dépendances) sont téléchargeables à cette adresse : http://www.box.net/shared/fe6ftxeb4y

L'ensemble des sources du projet alf-amp-osecm sont téléchargeables à cette adresse : http://www.box.net/shared/s966vj1xqz
Lire la suite...