Tutoriel : écrire un add-on pour BlueMind

Vous voilà donc avec votre beau BlueMind flambant neuf. Vous avez entendu parler de notre grand plan d’architecture, des possibilités d’extension, de la plateforme p2, de l’API REST, mais vous ne savez pas par où commencer. Réjouissez-vous ! Cet article a été écrit pour vous !

Il vous faut juste connaître un peu de java et être plus ou moins familier avec Maven.

Objectif : une simple tâche planifiée.

Notre add-on sera une tâche planifiée.
Vous pouvez voir le gestionnaire des tâches de BlueMind comme un CRON interne, qui va exécuter les tâches au moment où elles sont programmées, ce qui est plutôt pratique pour vous assister dans l’administration de votre serveur.

Cette tâche va loguer quelques statistiques – en gros, nous allons faire un placeholder pour montrer comment faire tourner les briques de l’API REST ensemble. Faire quelque chose de plus significatif vous sera laissé comme exercice 🙂

Votre tâche planifiée listera les appareils mobiles de tous les utilisateurs pour tous les domaines gérés par votre serveur BlueMind. Simplement parce que c’est possible. Nous l’appellerons MobileDevicesListingJob.

Prudence est mère de sûreté

N’oubliez pas que lorsque vous utilisez l’API REST avec un serveur BlueMind, vous traitez de vraies données d’utilisateurs et il est plutôt facile de faire des erreurs puisque tout ce que vous pouvez faire dans BlueMind peut être fait via l’API REST. Il n’y aura pas d’écran de confirmation comme lorsque vous utilisez la console d’administration : si vous avez un doute, alors ne faites pas. Ou mieux : faites vos tests sur un serveur d’entraînement. Nous ne modifierons pas de données dans ce tutoriel afin de ne pas prendre de risque, mais soyez averti.

Amorcer un projet maven

Si vous jetez un coup d’œil aux entrailles de BlueMind, vous verrez des bundles OSGi partout.

Comme nous voulons faire un add-on BlueMind, nous dépendons de la plateforme cible. Cette plateforme est publiée en tant que dépôt p2, vous pouvez la trouver à cette adresse : http://pkg.blue-mind.net/p2/latest/
Comme on peut le voir dans l’URL, il s’agit de la dernière et de la plus importante plateforme cible de BlueMind. Elle est mise à jour à chaque fois que nous publions une nouvelle version de BlueMind – avec un peu de chance les mises à niveau ne casserons pas votre travail.

Nous utiliserons Tycho, grâce auquel la construction de vos paquets avec maven est plus facile.

Vous trouverez ici la structure de projet de base. Téléchargez-là et extrayez l’archive quelque part.
Ce projet est réduit au strict minimum. Je ne vais pas rentrer dans les détails des fichiers de configuration, vu qu’ils ne sont pas spécifiques à BlueMind, mais je voudrais souligner deux points :

  • pom.xml contient la déclaration de l’emplacement de la plateforme cible de BlueMind
  • plugin.xml contient la déclaration du point d’extension que nous utiliserons, soit scheduledjob_provider, avec le nom de notre future classe java : org.example.mobiledeviceslistingjob.MobileDevicesListingJob

Le reste n’est que de la configuration standard.

Comme alternative, vous pouvez aussi utiliser notre plugin maven archetype pour démarrer votre projet. Ou cloner notre exemple bluemind-samples pour obtenir un add-on déjà existant à adapter.
Tous les chemins mènent à BlueMind. Ou Rome. Bref…

Dans le répertoire du projet, vous pouvez lancer :

mvn install

Et voilà !
Vous avez construit votre projet, mais il ne fonctionne pas encore : il n’y a pas de code.

Eclipse à la rescousse

Vous pourriez continuer à écrire votre code java dans votre éditeur favori, mais voici comment le faire dans Eclipse :

  1. Importez votre projet maven dans votre espace de travail
  2. Indiquez à Eclipse la plateforme cible de BlueMind : allez dans Preferences, cherchez « Target Platform » et ajoutez une nouvelle définition de plateforme cible. Vous devez commencer avec une définition de cible vierge, choisissez un nom (par exemple tout simplement « BM target platform ») puis ajouter l’URL indiquée précédemment comme nouveau Software Site :

screenshot-from-2017-03-29-17-43-39

Sélectionnez tout (les cases « Uncategorized » dans l’écran ci-dessus), cliquez sur Finish et c’est fini ! Attention, vous devez sélectionner la plateforme cible que nous venons de créer avant de fermer la fenêtre Preferences.

Mettre en place les dépendances

