Category Archives: Publication

24Avr/18
bluexml expert GED ECM BPM Gestion Documentaire_Alfresco_HotswapAgent

Hot Reloading en Alfresco avec HotswapAgent

Pour développer en Java sur Alfresco, il faut absolument mettre en place une solution de hot reloading, car le temps de redémarrage du serveur de la plateforme est bien trop long pour pouvoir tester facilement les changements au code. Cela concerne aussi le développement de scripts serveur en JavaScript qui sont exécutés par le moteur Rhino : il n’est pas normal pour un dev JavaScript de devoir attendre quelques minutes avant de tester une petite modification du code.

Alfresco propose deux solutions : JRebel (payante) et HotswapAgent (open source). Pour l’instant j’ai choisi de ne pas investir dans JRebel et de bien tester son concurrent gratuit pour voir s’il suffit. Alfresco nous donne un tutoriel officiel pour l’utiliser, mais il manque quelque passage (notamment l’utilisation dans Eclipse qu’on ne trouve que pour JRebel), donc je vais refaire le tour pour arriver a un petit projet basé sur l’archétype Maven et le code démo qu’il contient.

La liste de courses

Nous allons utiliser un correctif pour la machine virtuelle Java (ne paniquez pas, il s’installe à côté, sans modifier la VM originale). Téléchargez donc la version pour Java 8 de DCEVM (version 8u152 à l’heure).

Bien évidemment, il faut avoir exactement la même version de Java, donc si vous utilisez une version différente, allez fouiller dans l’archive Oracle pour trouver la bonne.

Enfin, le vrai HotswapAgent. Inutile de télécharger la version la plus récente : pour Alfresco il faut utiliser la 1.0.

Voici un résumé des fichiers que j’ai utilisés dans Linux :

L’installation

Après avoir installé le JDK (pas besoin de l’installer en tant que administrateur), appliquez le correctif en utilisant cette commande :

$ java -jar DCEVM-8u152-installer.jar

En Windows on peut aussi taper deux fois sur DCEVM-8u152-installer.

Il s’agit d’un installateur qui vous donne une interface utilisateur assez simple :

Ajoutez la VM que vous venez d’installer et après tapez sur Install DCEVM as altjvm :

Quant au JAR du HotswapAgent, il faut tout simplement le mettre quelque part et se souvenir de son parcours.

Creation d’un projet

Créez un projet Maven comme indiqué dans la documentation Alfresco :

mvn archetype:generate -Dfilter=org.alfresco:

Choisissez l’archétype « All-in-One » et configurez les paramètres comme vous voulez.

Configuration d’Eclipse

Après avoir rajouté le JDK installé à la liste des JREs disponibles dans Eclipse (Window > Preferences > Java > Installed JREs), importez le projet (la documentation officielle explique comment faire et vous l’avez déjà fait plusieurs fois, donc je vous évite les détails).

Exécution du projet en mode hot reloading

Enfin, vous êtes prêts à créer une configuration pour exécuter le code. Dans les configurations de debug, créez-en une nouvelle de type Maven. Les paramètres à définir sont :

  • Base directory ${project_loc}
  • Goals clean install alfresco:run
  • Dans l’onglet JRE, sélectionnez le JRE avec le correctif DCEVM
  • VM arguments -Xms256m -Xmx2G -javaagent:/<parcours du HotswapAgent>/hotswap-agent-1.0.jar -XXaltjvm=dcevm

(Je vous conseille aussi de sélectionner Skip Tests, parce que la VM Hotswap est plus lente, donc c’est mieux de vérifier les tests séparément.)

Cette configuration peut être exécuté en mode DEBUG. Il faudra attendre un peu plus que d’habitude avant de pouvoir se connecter à Alfresco, mais il vaut le coup.

Cela donne quoi ?

Nous allons faire le test proposé par Alfresco dans le tutoriel JRebel : en se connectant à http://localhost:8080/alfresco/s/sample/helloworld, ou ici ;  le résultat sera Message: ‘Hello from JS!’ ‘HelloFromJava’

Sans arrêter le processus de debug, nous allons modifier ce message qui est généré par trois fichiers du projet platform-jar (on peut les ouvrir en tapant Ctrl+R et helloworld) : helloworld.get.js, helloworld.get.html.ftl et HelloWorldWebScript.java. Habituellement, un changement à chacun de ces fichiers entraine un redémarrage du projet.

Allons donc changer les messages :

  • dans helloworld.get.js remplacez model["fromJS"] = "Hello from JS!"; avec model["fromJS"] = "Bonjour de JS !";
  • dans helloworld.get.html.ftl remplacez Message: '${fromJS}' '${fromJava}' avec Messages : '${fromJS}' et '${fromJava}'
  • dans HelloWorldWebScript.java remplacez model.put("fromJava", "HelloFromJava"); avec model.put("fromJava", "Bonjour de Java");

À noter que chaque fois que vous tapez Ctrl+S, les changements sont pris en charge à l’instant et le log vous en donne confirmation. Un coup de F5 dans Firefox vous donne le nouveau message qui arrive des trois fichiers modifiés : pour l’instant rien à envier à JRebel.

Conclusion

Je trouve encore plus intéressante de pouvoir exécuter mes tests d’intégration en mode debug hot reloading, ce qui donne la possibilité de redémarrer à la volée une méthode qu’on vient de changer. Cela sera peut-être le sujet d’une autre article si cela vous intéresse.

02Mar/18
bluexml expert GED ECM BPM Gestion Documentaire_Alfresco_Docker Alfresco avec SSL

Conteneur Docker Alfresco avec SSL

Ceci est une petite note concernant la génération de conteneur Docker Alfresco. Pour d’autres logiciels, possédant par exemple des ports particuliers il conviendra d’adapter ces informations.
Afin d’utiliser un conteneur Alfresco en HTTPS, voici la configuration à passer à la commande “docker run” :

#!/bin/sh
docker run -it -d -v /data/mvico:/opt/alfresco/alf_data \
-e VIRTUAL_PROTO=https \
-e VIRTUAL_PORT=8443 \
-e VIRTUAL_HOST=mvico.docker.bluexml.com \
-e INITIAL_PASS=mvicoforever \
-e ALF_1=smart.folders.enabled.EQ.true \
-e ALF_2=alfresco.host.EQ.mvico.docker.bluexml.com \
-e ALF_3=alfresco.port.EQ.443 \
-e ALF_4=alfresco.protocol.EQ.https \
-e ALF_5=share.host.EQ.mvico.docker.bluexml.com \
-e ALF_6=share.port.EQ.443 \
-e ALF_7=share.protocol.EQ.https \
–name mvico-522 mvico-522:$BUILD_NUMBER

Note 1 : Les variables VIRTUAL_XXX servent à la configuration du vhost générée automatiquement par le proxy NGINX lors de chaque nouveau “run” de conteneur.
Voir conteneur NGINX proxy utilisé ici
Note 2 : Les variables ALF_XXX servent à la configuration du fichier “alfresco-global.properties” en accord avec le travail de Philippe Dubois (d’où le travail sur le changement de numéro de port)
Note 3 :  “.EQ.” signifie “=“. La substitution est effectuée pas NGINX lors de la génération du vhost.

Attention, dans Jenkins, onglet build du projet en question, par défaut il est nécessaire de mettre toute la commande sur un ligne; je vous l’accorde ce n’est pas hyper pratique ni lisible. L’éditeur ne gérant pas les sauts de ligne dans la commande. Il y a possibilité de scinder la commande en ajoutant “#!/bin/sh” au début du script et en ajoutant ” \” à chaque fin de ligne où la commande se poursuit. Ceci force l’outil d’intégration continue à exécuter la commande comme dans un script shell.

J’ajouterais enfin que pour l’édition en ligne, ne pas oublier d’ajouter la propriété aos.baseUrlOverwrite (pour cet exemple) (et en remplaçant le “=” par “.EQ.” bien sûr 😉 ). Sans cela Alfresco insérera le port 8443 dans l’URL AOS et le document ne sera pas ouvert par Office.

Je terminerais en précisant s’il est nécessaire que dans cette installation, et vous l’aurez sans doute compris, nous avons plusieurs conteneurs Docker qui interagissent : celui d’Alfresco et ceux d’NGINX.

Hope this helps.

16Fév/18
bluexml expert GED ECM BPM Gestion Documentaire_Alfresco_VitamLogoRelease5

Génération d’un paquet SIP conforme au format SEDA 2.0

Introduction

Le projet VITAM propose des outils pour générer des SIP conformes au format SEDA 2.0 à partir d’une arborescence de fichiers.

Si cette fonctionnalité est disponible sur Windows et Linux, il est nécessaire de faire quelques adaptations pour MacOSX.

Adaptations

Installation de siegfried

Le générateur SEDA de VITAM utilise l’application siegfried pour détecter les formats des fichiers à intégrer. Pour cela, il suffit d’installer cette application à l’aide de brew :

brew install siegfried

Modification de run_generate.sh

Vous tentez alors de générer le paquet SIP :

sh run_generate.sh monrepertoire

Il est possible que vous obteniez le message d’erreur suivant :

jck$ > sh run_generator.sh conf
 run_generator.sh: line 4: realpath: command not found
 The given path must be a directory (not a single file):

Pour résoudre ce problème, vous devez installer coreutils :

brew install coreutils

Les outils ainsi fournis sont stockés, pour mon installation, dans le répertoire /usr/local/opt/coreutils/libexec/gnubin. Du coup, il faut modifier run_generator.sh pour lui donner cette information (ligne 4) :

#!/bin/sh
SCRIPT_DIR=$(dirname $0)
if [ "x$1" != "x" ];then
 TARGET_DIR=$(/usr/local/opt/coreutils/libexec/gnubin/realpath "$1")
fi
java -classpath "$SCRIPT_DIR/conf:$SCRIPT_DIR/lib/*" -Dvitam.config.folder=/tmp -Dvitam.tmp.folder=/tmp -Dvitam.data.folder=/tmp -Dvitam.log.folder=/tmp fr.gouv.vitam.generator.scanner.main.SedaGenerator "$SCRIPT_DIR" "$TARGET_DIR"

Utilisation

Il suffit alors de relancer le script run_generator.sh sur le répertoire de votre choix. Et ça marche !

jck$ > sh run_generator.sh monrepertoire
2018-02-16 16:01:25,987 [main] INFO f.g.v.g.scanner.main.SedaGenerator : Generateur SEDA : Beginning of scan of directory /Users/bxml/Documents/opt/local/new-workspaces/vitam/seda/generateur-seda_0.16.0/monrepertoire 
2018-02-16 16:01:26,951 [main] INFO f.g.v.generator.scanner.core.ScanFS : Managing BinaryDataObjects : 455 ms for 3 BinaryDataObjects (time per BDO : 151 ms) 
2018-02-16 16:01:27,085 [main] INFO f.g.v.generator.scanner.core.ScanFS : Writing ArchiveUnits : 127 ms for 5 ArchiveUnits (time per AU : 25 ms) 
2018-02-16 16:01:27,366 [main] INFO f.g.v.g.scanner.main.SedaGenerator : Generateur SEDA : End of scan of directory /Users/bxml/Documents/opt/local/new-workspaces/vitam/seda/generateur-seda_0.16.0/monrepertoire in 1380 ms

Conclusion

Merci Vitam 🙂

18Jan/18
bluexml expert GED ECM BPM Gestion Documentaire_Alfresco_Blog

Présentation de l’outil Alfresco Bulk Export

Alfresco Bulk Export Tool.