Nous devons déclarer quelles parties de la plateforme cible de BlueMind nous utiliserons effectivement dans le fichier MANIFEST.MF. Notre documentation en ligne de l’API REST vous aidera à sélectionner les parties dont vous aurez besoin. Si vous avez installé le paquet optionnel bm-docs et donné la permission Api docs à votre utilisateur, cette documentation devrait être accessible directement dans BlueMind :

screenshot-from-2017-03-30-09-36-52

Cerise sur le gâteau : cette documentation en ligne est interactive, ainsi vous pouvez exécuter les appels depuis le client javascript. Attention, l’avertissement précédent s’applique toujours ! Et les dégâts que vous pourrez faire dépendront des droits accordés à l’utilisateur connecté.

Vous pouvez aussi trouver de l’inspiration dans le code source de BlueMind.

Voici les dépendances dont vous aurez besoin, ajoutez simplement ces lignes à la fin du fichier MANIFEST.MF :

Require-Bundle: net.bluemind.domain.api,
 net.bluemind.user.api,
 net.bluemind.device.api,
 net.bluemind.scheduledjob.scheduler,
 net.bluemind.core.rest,
 net.bluemind.slf4j
  • net.bluemind.*.api : les APIs REST servant à explorer les domaines, utilisateurs et appareils mobiles
  • net.bluemind.scheduledjob.scheduler : pour utiliser les extension points
  • net.bluemind.core.rest : pour mettre en place l’authentification à l’API REST
  • net.bluemind.slf4j : classes permettant de loguer – nous ne ferons guère plus que loguer quelques informations à la fin de la journée

Amusez-vous avec l’API REST

Alors, continuez et créez la classe que nous avons déclarée dans plugin.xml :  org.example.mobiledeviceslistingjob.MobileDevicesListingJob. Elle doit implémenter IScheduledJob pour scheduledjob_provider pour pouvoir se brancher dessus. Voici le code complet, je copie ici la logique métier seulement :

// logger will write in bm core logs (/var/log/bm/core.log)
logger.info("Executing MobileDevicesListingJob");
// sched will write in the execution report, that you can send by mail in the Job setup UI
sched.info(slot, "en", "Collecting mobile devices data for all users...\n");
// write header row for the data to come
sched.info(slot, "en", "device; isWipe; lastSync; user; domain");
// initialize client for domain service
IDomains domainService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM)
    .instance(IDomains.class);
// loop on all domains
domainService.all().stream().forEach(domain -> {
  // initialize client for user service
  IUser userService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM)
      .instance(IUser.class, domain.uid);
  // loop on all users
  userService.allUids().stream().forEach(userUID -> {
    // grab full details for user
    ItemValue<User> user = userService.getComplete(userUID);				
    // initialize device service for each user
    try {
      IDevice deviceService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM)
          .instance(IDevice.class, userUID);
      // loop on all devices
      deviceService.list().values.stream().forEach(device -> {
        // collect info for this device
        List<String> deviceInfo = new ArrayList<>();
        deviceInfo.add(device.displayName);
        deviceInfo.add(Boolean.toString(device.value.isWipe));
        deviceInfo.add(device.value.lastSync.toString());
        deviceInfo.add(user.displayName);
        deviceInfo.add(domain.displayName);
        // write a line in the report					
        sched.info(slot, "en", String.join("; ", deviceInfo));
      });;
    } catch (ServerFault exception){
      // Skipping this user since she doesn't have a "device" container
    }
  });
});

Déployer dans votre serveur BlueMind

Compilez votre code :

mvn clean install

Puis déposez le jar produit (target/org.example.mobiledeviceslistingjob-1.0.0-SNAPSHOT.jar) dans le dossier /usr/share/bm-core/extensions de votre serveur BlueMind.

Enfin, redémarrez le service bm-core :

/etc/init.d/bm-core restart

Votre tâche devrait apparaître parmi les tâches planifiées de la console d’administration. Vous pouvez l’exécuter, la programmer, envoyer le rapport à votre meilleur ami, elle est à vous !

Avertissement : si vous devez recompiler/redéployer votre extension, vous aurez peut-être besoin d’effacer le cache de bm-core pour vous assurer que la dernière version du jar est utilisée :

rm -Rf /var/lib/bm-core

Parler REST depuis le monde extérieur

Vous avez remarqué que nous avons utilisé un fournisseur de service ServerSideServiceProvider pour initialiser les services de l’API REST, mais vous pouvez bien sûr parler REST depuis l’extérieur, par exemple en utilisant un client python. Pour cela il vous faudra une clef d’API BlueMind.

Partagez votre travail !