Vijay Prince a présenté l’outil Alfresco Bulk Export Tool à la Devcon Alfresco et comment l’utiliser et gérer les exports de données pendant les migrations.
Plusieurs fonctionnalités ont été ajoutées à l’outil afin de rendre son usage plus simple :
[list style=”list12″ color:”#6699ff”]

  • Une interface utilisateur pour superviser l’export et utiliser l’outil
  • Vous pouvez à présent démarrer, stopper et redémarrer l’export via l’interface
  • Vous pouvez choisir une période d’export
  • Vous pouvez ajouter des aspects et des propriétés aux données exportées
  • Vous pouvez mettre à jour les types, les aspects et les propriétés
  • Vous pouvez mettre à jour le préfix du modèle
[/list] L’interface n’est pas très belle mais efficace :

Si vous souhaitez plus d’informations sur ce projet

02Jan/18
bluexml expert GED ECM BPM Gestion Documentaire_Alfresco_News Société

Voeux 2018

Nous vous souhaitons une bonne et heureuse année 2018.
Merci à nos clients de leur confiance renouvelée. Nous sommes heureux de poursuivre nos collaborations. Et nous restons à l’écoute et au service de tous pour démarrer de nouvelles aventures.

01Déc/17
bluexml expert GED ECM BPM Gestion Documentaire_Alfresco_oldlogo-Flowable

Installation de Flowable

Introduction

Ce tutoriel décrit comment installer et configurer l’application de BPM Flowable pour stocker les informations de manière permanente, l’installation de base par défaut étant temporaire, vos travaux sont purement et simplement supprimés à chaque arrêt/redémarrage de votre serveur BPM.

Pré-requis

Flowable est une application Java qui stocke les nombreuses informations qu’elle gère dans une base de données relationnelles. Elle a donc besoin d’un moteur de base de données relationnelles, par exemple postgresql ou mysql ainsi que d’un moteur d’exécution tel que Tomcat.

Vous pouvez trouver des informations sur l’installation de ces logiciels sur les sites correspondants.

Installation

Dans un premier temps, téléchargez la dernière version de Flowable. :

  • Double-cliquez sur l’archive flowable que vous avez récupérée. Récupérez les fichiers contenus dans le répertoire « wars » et déposez-les dans le répertoire webapps de tomcat
  • Lancez tomcat en double-cliquant sur ./bin/startup.bat

Vous pouvez alors vous connecter sur l’application flowable :

  • http://localhost:8080/flowable-idm/

Flowable est installé mais cette installation est temporaire : rien de ce que vous ferez ne sera sauvegardé. Il faut donc configurer flowable pour utiliser une base de données et persister les informations.

Configuration et initialisation

Afin de rendre les processus persistants, tout comme les données de configuration telles que les utilisateurs, il est nécessaire de configurer Flowable pour qu’il utilise la base de données que vous avez installée :

datasource.driver=org.postgresql.Driver

datasource.url=jdbc:postgresql://localhost:5432/flowable

Bien sûr, n’oubliez pas de créer la base de données correspondante:-)

Arrêtez et redémarrez Tomcat.

Initialisation

Avant de pouvoir faire quoique ce soit, il vous faut d’abord créer quelques utilisateurs et leur donner les droits nécessaires et suffisants pour pouvoir :

  • administrer flowable ;
  • créer des utilisateurs ;
  • modéliser des applications ;
  • gérer les tâches.

Création des utilisateurs

L’utilisateur par défaut est admin :

  • utilisateur : admin
  • mot de passe : test

Connectez-vous à l’adresse suivante :

Vous arrivez alors sur l’écran suivant :

  • Cliquez sur Créer un utilisateur
  • Saisissez les informations attendues

Dans le cadre de notre tutoriel, je vous invite à créer les utilisateurs suivants, en mettant le même mot de passe que le nom d’utilisateur, et ajoutant @test.org à chaque nom d’utilisateur (pas besoin que l’adresse soit opérationnelle ou même réelle) :

  • Jean-Christophe ELPADRE : directeur / identifiant : jcelpadre
  • Théo LEPREM : directeur commercial / identifiant : tleprem
  • Max LESEC : directeur RH / identifiant : mlesec
  • Lou LADER : directrice SI / identifiant : llader

Création des groupes

Cliquez ensuite sur l’onglet Groupes et créez les groupes suivants :

  • Nom : Administrateurs Alfresco / Identifiant : ADMIN_ALFRESCO
  • Nom : Administrateurs Flowable / Identifiant : ADMIN_FLOWABLE
  • Nom : Direction / Identifiant : DIR_GEN
  • Nom : Direction Commerciale / Identifiant : DIR_CALE
  • Nom : Direction des Ressources Humaines / Identifiant : DIR_RH
  • Nom : Direction du Service Informatique / Identifiant : DIR_SI

Ajoutez ensuite les utilisateurs créés précédemment dans les groupes ci-dessus.

Configuration des privilèges

Pour finir, cliquez sur l’onglet Privilèges :

Et donnez les privilèges suivants :

  • Accéder à l’application de gestion des identités : ADMIN_FLOWABLE
  • Accéder à l’application d’administration : ADMIN_FLOWABLE
  • Accéder à l’application de modélisation : DIR_TRANSVERSE_METIER
  • Accéder à l’application de workflow : DIR_CALE, DIR_GEN, DIR_RH, DIR_SI

Test

Connectez-vous sur l’application http://localhost:8080/flowable-modeler/ avec l’utilisateur jcelpadre et vérifiez que vous avez accès aux fonctions de modélisation :

31Juil/17
bluexml expert GED ECM BPM Gestion Documentaire_Alfresco_Docker

Mise en place d’un RedMine actif sur Docker

Lorsque l’on développe une application, celle-ci est testée sur une machine de développement. Mais il peut être intéressant de préserver le comportement de l’application indépendamment de la machine utilisée. Pour cela, il est possible d’utiliser un Docker, qui permet la mise en place d’un environnement virtuel qui ne varie pas selon la machine sur laquelle il est déployé.

Cet article va se diviser en 2 parties :

  1. Mise en place d’un container Docker sur une machine Ubuntu.
  2. Mise en place d’une image de l’environnement de développement d’un RedMine existant.

1 . Technologies Utilisées

  • Linux Ubuntu 16.04
  • RedMine 3.3.3
  • Docker 17.03.1

2 . Déroulement du développement

2.1   Mettre à jour Linux :

Source(s) utilisée(s) : https://angristan.fr/mettre-a-jour-ubuntu-16-04-lts/

Dans un premier temps, afin d’être bien sûr de mon environnement, j’ai effectué une ‘bête’ mise à jour de Linux … sans imaginer tous les problèmes que cela allait engendrer …

Problème(s) rencontré(s) :

  1. Crash au redémarrage de la machine sur la page de chargement. Ubuntu ne se lance pas, seul le chargement des packages avec [OK] sont inscrits à l’écran.
  2. Connexion au réseau Wi-Fi, mais aucune connexion Internet.
  3. Message d’erreur rencontré lors de l’utilisation d’apt.

N: « 50unattended-upgrades.ucf-old » dans le répertoire « /etc./apt/apt.conf.d/ » a été ignoré car il utilise une extension non valable

Solution(s) apportée(s) :

  1. Suppression d’un package en passant par l’invite de commande (ctrl+alt+1).

apt-get remove insserv

  1. Suppression d’une 2ème route par défaut sur le mauvais port (eth0 au lieu de wlan0).
  2. Suppression du fichier “50unattended-upgrades.ucf-dist”

Source(s) solution(s) :

  1. https://help.directadmin.com/item.php?id=379
  2. Collègue Brice PAJOT
  3. https://forum.ubuntu-fr.org/viewtopic.php?id=1999366

2.2  Installation de Docker CE (Community Edition) pour Linux :

Source(s) utilisée(s) : https://docs.docker.com/engine/installation/linux/ubuntu/

Installation de Docker Community Edition sur la machine.

Problème(s) rencontré(s) : Aucun

Solution(s) apportée(s) : Aucune

Source(s) solution(s) : Aucune

2.3  Lancement d’un environnement RedMine sur Docker :

2.3.1  RedMine simple :

Source(s) utilisée(s) : https://hub.docker.com/_/redmine/

Dans un premier temps, j’ai mis en place un RedMine simple (qui ne s’appuie sur aucune base existante).

$ docker run -d --name some-redmine redmine

$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' some-redmine

>172.17.0.2

Aller dans le navigateur et entrer l’adresse retournée dans l’invite de commande + port 3000 : 172.17.0.2:3000

Voilà, un RedMine neuf est lancé, cependant ce n’est pas réellement ce qui nous intéressait initialement.

Problème(s) rencontré(s) : Aucun

Solution(s) apportée(s) : Aucune

Source(s) solution(s) : Aucune

2.3.2  RedMine personnalisé :

Source(s) utilisée(s) : http://www.outofpluto.com/blog/how-to-dockerize-your-outdated-redmine/

https://github.com/abgotsunami/simple-docker-redmine

Dans l’optique d’installer un RedMine personnalisé (Avec une base de donnée, des plugins, des thèmes) nous allons suivre le Tutoriel du site OutOfPluto :

Tout d’abord, récupérer les sources du GitHub pour la suite du développement, puis se placer dans le dosser ‘simple-docker-RedMine’ du git cloné.

Résumé du Tutoriel GitHub/OutOfPluto :

Création d’une boite qui contiendra la base de données de notre RedMine

docker pull busybox

docker create –name redminedata busybox

    docker pull mysql

    docker run -d –volumes-from redminedbdata -e MYSQL_ROOT_PASSWORD=<root_psswd> -e MYSQL_DATABASE=redmine -e MYSQL_USER=redmine -e MYSQL_PASSWORD=<redmine_psswd> --name tmpdb mysql

NOTE : Penser à remplacer <root_psswd> par ‘ root ’ et <redmine_psswd> par ‘ RedMine ’ dans lignes de commandes et le fichier docker-compose.yml

docker exec -ti tmpdb /bin/bash

mysql

CREATE USER ‘lwa’@’%’ IDENTIFIED BY ‘=<redmine_psswd>’;

CREATE DATABASE ‘redmine’;

GRANT ALL PRIVILEGES ON redmine.* TO ‘redmine’@’%’;

exit

exit

NOTE : Erreur dans le GitHub, écrire ‘ tmpdb ‘ à la place de ‘ db ‘.

NOTE : Une erreur peu intervenir à l’exécution de mysql, se référer aux erreurs ci-dessous (problèmes rencontrés).

docker stop tmpdb

docker rm tmpdb

(Inutile d’installer / configurer nginx dans notre situation)

Dans le fichier docker-compose.yml :

Supprimer la partie nginx

Remplacer <mydomain> par ‘ localhost ‘ à la ligne     – MAILNAME=localhost

Rajouter :

ports:

– 3000:3000

Juste en dessous de    – smtp:smtp

Changer les versions dans le fichier Dockerfile par les plus récentes :

  • ruby:2.4-slim
  • GOSU_VERSION 1.10
  • TINI_VERSION v0.14.0
  • REDMINE_VERSION 3.3.3

NOTE : Changer ruby:2.4-slim  par   ruby:2.2-slim  peut éviter quelques erreurs directement (voir liste des erreurs ci-dessous)

docker-compose build

docker-compose up

Problème(s) rencontré(s) :

  1. Erreur à l’étape 4 du github, pas les permissions pour root@localhost lors de l’exécution de mysql.
  2. Erreur lors du docker-compile build
ERROR: Service 'redmine' failed to build: The command '/bin/sh -c set -x     && curl -fSL -o /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)"     && […] && gosu nobody true' returned a non-zero code: 127
  1. Erreur lors du docker-compile build
ERROR: Service 'redmine' failed to build: The command '/bin/sh -c curl -fSL "http://www.redmine.org/releases/redmine-${REDMINE_VERSION}.tar.gz" -o redmine.tar.gz     && […] && chown -R redmine:redmine ./' returned a non-zero code: 1
  1. simpledockerredmine_redmine_1 exited with code 2 lors de   docker-compile up
  2. simpledockerredmine_redmine_1 exited with code 1 lors de docker-compile up En remontant plus haut on aperçoit également :
 /usr/local/lib/ruby/gems/2.4.0/gems/activesupport-4.2.7.1/lib/active_support/core_ext/numeric/conversions.rb:121: warning: constant ::Fixnum is deprecated

/usr/local/lib/ruby/gems/2.4.0/gems/activesupport-4.2.7.1/lib/active_support/core_ext/numeric/conversions.rb:121: warning: constant ::Bignum is deprecated

rake aborted!

Solution(s) apportée(s) :

  1. mysql -u root -p  à la place de      mysql
  2. Ajout de RUN apt-get update && apt-get install -y apt-transport-https && apt-get install -y curl   dans le fichier Dockerfile avant la ligne :

#grab gosu for easy step-down from root

(Ecrire ligne 5)

  1. la ligne && echo “$REDMINE_DOWNLOAD_MD5 redmine.tar.gz” | md5sum -c – \  dans le fichier docker-compose.yml pose soucis, car la vérification de la variable  $REDMINE_DOWNLOAD_MD5  n’est pas connue en brut pour la version de RedMine 3.3.3, j’ai simplement retiré cette ligne. (On peut éventuellement la commenter ou chercher la valeur en ligne).
  2. Exécuter :