Ne vous embêtez pas à partager votre MobileDevicesListingJob. En revanche une fois que vous aurez fait quelque chose d’utile vous pourrez le partager sur le MarketPlace BlueMind. Nous attendons avec impatience vos contributions !

Enregistrer

Enregistrer

Enregistrer

Enregistrer

Enregistrer

Enregistrer

Enregistrer

Enregistrer

Enregistrer

Suivez nous :

Suggestion Box – le self service des nouvelles fonctionnalités

En tant qu’éditeur, notre rôle consiste à prendre en compte les attentes de nos utilisateurs et de faire évoluer notre produit afin de répondre à ces attentes.

La particularité est que BlueMind est un logiciel OpenSource, et donc ouvert par définition. Cependant, cette ouverture peut nuire à la bonne organisation du développement.

Très vite, le succès du produit nous a apporté énormément de retours fonctionnels ou techniques. Et il a fallu nous organiser afin de traiter ces demandes.

Business model

Avant de partir dans le vif du sujet, il est important de comprendre notre métier d’éditeur, le modèle économique choisi par BlueMind, et ces impacts sur notre organisation.

Nous sommes éditeurs, et à ce titre, nous nous concentrons sur le développement du logiciel, l’amélioration du produit, l’interconnexion avec des partenaires technologiques. Nous visons un marché qui ne se cantonne pas à un pays ou à un métier particulier. Aujourd’hui tout le monde a besoin d’une messagerie, et BlueMind permet de répondre à ce besoin que l’on soit une PME, une ETI, ou une multinationale.

Afin de parvenir à couvrir un marché mondial, nous travaillons avec un réseau de distribution via des partenaires qui sont en charge de réaliser les projets chez nos clients, et/ou mettre en place des plate-formes SAAS.

Via notre réseau de partenaires, nous pouvons ainsi atteindre beaucoup plus de clients potentiels.

Cela a deux conséquences :

  • issus pour la plupart de nos partenaires, nous ne connaissons pas tous nos clients
  • et nous aurons de plus en plus de clients

Cela impose de mettre en place des outils et méthodes permettant de recueillir les attentes de nos clients et de les traiter le mieux possible.

Organisation du développement

Si l’on parle au sens DevOps et notamment en regardant ce schéma de nos confrères de Normation, du développement d’une application à la mise en place en production, deux parties sont présentes, le BUILD et le RUN.

Le rôle d’un éditeur est le BUILD, et donc de traiter les besoins métiers pour créer des “binaires applicatifs”. Au sens méthodes agiles, les besoins métiers peuvent prendre plusieurs formes (stories, epics, …)

L’équipe R&D de BlueMind travaille depuis la naissance du produit avec des méthodes agiles, permettant de développer des fonctionnalités rapidement, dans un contexte précis. Toute une batterie d’automatisation et de tests est en place et permet de distribuer rapidement une nouvelle version avec de nouvelles fonctionnalités.

Le problème analysé dans cet article est l’abondance des besoins métiers : comment les traiter pour alimenter convenablement la R&D ?

Gestion des besoins métiers

Mais pourquoi les gérer ? On nous demande quelques choses et on le fait !

Cela resterait simple si seulement nous avions des ressources infinies et que toutes ces demandes étaient cohérentes entre elles et avec notre vision. En attendant, il faut trier, sélectionner les demandes pour enrichir une Roadmap avec un ensemble de features qui iront dans un Backlog.

Le backlog va contenir un ensemble de fonctionnalités qui devra être trié et validé par le Product Owner, les premières du backlog devant être traitées en priorité par l’équipe R&D.

Processus simple de qualification

Nous avions mis en place un processus simple de qualification d’une feature (jeunes padawan que nous étions!), simple et complet.

  1. comprendre le besoin
  2. valider ou pas la demande
  3. rechercher les doublons (qui vous dit que d’autres utilisateurs n’ont pas fait exactement (ou pas exactement d’ailleurs) la même demande !)
  4. créer une story pour le backlog
  5. la positionnner dans le backlog en fonction de la priorité décidée par le Product Owner
  6. la rattacher à une Epic, si cette story est trop volumineuse

En théorie, nous avons donc « seulement«  6 étapes pour trier une demande de fonctionnalité.

Cette méthode qui semble simple, vient se compliquer quand vous avez un afflux important de demandes (décrites par des personnes qui ne sont pas forcément clientes, que vous ne connaissez pas, avec leur vocabulaire et leurs attentes –souvent un peu spécifiques), et des fonctionnalités qui s’accumulent dans votre backlog. Rechercher un doublon peut être long dans une centaine de features…