docker logs simpledockerredmine_redmine_1

On s’aperçoit qu’il y a un ‘ ” ‘ manquant dans le fichier docker-entrypoint.sh ligne 54

  1. RedMine 3.3.3 ne supporte pas Ruby 2.4 et 2.3, changer ruby:2.4-slim  par   ruby:2.2-slim dans le fichier Dockerfile

Source(s) solution(s) :

  1. http://askubuntu.com/questions/401449/error-104528000-access-denied-for-user-rootlocalhost-using-password-no
  2. http://www.redmine.org/issues/25109

2.4  Intégration de la base de données d’un RedMine existant :

Source(s) utilisée(s) : http://www.outofpluto.com/blog/how-to-dockerize-your-outdated-redmine/

Tout d’abord, faire une sauvegarde de la base de données du RedMine actuel, créer un fichier recover.sh contenant :

#!/bin/bash

/usr/bin/mysqldump -u redmine -pmy_password redmine |gzip > ./redmine_db`date +%y_%m_%d`.gz

Exécuter. recover.sh

Le .gz contient un fichier, extraire ce fichier, le renommer en .sql

(Pendant que le docker RedMine est lancé)

(Pour lancer un docker sans avoir besoin d'une console active, utiliser l'argument -d après docker-compose up)

 docker cp backup_db/redmine_db17_04_13.sql simpledockerredmine_db_1:/

 docker exec -ti simpledockerredmine_db_1 /bin/bash



 mysql -u RedMine -predmine -D RedMine < /redmine_db17_04_13.sql

 rm redmine-db17_04_13.sql

 exit

NOTE : Remplacer 17_04_13 par la date du fichier .sql (date actuelle)

Enfin, associer maintenant les fichiers présents sur notre RedMine actuel avec le RedMine du Docker.

docker inspect --format "{{ .Mounts }}" simpledockerredmine_redmine_1

 [{bind  /var/lib/docker/volumes/24d85b9a6996844d7c1260a19b200e49a1001a7b40962377b5d40ef4c323694f/_data /usr/src/redmine/files  rw true }]

 sudo cp -r <REDMINE_PATH>/files/* /var/lib/docker/volumes/24d85b9a6996844d7c1260a19b200e49a1001a7b40962377b5d40ef4c323694f/_data

NOTE : <REDMINE_PATH> est le chemin vers le RedMine (éventuellement. si on se place à la racine du RedMine)

NOTE : La partie longue (/var/lib/docker/volumes/24…/_data) est propre au résultat obtenu par la commande précédente

Voilà, le RedMine du Docker possède maintenant la même base de données (utilisateurs, fichiers, etc. …) que le RedMine précédent.

Problème(s) rencontré(s) : Aucun

Solution(s) apportée(s) : Aucune

Source(s) solution(s) : Aucune

2.5  Ajout de Plugins et Thèmes :

Source(s) utilisée(s) : http://www.outofpluto.com/blog/how-to-dockerize-your-outdated-redmine/

2.5.1  Ajouter un plugin custom ou existant sur la machine :

Pour ajouter un plugin déjà présent sur le pc, créer un .tar.gz de celui-ci puis le mettre dans le répertoire RedMine/plugins de notre répertoire Docker.

Dans le fichier Dockerfile, sous la catégorie #install some plugins, écrire :

COPY RedMine/monplugin.tar.gz /usr/src/RedMine/plugins/

RUN tar xzf /usr/src/RedMine/plugins/monplugin.tar.gz -C /usr/src/RedMine/plugins/ \

    && rm /usr/src/RedMine/plugins/monplugin.tar.gz

Puis dans l’invite de commande :

docker-compose stop

docker-compose build

docker-compose up -d
2.5.2  Ajouter un plugin depuis un github :

Dans le cas d’un plugin qui provient directement d’un GitHub, il est possible de l’intégrer par lien. Dans le fichier Dockerfile, sous la catégorie #install some plugins, écrire :

RUN git clone <adresse_github>.git <nom_repertoire_plugin> && mv <nom_repertoire_plugin> /usr/src/RedMine/plugins/

<adresse_github> est l’adresse à laquelle se trouve le plugin à télécharger ex : https://github.com/onozaty/redmine-parent-issue-filter

<nom_repertoire_plugin> est le nom que doit porter le répertoire du plugin ex : parent_issue_filter

le nom du répertoire peut être connu en regardant dans le fichier init.rb du plugin : RedMine::Plugin.register :parent_issue_filter do

Exemple final :

RUN git clone https://github.com/onozaty/redmine-parent-issue-filter.git parent_issue_filter && mv parent_issue_filter /usr/src/redmine/plugins/
2.5.3  Ajouter un thème :

Pour ajouter un thème, il suffit d’appliquer exactement la même méthode que pour l’ajout d’un plugin. Dans le fichier Dockerfile, sous la catégorie #install theme, écrire :

RUN git clone <adresse_github>.git && mv <nom_repertoire_theme> /usr/src/redmine/public/themes/<nom_theme>

COPY redmine/themes/<nom_theme>/stylesheets/ /usr/src/redmine/public/themes/<nom_theme>/stylesheets/

Ici le répertoire n’a pas besoin d’être renommé (il peut l’être, de la même manière que pour le plugin si le nom ne convient pas).

<nom_theme> est le nom que vous choisirez de donner au thème.

Problème(s) rencontré(s) : Aucun

Solution(s) apportée(s) : Aucune

Source(s) solution(s) : Aucune

3. Durée de développement

Le développement de ce module a duré 2 jours du 04/12 au 04/13.

4. Commentaires supplémentaires

Une partie du développement a été consacrée à la lecture de la documentation Docker (et à la résolution des problèmes engendrés par la mise à jour de Linux).

 

Auteur : Alexandre BOUDINE

31Juil/17
bluexml expert GED ECM BPM Gestion Documentaire_Alfresco_Redmine

Reprise du tutoriel officiel de création d’un plugin RedMine

Cet article a pour objectif de reprendre le tutoriel officiel de création de plugin RedMine, tout en y apportant les corrections et modifications nécessaires pour le faire fonctionner correctement et avec la version 3.3 de RedMine. De plus, il y liste une partie des erreurs et problèmes rencontrés au cours de sa réalisation et les solutions apportées.

NOTE : Mon conseil pour la réalisation d’un plugin RedMine est d’utiliser l’article [CREATION_PLUGIN_REDMINE] qui contient de plus amples explications, ainsi que plus d’exemples pour des cas différents (surcharges de méthodes déjà existantes dans le cœur de l’application par exemple).

1 . Déroulement du développement

Source(s) utilisée(s) :

Partant du principe que RedMine est installé sur la machine et correctement configuré.

1.1  Création des fichiers du plugin

Un script est disponible pour créer automatiquement les répertoires / fichiers nécessaire à la création d’un plugin (y compris des répertoires optionnels). Se placer dans le répertoire RedMine :

$ export RAILS_ENV="production"
$ RAILS_ENV=production
$ bundle exec ruby bin/rails generate redmine_plugin <nom_plugin>

Modifier le fichier plugins/<nom_plugin>/init.rb  pour y modifier les informations qui conviennent.

Redémarrer l’application RedMine, dans l’onglet ‘Administration/plugins’ le plugin apparaît (mais ne sert actuellement à rien).

Problème(s) rencontré(s) : Aucun

Solution(s) apportée(s) : Aucune

Source(s) solution(s) : Aucune

1.2   ‘Model’, ‘View’, ‘Controller’ et premières actions

L’objectif du plugin développé dans ce tutoriel est de créer un système de sondage pouvant être répondus par ‘oui’ ou ‘non’.

La suite de commande qui permet de faire cela n’est pas très explicite à première vue, elle utilise des scripts pré construits pour créer une table contenant des objets ‘poll’ (sondage) dans la base de donnée du RedMine. Ceux-ci possèdent une question ainsi qu’un nombre de réponses ‘oui’ et ‘non’.

De plus, cela créé également un ‘model’, c’est une classe où sont répertoriée les méthodes qui interagissent directement avec notre objet.

$ bundle exec ruby bin/rails generate redmine_plugin_model mon_plugin poll question:string yes:integer no:integer

Syntaxe:

bundle exec ruby bin/rails generate redmine_plugin_model <nom_plugin> <nom_model> [<nom_attribut>[:type]] [<nom_attribut2>[:type2]] [...]

<nom_model> correspond au nom de la “classe” générée, ici par exemple “poll” (sondage)

<nom_attribut> est le nom de la variable, ex : question,oui,non,…

type est la type de la variable, ex : string,integer,boolean,…

Mettre à jour la base de données :

$ bundle exec rake redmine:plugins:migrate
$ bundle exec ruby bin/rails console

NOTE : Erreur possible lors de l’appel à la console, voir les solutions ci-dessous

Création de deux sondages (depuis la console) :

Poll.create(:question => "Suis-je une première question")

Poll.create(:question => "Et maintenant")

exit

Créer la fonction de vote pour le sondage (qui incrément le score de ‘oui’ ou ‘non’ de chaque sondages).

Dans le fichier plugins/<nom_plugin>/app/models/poll.rb  écrire :

class Poll < ActiveRecord::Base

def vote(answer)

increment(answer == ‘yes’ ? :yes : :no)

end

end

Cependant pour interagir avec notre model il nous faut un contrôleur qui fasse la liaison entre les actions de l’utilisateur et les répercussions sur les objets. Génération du contrôleur qui permet d’interagir avec les sondages :

$ bundle exec ruby bin/rails generate redmine_plugin_controller mon_plugin polls index vote

Syntaxe :

bundle exec ruby bin/rails generate redmine_plugin_controller <plugin_name> <controller_name> [<actions>] […]

La fonction Index sert à lister les sondages.

LA fonction Vote sert à voter sur un sondage et incrémenter le nombre de réponses correspondant.

Dans le fichier plugins/mon_plugin/app/controllers/polls_controller.rb  écrire :

class PollsController < ApplicationController

unloadable

def index

@polls = Poll.all

end

def vote

poll = Poll.find(params[:id])

poll.vote(params[:answer])

if poll.save

flash[:notice] = 'Vote saved.'

end

redirect_to :action => 'index'

end

end

Puis écrire dans le fichier plugins/mon_plugin/app/views/polls/index.html.erb :

<h2>Polls</h2>

<% @polls.each do |poll| %>

<p>

<%= poll.question %>?

<%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes'}, :method => :post %> (<%= poll.yes %>) /

<%= link_to 'No', {:action => 'vote', :id => poll[:id], :answer => 'no'}, :method => :post %> (<%= poll.no %>)

</p>

<% end %>

On peut supprimer le fichier plugins/mon_plugin/app/views/polls/vote.html.erb (car la méthode vote n’a pas de rendu à l’écran)

Enfin afin d’établir un lien entre les boutons, et l’adresse URL de sondage, il est nécessaire de déclarer des ‘routes’ pour que l’application comprenne ce que l’on veut faire.

Écrire dans le fichier plugins/mon_plugin/config/routes.rb :

get 'polls', :to => 'polls#index'

post 'post/:id/vote', :to => 'polls#vote'

Redémarrer le RedMine (probablement via la commande bundle exec rails server webrick -e production)

Dans un navigateur : localhost:3000/polls devrait permettre d’afficher les sondages créés précédemment.

Problème(s) rencontré(s) :

  1. Lors de l’appel à rails console
/usr/local/lib/ruby/2.3.0/irb/completion.rb:10:in `require': cannot load such file -- readline (LoadError)

[…]

from bin/rails:4:in `<main>'

Solution(s) apportée(s) :

  1. Dans le fichier Gemfile, rajouter la ligne :
gem "rb-readline"

Source(s) solution(s) :

  1. http://stackoverflow.com/questions/22915676/rails-console-in-require-cannot-load-such-file-readline-loaderror

1.3  Gérer les onglets

Actuellement les plugins sont accessibles uniquement depuis l’adresse ‘/polls’ ce qui n’est pas très pratique. Nous devons donc rajouter la possibilité d’accéder à notre index depuis un onglet.

Pour afficher l’accès au plugin dans un onglet,

Dans plugins/mon_plugin/init.rb écrire :

Redmine::Plugin.register :mon_plugin do

[...]

menu :application_menu, :polls, { :controller => 'polls', :action => 'index' }, :caption => 'Polls'

end

Syntaxe :

menu <zone_menu>, <nom_model>, { <action> }, <nom_menu>

<zone_menu> peut être :

:top_menu – En haut à gauche

:account_menu – En haut à droite (près de my account, sign out, …)

:application_menu – Le menu principal

:project_menu – Le menu dans un projet

:admin_menu – Le menu de la page administrateur (entre plugin et settings)

NOTE : pour utiliser l’option :project_menu, il est utile d’écrire la ligne :

permission :polls, { :polls => [:index, :vote] }, :public => true

Juste au-dessus de l’autre pour permettre aux utilisateurs de voir l’onglet.

<nom_model> est le nom du model implémenté et utilisé, ici polls

<action> est l’action exécutée lors du clic sur l’onglet :

:controller => 'polls', :action => 'index'

Signifie que la méthode ‘index’ (qui renvoie tous les sondages) du controller de ‘polls’ est appelé au clic.

<nom_menu> sous la forme :caption => ‘<nom>’ donne simplement un nom brut à l’onglet

De plus vastes options peuvent être trouvées sur : http://www.redmine.org/projects/redmine/wiki/Plugin_Tutorial#Extending-the-application-menu

Nous allons nous placer dans le contexte de l’affichage par projet (:project_menu).

Pour que l’onglet du plugin, affiche les autres onglets liés au projet :

Dans le fichier plugins/mon_plugin/app/controller/polls_controller.rb modifier :

def index

@project = Project.find_by_identifier(params[:project_id])

@polls = Poll.all

end

Pour supprimer des éléments de menu :

Dans le fichier plugins/mon_plugin/init.rb ecrire :

delete_menu_item <zone_menu>, <nom_element>

<zone_menu> comme vu précédemment

<nom_element> le nom du menu à supprimer

Par exemple pour supprimer l’onglet Gantt des projets :

delete_menu_item :project_menu, :gantt

Problème(s) rencontré(s) :

  1. Erreur 404 not found lors de la création de la méthode index pour les sondages.
  2. Après vote, les menus ne reviennent pas.

Solution(s) apportée(s) :

  1. remplacer
@project = Project.find(params[:project_id])

Par

@project = Project.find_by_identifier(params[:project_id])
  1. Dans plugins/mon_plugin/app/controllers/polls_controller.rb :

Changer

redirect_to :action => 'index'

Par

redirect_to :action => 'index', :project_id => params[:project_id]

Dans plugins/mon_plugin/app/polls/index.html.erb :

après   :answer => ‘yes’ et :answer => ‘no’   ajouter :   , :project_id => @project[:identifier]   de cette manière :

<%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes', :project_id => @project[:identifier]}, :method => :post %> (<%= poll.yes %>)

Source(s) solution(s) :

  1. http://www.redmine.org/boards/3/topics/48536
  2. http://www.redmine.org/boards/3/topics/11999

1.4  Définir des Permissions

Toutes les actions ne sont pas bonnes à être utilisées par tout le monde, il peut être nécessaire de définir des permissions pour ces actions. Dans le fichier plugins/mon_plugin/init.rb :

Commenter la ligne

permission :polls, { :polls => [:index, :vote] }, :public => true

Ajouter les lignes :

permission :view_polls, :polls => :index

permission :vote_polls, :polls => :vote

Syntaxe :

permission :<nom_permission>, :<nom_model> => :<nom_methode>

<nom_permission> est le nom choisi par l’utilisateur pour cette permission (espaces remplacés par des _ )

<nom_model> le nom du model auquel appartient la méthode à gérer

<nom_méthode> le nom de la méthode qui doit avoir une permission

Dans le fichier plugins/mon_plugin/app/controllers/polls_controller.rb modifier le fichier de la manière suivante :

class PollsController < ApplicationController

unloadable

before_filter :find_project, :authorize, :only => [:index, :vote]

def index

#@project = Project.find_by_identifier(params[:project_id])

@polls = Poll.all

end

[...]

private

def find_project

#@project variable must be set before calling the authorize filter

@project = Project.find_by_identifier(params[:project_id])

end

end

Pour renommer proprement les permissions, aller dans plugins/mon_plugin/config/locales/ et créer (ou éditer) le fichier .yml de la langue voulue (ex : en.yml) pour y ajouter

en:

permission_view_polls: View Polls

permission_vote_polls: Vote Polls

Pour permettre d'utiliser ce plugin dans certain projet (pas tous) :

Éditer le fichier plugins/mon_plugin/init.rb pour le modifier de la sorte :

project_module :polls do

permission :view_polls, :polls => :index

permission :vote_polls, :polls => :vote

end

Problème(s) rencontré(s) :

  1. Les votes ne semblent pas être affectés par les permissions.

Solution(s) apportée(s) :

  1. Modification du code

Source(s) solution(s) :

  1. http://www.redmine.org/boards/2/topics/17002

1.5  Amélioration du rendu visuel

Afin de mettre un peu de couleur et d’améliorer le rendu du plugin :

Créer un fichier <nom>.css dans plugins/mon_plugin/assets/stylesheets/

<nom> le nom que l’on souhaite ici par exemple : voting.css

Et y écrire :

a.vote { font-size: 120%; }

a.vote.yes { color: green; }

a.vote.no  { color: red; }

Modifier le fichier plugins/mon_plugin/app/views/polls/index.html.erb pour y ajouter

, :class => ‘vote yes’ après :post

soit :

<%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes' }, :method => :post, :class => 'vote yes' %> (<%= poll.yes %>)

<%= link_to 'No', {:action => 'vote', :id => poll[:id], :answer => 'no' }, :method => :post, :class => 'vote no' %> (<%= poll.no %>)

Et ajouter :

<% content_for :header_tags do %>

<%= stylesheet_link_tag 'voting.css', :plugin => 'mon_plugin' %>

<% end %>

à la fin du fichier.

(On peut également modifier le titre de la page avec <% html_title “Polls” %>)

NOTE : Il est possible que l’affichage du css ne fonctionne pas, se référer à l’erreur ci-dessous

Problème(s) rencontré(s) :

  1. Le fichier css ne fonctionne pas

Solution(s) apportée(s) :

  1. Doubler le 1er élément de chaque bloc css, de la sorte :
a.vote {

font-size: 120%;

font-size: 120%;

}

Source(s) solution(s) :

  1. Tests depuis l’éditeur du navigateur web.

1.6  Utiliser le principe des ‘Hooks’

La suite de ce tutoriel n’as donc plus rien à voir avec la partie des sondages, elle permet uniquement de donner des exemples d’utilisations divers. Pour ajouter du contenu à une page existante, on utilise le principe des hooks (accroches) qui permettent d’incruster du code dans une partie de code déjà existante. Créer un fichier plugins/mon_plugin/lib/hooks.rb contenant :

class Hooks < Redmine::Hook::ViewListener

def view_projects_show_left(context = {})

return content_tag("p", "Custom content added to the left")

end

def view_projects_show_right(context = {})

return content_tag("p", "Custom content added to the right")

end

end

Ajouter au fichier plugins/mon_plugin/init.rb la ligne suivante :

require_dependency 'hooks'

Méthode alternative :

Dans le fichier hooks.rb, écrire :

class Hooks < Redmine::Hook::ViewListener

render_on :view_projects_show_left, :partial => "polls/overview"

end

Créer un fichier plugins/mon_plugin/app/views/polls/_overview.html.erb et y rentrer du texte ex :

"Custom content added to the left"

Problème(s) rencontré(s) :

  1. Aucuns

Solution(s) apportée(s) :

  1. Aucunes

Source(s) solution(s) :

  1. Aucunes

1.7  Rendre le plugin configurable

Il peut être parfois intéressant de rendre une partie du plugin configurable, pour activer l’option de configuration :

Ajouter au fichier plugins/mon_plugin/init.rb la ligne :

settings :default => {'empty' => true}, :partial => 'settings/<mon_module>_settings'

<mon_module> est le nom attribué aux configurations, il doit être différent de celui de tout les autres plugins RedMine.

Créer le répertoire plugins/mon_plugin/app/views/settings/

Créer le fichier plugins/mon_plugin/app/views/settings/_<mon_module>_settings.html.erb et y inscrire du code html, tel que :

<table>

<tbody>

<tr>

<th>Notification Default Address</th>

<td>

<input type="text" id="settings_notification_default"

value="<%= settings['notification_default'] %>"

name="settings[notification_default]" >

</td>

</tr>

</tbody>

</table>

<br>

<% for status in IssueStatus.all do %>

<p>

<label for="settings_status-<%= status.id %>"><%= status.name %></label>

<%= select_tag "settings[status-#{status.id}]",

options_from_collection_for_select(

[[l(:label_no_change_option), '']] +

(0..10).to_a.collect{|r| ["#{r*10} %", r*10] },

:last, :first, @settings["status-#{status.id}"]

) %>

</p>

<% end %>

(Ceci est un exemple sans aucun rapport avec le reste).

Problème(s) rencontré(s) :

  1. Aucuns

Solution(s) apportée(s) :

  1. Aucunes

Source(s) solution(s) :

  1. Aucunes

1.8 Phases de Test

Enfin pour finir, nous testons le bon fonctionnement de notre application via des scripts de test pré exécutables par Ruby On Rails. On peut effectuer des tests Unitaires, Fonctionnels, … Ici nous ne verrons que les tests fonctionnels.

Les tests sont contenus dans le fichier plugins/mon_plugin/test/functional/polls_controller_test.rb

Y inscrire les tests à effectuer, ex :

require File.expand_path('../../test_helper', __FILE__)

class PollsControllerTest < ActionController::TestCase

def test_index

get :index, :project_id => 1

assert_response :redirect

assert_template 'index'

end

end

Initialiser la base de test :

$ rake db:drop db:create db:migrate redmine:plugins:migrate redmine:load_default_data RAILS_ENV=test

NOTE : Erreur 1

Lancer le test :

$ bundle exec ruby plugins/mon_plugin/test/functional/polls_controller_test.rb

NOTE : Multiples erreurs possibles … (2, 3, 4, 5, 6)

Après résolution des erreurs depuis la section Solutions Apportées (voir ci-dessous), la commande devrait dorénavant fonctionner

Problème(s) rencontré(s) :

1. Error: unknown attribute 'issues_visibility' for Role.
2. `require': cannot load such file -- mocha/setup (LoadError)

3. `rescue in block (2 levels) in require': There was an error while trying to load the gem 'mocha'. (Bundler::GemRequireError)
Gem Load Error is: method `run' not defined in Minitest::Unit::TestCase

4. /usr/local/lib/ruby/gems/2.3.0/gems/bundler-1.14.6/lib/bundler/runtime.rb:40:in `block in setup': You have already activated mocha 1.2.1, but your Gemfile requires mocha 0.12.10. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)

5. Warning : *** Mocha deprecation warning: Change `require 'mocha'` to `require 'mocha/setup'`.

6. expecting <"index"> but rendering with <[]>

Solution(s) apportée(s) :

  1. Aucunes (Pas trouvé de solutions)
  2. Lancer la commande
$ bundle install --with test
  1. Dans le Gemfile, écrire :
require "rubygems"

gem "mocha", "~> 0.13.0"

require 'minitest/autorun'

$ bundle install
  1. Désinstaller la mauvaise version de mocha (1.2.1) via la commande :
$ sudo gem uninstall mocha
  1. Modifier dans le Gemfile :
gem "mocha", "~> 0.13.0", :require => false
  1. Aucune solution pour le moment …

Source(s) solution(s) :

  1. Aucunes
  2. Aucunes
  3. https://github.com/freerange/mocha

https://github.com/freerange/mocha/issues/187

  1. http://stackoverflow.com/questions/6317980/you-have-already-activated-x-but-your-gemfile-requires-y
  2. http://jamesmead.org/blog/2013-01-24-using-mocha-with-rails-3-and-minitest
  3. Aucune

2. Durée de développement

En raison du peu d’explication et du manque d’adaptation du tutoriel, le développement de ce module a duré 2 jours.

3. Commentaires supplémentaires

Le tutoriel officiel de création de plugin RedMine n’est pas adapté à RedMine 3.3.3.
De plus, celui-ci contient de nombreuses erreurs, ce que n’a pas aidé son déroulement.

Il est fortement recommandé d’utiliser à la place l’article [CREATION_PLUGIN_REDMINE] qui contient de plus amples explications, ainsi que plus d’exemples pour des cas différents (surcharges de méthodes déjà existantes dans le cœur de l’application par exemple).

Auteur : Alexandre BOUDINE