L’afflux de demandes dans notre cas se fait via plusieurs canaux :

  • les clients finaux
  • les partenaires
  • en interne (les développeurs, les commerciaux, les avants vendeurs…)
  • la communauté utilisatrice du logiciel

Et on voit bien que cela commence à faire potentiellement beaucoup de personnes qui ont des demandes fonctionnelles à nous remonter.

people

Tout le monde a un besoin qu’il juge générique (alors que souvent il ne l’est pas…), qui n’est pas toujours exprimé de la façon la plus évidente et tout le monde considère sa fonctionnalité comme indispensable dans son logiciel de tous les jours !

Notre backlog : en jachère

En janvier 2015, l’état du backlog était le suivant :

  • 140 feature non triées
  • 470 stories dans le backlog

avec parmi ces stories :

  • certaines importantes (la mise en place d’une fonctionnalité majeure et structurante)
  • des stories moins importantes (l’évolution d’une fonctionnalité déjà présente par exemple)
  • certaines petites, mais légitimes (possibilité de trier une colonne : faisable, intéressant, mais est-ce prioritaire ?)
  • d’autres, insignifiantes, voire polluantes (avec tout le respect que j’ai pour nos utilisateurs : “le bouton serait mieux en jaune”)

Le problème principal ne vient pas directement de l’afflux de features, mais plutôt de la façon de traiter et de créer ces features.

Comme dans tous les projets informatiques, nous avons mis en place un bug tracker. Dans la majorité des bug trackers (pour ne pas dire la totalité à ma connaissance), les traitements d’un bug et d’une feature sont presque équivalents (par défaut). Nous avons le plus souvent un formulaire de demande quasi identique et un menu déroulant permettant de qualifier une “issue” en “bug” ou en “New feature”.

7-differences

Le véritable problème est là : un Bug n’est pas une feature ! Ce sont deux traitements différents, avec des objectifs différents !

Malheureusement, dans les bug trackers, la frontière entre un bug et une feature n’est pas assez claire.

L’utilisateur qui crée une feature se retrouve dans le même niveau d’attente (voire d’exigence) qu’un bug, ce qui ne doit pas être le cas.

Un bug :

  • doit avoir des délais de résolution, et suivant le service offert, doit respecter une SLA
  • doit être corrigé. C’est un dysfonctionnement qui doit entrer dans un cycle de correction.
  • a un workflow précis permettant de suivre son évolution ( ouvert, en attente de retours, corrigé, déployé, “won’t fix”…)
  • a une criticité
  • impacte sensiblement les utilisateurs, qui veulent être informés des avancées.

Une feature :

  • est une demande d’évolution
  • n’a pas (contractuellement) de deadline
  • n’a pas (contractuellement)  de criticité
  • n’oblige pas à un feedback vers les utilisateurs
  • peut être prise en compte, acceptée… ou pas

Ainsi, par la nature même d’un bug ou d’une feature, leur traitement est complètement différent.

La Suggestion Boxlogo-sb

Nous avons donc décidé de fonctionner autrement, de reconsidérer totalement le traitement des fonctionnalités. Premièrement, nous n’allons plus parler de “new features” ou fonctionnalités : nous parlerons dorénavant de suggestions.

Dans notre analyse, nous avons compris que pour optimiser le traitement des “demandes de suggestions”, il est important  que le besoin soit le mieux décrit, le mieux qualifié possible par le demandeur lui-même.

Le problème n’est pas, à ce stade, technique ! Mais comment arriver à pousser les “demandeurs” à être actifs ? Le vocabulaire utilisé est important, et commence déjà à conditionner l’utilisateur :

  • l’utilisateur va « suggérer » et non pas « exiger » !
  • le « Je veux » devient un, “je vous propose”, “j’aimerais, un jour”

C’est donc sur cette base que nous avons créé La Suggestion Box, une interface dédiée permettant principalement la consultation des suggestions existantes.

Du mérite et de la discipline

La suggestion box doit inciter ses utilisateurs à se poser plusieurs questions avant de proposer sa suggestion :

Questions fonctionnelles :

  • à quoi sert et que devra faire ma proposition de fonctionnalité ?
  • quels sont les impacts de cette fonctionnalité sur le logiciel BlueMind en général ?

Questions organisationnelles :

  • Est-ce qu’un autre utilisateur a déjà fait une telle demande ?
  • Ou est-ce qu’une suggestion existante s’en rapproche ?

Si la création d’une suggestion est immédiate, nous n’aidons pas nos utilisateurs à réfléchir à leurs attentes. Ainsi chaque besoin va finir en demande, sans analyse en amont. Et ce travail devra tout de même être réalisé, avant de passer une feature en story (découpage réalisable d’une fonctionnalité).

C’était exactement ce qui se passait quand on autorisait la création d’une “new feature” dans un bug tracker: “ je n’ai qu’une liste déroulante à choisir et un titre à remplir”…

Nous devons donc guider les utilisateurs dans leur démarche, via un self-service de la suggestion : la suggestion box !

Comment

La suggestion Box a été créée suivant les spécifications suivantes, volontairement simples pour ne pas alourdir la démarche :

blueprint-suggestionbox

  • La recherche :
    La recherche est importante, puisque nous sommes sur une interface de consultation des suggestions. Il nous faut donc une recherche performante.
  • Pas de création sans recherche :
    pour inciter les utilisateurs à rechercher une demande similaire,  il n’est pas possible de créer une suggestion depuis la page d’accueil. La création est autorisée si seulement une recherche ne donne pas le résultat attendu. En l’absence de résultat probant, la création de suggestion devient possible.
  • Catégorie :
    Toujours dans le but de donner un maximum d’information, la suggestion doit être catégorisée, afin de permettre des regroupements logiques et de faciliter la recherche.
  • Votes :
    les votes vont permettre d’ordonner les demandes. Il devient ainsi facile d’identifier quelles sont les demandes les plus populaires.
  • Commentaires :
    Si une demande se rapproche d’une suggestion déjà existante, les commentaires permettent de donner une autre vision de la suggestion et de débattre de celle-ci, plutôt que d’en créer une autre. En effet, il vaut mieux enrichir une demande existante qui se rapproche de la sienne plutôt que d’en créer une autre : cela permet de cumuler plus de votes.
  • Aucun statut :
    Le but est de laisser évoluer la suggestion par la communauté d’utilisateurs, afin qu’elle s’affine, se précise et réponde aux attentes du plus grand nombre. À tout moment, quelqu’un peut rajouter un commentaire et enrichir sa vision, sans contrainte de temps. BlueMind s’en empare au moment opportun, la marque en « acceptée » pour rédiger les spécifications finales et réaliser la suggestion.

Comment BlueMind utilise la Suggestion Box

Établir la RoadMap d’un logiciel est le travail d’un éditeur. La suggestion box est un élément parmi d’autres afin de construire une RoadMap. La suggestion Box n’est pas la source absolue de la RoadMap, mais va compléter les retours et chantiers internes que nous avons prévu de faire.

Le nombre de votes d’une suggestion permet de connaître la popularité d’une demande. Cependant, BlueMind peut faire le choix de ne pas prioriser une suggestion qui se retrouve avec un nombre de votes important et privilégier plutôt une suggestion moins populaire.

En effet, pour des raisons techniques, d’organisation, de cohérence ou de choix stratégiques, c’est toujours le Product Owner qui prend la décision finale du contenu d’un sprint R&D.

De plus, les tâches “internes” non demandées par les utilisateurs (changement d’API, de librairie de dév..) peuvent être priorisées afin de prévoir dans un second temps un possible développement d’une fonctionnalité avancée.

Une fois qu’il a était décidé de faire évoluer un composant (calendrier, administration, contact…), la suggestion box est mise à contribution afin de connaître les attentes de nos utilisateurs, et de voir ce qu’il est possible de faire évoluer en fonction des différentes contraintes.

La catégorisation de la suggestion box permet ainsi de limiter l’analyse des suggestions au module que nous souhaitons faire évoluer.

Bilan

Deux ans après la mise en service de la Suggestion Box, le retour est extrêmement positif.

Actuellement nous avons un backlog avec 78 stories découpées en 22 EPIC  alors qu’auparavant, nous nous battions avec 470 stories dans le backlog plus 170 features non analysées.

La suggestion BOX regroupe 224 suggestions, 662 votes ont été effectués, répartis sur 134 suggestions. 50 suggestions ont été réalisées, certaines avec beaucoup de votes (jusqu’à 46), certaines avec beaucoup moins de votes, mais jugées prioritaires.

Informations Complémentaires

La suggestion Box de BlueMind se trouve à cette adresse https://community.bluemind.net/suggestions/

Notre développement est OpenSource, et vous pouvez trouver toutes les informations que vous voulez sur ce projet directement sur http://www.suggestion-box.io

La naissance de la suggestion Box est issue de discussions et réflexions interne notamment avec Dominique Eav, notre responsable qualité, aussi auteur du développement de la Suggestion Box.

Et bien sûr, comme nous faisons évoluer la suggestion box, vous pouvez aussi créer une suggestion pour la Suggestion Box !

Enregistrer

Enregistrer

Enregistrer

Suivez nous :