Espace de fouille

La zone de fouille technologique java-jEE, M2M, noSQL…

Bien des fois, le design de processus est une tâche si ardue qu’elle finit souvent par un vrai sac de noeuds bon à jeter. Cet article tente d’adresser cette problématique en viennant compléter le post du 29 novembre 2011 : « où commencer son processus ?«  et propose une méthode de conception qui, je l’espère, vous permettra de concevoir un processus avec Bonita Open Solution aisément et rapidement.

1. Formalisation du métier

Un processus fait souvent intervenir différents acteurs et il peut être difficile d’extirper qui fait quoi et quand.

La première étape consiste donc à identifier clairement quels sont les différents profils qui interviendront dans le workflow. Une fois cette liste établie, l’étape suivante s’attaque aux processus vus par chaque acteur.Ainsi, on commence par établir le chemin le plus long de façon informelle : le « happy path ».

Ici, différentes tâches vont apparaître. Pour chaque tâche, il va falloir établir de façon claire et précise :

  • Les évènements déclencheurs de l’action. Le plus souvent, ce sera la fin de l’étape précédente, mais cela peut être des évènements basés sur le temps, ou même une information envoyée par un autre processus, …
  • Le produit résultat de l’étape : quel est le livrable de l’action effectuée à cette étape ? Qu’est-ce que l’on cherche à obtenir, pourquoi est-ce que cette étape est nécessaire : en quoi est-ce qu’elle résulte ?
  • Les ressources requises en plus que le profil acteur de cette tâche : quels sont les outils dont il va avoir besoin, est-ce qu’il va devoir travailler avec quelqu’un d’autre, … En bref, tout ce qui existe avant la tâche, ce qui sera utilisé pendant la tâche, mais se retrouvera intact après son exécution.
  • Les informations et produits nécessaires à l’établissement de l’activité. Ces produits seront consommés et éventuellement modifiés en le produit résultat.
  • Identifier l’activité en tant que tel et quel est l’évènement provoqué : quel est l’objectif de la tâche et la décision qui en résulte. Une bonne convention de nommage est ici de nommer une activité par un verbe d’action à l’infinitif et un produit résultat. « Saisir les informations », « Ouvrir un ticket », « Acheter bouteille de lait », …

Une fois que toutes les tâches de ce happy path ont été spécifiées, il convient de traiter tous les chemins alternatifs en partant de la fin du processus. Soit, pour chaque étape depuis en partant de l’évenement de terminaison, est-ce que j’ai une décision alternative possible ? Un chemin d’exception, … Si la réponse est oui, ce chemin alternatif devient le nouveau chemin le plus long à clarifier comme défini précédemment.

A ce point, nous aurons pour chaque profil d’acteur une liste de micro processus qu’il va falloir agréger et dans un sens cartographier pour obtenir un design clair, précis et configurable…

2. Configuration du ou des processus

Plus haut, nous avons établi l’ensemble des connaissances, des informations qui étaient nécessaires à l’exécution des tâches, et les décisions en résultant.

Toutes ces informations ne sont pas nécessaires à l’avancée de notre processus. Il s’agit pour la plupart de données métier dont le processus et sa logique n’ont que faire. L’étape suivante consiste donc à identifier clairement les informations nécessaires au processus pour les modéliser et donner au processus cette connaissance.

Ainsi, il convient de créer les conteneurs pour ces données (les variables) et les éventuels connecteurs nécessaires à leur manipulation. Le processus peut, dans certains cas, nécessiter des actions sur des services externes. Il est maintenant nécessaire d’établir ces connexions et donner au processus la connaissance nécessaire à ce que ses activités automatiques soient réalisées correctement.

A ce moment, notre processus est prêt à être exécuté. Le problème : il n’a aucune interaction avec le métier et les utilisateurs ne peuvent pas effectivement travailler : c’est l’application métier au dessus du processus.

3. Développement de l’application métier

Pour chaque étape où un utilisateur doit interagir, il faut modéliser les écrans qu’il utilisera pour effectuer le travail qui lui est demandé. Il s’agit d’interfaces (web) qui serviront à saisir de l’information. Une saisie d’information doit répondre à des règles d’ergonomie et d’utilisabilité qu’il va falloir modéliser à partir des informations identifiées dans au premier point de notre méthode. Il s’agit du développement de la vue de notre application métier.

En parallèle, il est nécessaire de spécifier le modèle de données métier, les sources de données, et l’interaction qu’elles vont avoir entre elles. Une fois le modèle de données établi et les sources identifiées/créées, il ne reste plus qu’à connecter nos modèles de formulaires avec les données qui lui seront utiles.

A cette étape, notre processus est prêt à être utilisé, mais potentiellement moche et avec des temps de chargement non négligeables qui le rendent peu « user friendly ».

L’étape finale consiste donc à optimiser les performances là où nécessaire et à établir le look’n'feel final de notre application.

Le mot de la fin

Le développement d’un processus comprend trois grandes étapes consécutives : la spécification de la façon de travailler (1), la configuration du processus pour qu’il puisse s’exécuter (2) et le développement des interfaces utilisateur (3).

L’expérience montre que l’étape 1 semble souvent assez rapide à mettre en place mais nécessite hélas un travail de spécification non négligeable et très souvent mal évalué. L’étape 2 est souvent la plus rapide car elle est presque automatique. L’étape 3 est souvent le plus gros développement d’un projet où l’on fait face à des détails souvent négligeables et pourtant si problématiques… Comme on le dit souvent : le client est roi, alors soignons ce que nos utilisateurs voient tous les jours.

Très souvent, on en vient à se demander où commencer son processus, par quel bout prendre notre projet pour avoir une modélisation aisée et rapide. Cet article tente de répertorier plusieurs idées qui peuvent permettre de débuter sans trop de heurts pour aboutir rapidement à un prototype fonctionnel.

Qu’est-ce que l’on manipule ?

Un processus a pour objet la manipulation d’une notion métier. Plus loin, un processus sert à traiter une action sur un objet métier. Par exemple, dans le cadre de l’organisation d’une formation, nous pourrions avoir les processus suivants :

  • enregistrer une nouvelle formation,
  • enregistrer un nouveau participant à une session donnée,
  • suivre le payement d’un participant,

Chaque cas, chaque instance de processus représente une session de formation, un stagiaire, une facture, … qui interagissent ensembles pour former un projet global : la gestion des formations.

On commence où ? On obtient quoi ?

A partir de l’idée qu’un processus représente une action sur une notion métier, il convient de se demander où l’on commence le design.

L’idée principale là derrière, c’est que le cas est créé par un évènement métier bien défini. Par exemple, le cas (l’instance de processus) d’enregistrement du stagiaire M. Dupont est créé par son enregistrement sur le site web.

Et qu’est-ce qui termine le processus ? Un processus a un objectif métier, un état de l’objet métier manipulé. Pour notre enregistrement par exemple, ce sera une fin de processus « stagiaire enregistré », « stagiaire refusé », …  Les fins de notre processus correspondent donc à ces états vers lesquels nous arrivons. Ainsi, il n’est pas rare qu’un processus puisse avoir plusieurs fins, suivant l’état obtenu.

Et la gestion des risques dans tout ça ?

Un processus peut être vu comme la standardisation d’un projet récurrent. En gestion de projet, nous avons plusieurs façons de gérer les risques :

  • Tout se passe bien dans le meilleur des mondes, on ignore tout bonnement le risque : rien n’apparaît
  • On se débrouille pour ne jamais tomber dans le risque que l’on a identifié, auquel cas, la gestion de ce risque apparaîtra dans notre modèle
  • On identifie le risque et on le traite de façon exceptionnelle.

Ce dernier cas est ce que l’on pourrait qualifier d’erreur métier, notion qui est disponible dans la norme BPMN2 par exemple. Une erreur métier correspond à un risque identifié qui, s’il se produit, place mon cas dans un état d’erreur. Auquel cas, cette erreur est identifiée et il convient de définir un traitement particulier.

Mais une erreur métier, ça représente quoi exactement ? De base, il y en a de deux types :

  • une erreur qui survient au niveau technique et que l’on remonte au niveau métier. C’est le cas par exemple du cas où l’on doit récupérer l’information à traiter d’une base de donnée, mais que cette base de donnée est inaccessible, auquel cas, il faut définir une autre stratégie alternative de récupération de données, si elle est possible…
  • une erreur qui survient par le métier et impacte le métier. Par exemple, lors de la session de formation où le stagiaire ne se présente pas le premier jour.

Et comment prévoir l’imprévisible ?

Avant tout, rester pragmatique. Un processus est là pour automatiser la gestion de plusieurs cas. Si l’on traite 70% des cas, c’est déjà bien. La question, que fait on des cas restants ?
Est-ce pertinent de traiter ces cas d’exception alors qu’ils n’interviennent qu’une fois tous les 10 ans ? Le retour sur investissement d’un tel développement est loin d’être évident. Auquel cas, autant ne pas le modéliser et agir le moment venu.

Oui, mais… J’ai un processus qui automatise tout mon système. Comment est-ce que je peux agir manuellement là où tout est automatisé ? Comment faites vous avec vos systèmes existants ? En général, vous décrochez votre téléphone pour le service informatique pour qu’il traite l’information exceptionnelle. Là c’est pareil, mais cela nécessite de concevoir vos processus de telle façon qu’il vous sera toujours possible de traiter ces cas d’exception.

Voici quelques idées qui pourraient vous aider :

  • Utiliser une base de donnée métier : ne pas stocker l’information dans le processus mais dans une base métier. Cela a aussi l’avantage de rendre ces données accessibles de l’extérieur
  • Utiliser des processus simples : c’est exactement ce que l’on disait en première partie, un processus par action sur un objet métier
  • Rester sur des processus le plus linéaires possibles. Après tout, la logistique nous apprend qu’un processus est une série d’actions qui débouchent sur un objectif métier précis, que si l’on traite les chemins alternatifs, on passe dans une gestion de projet, discipline beaucoup plus complexe

Ces quelques principes de base pourront, je l’espère, vous permettre de concevoir rapidement des processus utilisables, simples à maintenir, mais surtout, qui n’aboutissent pas à des plat de spaghetti. Revenir sur ces principes de base lorsque l’on commence à perdre pied, c’est souvent une façon de redevenir pragmatique et trouver une issue simple et rapide à la trop forte complexité dans laquelle nous nous égarons trop souvent.

Les recorders sont un service du moteur de Bonita qui permettent de d’enregistrer les différents évènements du moteur. Dans les grandes lignes, il s’agit simplement d’implémenter un service bonita pour écouter ce qui nous intéresse et y réagir en conséquence. L’implémentation par défaut fournie par Bonita est de stocker l’état Bonita dans la base de donnée journal. Une utilité étendue que l’on peut envisager à la première pensée est le log (savoir quand une tâche est démarrée, lorsque des acteurs sont assignés et qui ils sont, …). Ensuite, d’autres utilisations plus originales peut être envisagées comme envoyer un email aux candidats de chaque tâche créée.

Mettons donc les mains dans le cambouis.

La configuration

Les services du moteur se configurent dans le fichier bonita/server/default/conf/bonita-server.xml. Les recorders se chainent par leur déclaration dans la section chainer d’identifiant recorder.

<chainer name='recorder'>
    <!-- Implémentation des recorders à utiliser -->
    <ref object='journal' />
</chainer>

Et un recorder (disons org.jaalon.MyRecorder) se déclare ainsi :

<recorder class='org.jaalon.MyRecorder'>
    <arg><string value='un parametre' ></arg>
</recorder>

Et le code dans tout ça ?

Le code, c’est pas bien compliqué. La seule dépendance requise est le bonita-server-<version>.jar

Un recorder implémente la classe org.ow2.bonita.services.Recorder. Chaque méthode représente un évènement qui peut survenir dans le moteur ; son corps, le traitement correspondant.

public class MyRecorder implements Recorder {
  /* code du recorder */
}

Les paramètres de configuration fournis sont récupérés par le constructeur, par exemple, pour notre configuration plus haut

  String message;
  public MyRecorder (String message) {
    this.message = message;
  }

Et réagir à un évènement ? Il s’agit simplement d’implémenter la méthode qui nous intéresse, par exemple, pour logger le fait qu’une instance est prête :

  public void recordTaskReady(ActivityInstanceUUID uuid, Set candidates,
                              String userId) {
    LOG.log(Level.INFO, "Activity "+uuid+" is ready");
  }

Et l’accès au moteur me direz vous ? Ici, il n’est plus rentable d’utiliser l’API publique du moteur, mais passer par l’environnement du moteur et manipuler les objets directement depuis l’intérieur. Tout se fait en passant par l’EnvTool. Pour certains cas, les méthodes accessibles à partir de l’API publique peuvent être pratiques, alors on utiliserait ici l’accesseur renvoyé par LocalAPIAccessorFactory.getStandardServerAPIAccessor()

Ainsi, pour récupérer la valeur d’une variable par exemple :

EnvTool.getAllQueriers().getProcessInstance(processUUID).getLastKnownVariableValues().get("myVariableName");

Ce document explique sommairement comment établir un serveur pour partager des ressources REST.

Un webservice simple

Voici le code d’un service simple qui permet d’afficher « coucou » via un GET en se basant sur JAX-RS.

import javax.ws.rs.GET;
import javax.ws.rs.Path;
 
public class Resource {
	@GET
	@Path("/test")
	public String test() {
		return "coucou";
	}
}

Exposer une resource

Il convient maintenant d’exposer cette ressource à l’aide de cxf. Pour cela, les étapes les plus simples sont les suivantes :

  1. Tout débute par la création d’un JAXRSServerFactoryBean : une fabrique de serveur REST
  2. Il faut ensuite exposer la resource à l’aide de la resource à l’aide de  la méthode setResourceClasses
  3. Il ne reste qu’à demander au serveur d’écouter avant de le créer.
Cela donne le code suivant :
public class startJetty {
	public static void main(String args[]) {
		JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
 
		sf.setResourceClasses(Resource.class);
		sf.setAddress("http://localhost:9080/");
		sf.create();
 
	}
}

Compiler et lancer

La seule chose à faire maintenant est de construire un pom.xml maven avec les dépendances nécessaires :

  <dependencies>
    <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxrs</artifactId>
    <version>2.5.0</version>
  </dependency>
  <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-jetty</artifactId>
    <version>2.5.0</version>
  </dependency>
</dependencies>

Le projet se lance maintenant avec la commande :

mvn exec:java -Dexec.mainClass="org.jaalon.simpleJettyServer.startJetty"

Jboss Drools est un moteur de règles métier intéressant mais l’aborder semble une tâche ardue. Plutôt que de se laisser intimider, plongeons la tête la première dans l’outil, de son téléchargement à son utilisation, jusqu’à ce qui m’intéresse en dernier lieu : le piloter avec Bonita.

Où commencer ?

Sur http://www.jboss.org/drools. Ici, nous avons visiblement le choix entre 5 projets :

  • Drools Guvnor : pour la gestion des règles métier
  • Drools Expert : le moteur de règles
  • jBPM 5 : le BPMS de jboss
  • Dools Fusion : pour la gestion d’évènements métier. Cela semble s’apparenter à un bus d’évèments
  • Drools planner : un plannificateur automatique (recherche opérationnelle inside :))
Je pense que pour commencer, Drools guvnor est la bonne solution :
Guvnor is the web application and repository to govern Drools and jBPM assets

Téléchargement effectué, que nous réserve le manuel de référence ?
Le quickstart tour part du principe que l’installation de drools a été effectuée donc …

Installation de Drools Guvnor

A l’heure où j’écris ces lignes, la dernière version stable est la 5.2.0, donc c’est sur l’installation de cette version que nous allons couvrir. RDV au chapitre 13 du manuel de référence.

Guvnor est fourni comme un fichier .war, déployons le sous un apache tomcat. Dans les grandes lignes :

  1. Télécharger et extraire une archive de tomcat (disons la dernière version 6 stable)
  2. Copier guvnot (binaries/guvnor-5.2.0.Final-tomcat-6.0.war) dans le dossier webapps de tomcat
  3. Lancer le tomcat
  4. Se connecter à http://localhost:8080/guvnor (j’ai renommé le fichier .war en guvnor.war pour me simplifier la vie)

Et installons un dépôt d’exemple en cliquant au prompt sur « Yes, please install samples »

L’exemple vient avec un modèle et un ensemble de règles pour nous aider à prendre en main l’outil. L’interface présente à gauche les grandes fonctionnalités, ici seule l’administration et la base de connaissance (knowledge base) nous intéressent pour l’instant.

Nous avons à l’heure actuelle une configuration de base sur le projet exemple, cependant, pour un cas réel, il nous faut une configuration de base et écrire des règles. Ainsi :

Configuration de base

  1. Créer une catégorie pour le projet (administration->categories)
  2. Créer un package pour le projet (knowledge base->create new->package)
  3. Uploader le modèle de données (une librairie java .jar)

Nous sommes maintenant prêt à définir nos règles métier

Ecrire des règles

  1. Dans knowledge base : create new->new rule
  2. Définir un nom pour la règle
  3. Définir une catégorie (un tag)
  4. Etablir une règle métier à l’aide du DSL correspondant

Ces quelques lignes se sont concentrées sur les grands composants de Drools, ainsi que l’installation du moteur de règle métier et l’interface utilisateur par défaut.
D’autres articles seront à venir sur le vocabulaire intrasèque à Drools et son utilité réelle, sur des exemples concrets d’utilisation et sur l’utilité d’un moteur de règle en relation avec un BPMS. Bien entendu, au fur et à mesure que l’on plongera dans l’exploration du domaine des règles métier, nous rentrerons plus en détail dans les choses techniques qui régissent l’outil.

Mercurial (hg pour les intimes) est un outil de gestion de sources distribué à l’instar de git, développé en python. L’avantage que l’on peut lui trouver est sa simplicité d’utilisation, son port sur les systèmes d’exploitation les plus répandus et son extensibilité aisée.

Cet article a pour objet l’installation et la configuration de rhodecode, une application web permettant d’administrer de multiples dépôts mercurial.

Mise en place de rhodecode

Les manipulations ont été effectuées sur un serveur archlinux. Pour d’autres distributions/OS, la procédure reste équivalente.

Versions utilisées

  • mercurial mercurial 1.9.1
  • pip 1.0.2

Procédure

  1. Installer rhodecode
    pip install rhodecode
  2. Créer l’utilisateur rhodecode et se logger en tant que tel et créer le répertoire pour les dépôts
    useradd -m rhodecode
    su - rhodecode
    mkdir repos
  3. Créer le fichier de configuration
    paster make-config RhodeCode production.ini
  4. Configuration de base
    paster setup-app production.ini

Il ne reste alors plus qu’à lancer le serveur :

paster serve production.ini

Note importante : le serveur écoute en local sur le port 5000. Pour écouter à l’extérieur ou sur un autre port, deux solutions :

  1. Editer le fichier production.ini afin de changer l’IP et le port d’écoute
  2. Mettre en place un proxy http pour rediriger les requêtes

Liens utiles

  1. Mercurial
  2. RhodeCode

L’utilisation et la configuration des messages est souvent quelque chose de mal
compris par les utilisateurs de BOS. Le but de cet article est de
reprendre ces notions pour tenter d’éclaircir les choses.

Quelques rappels sur les messages

Les messages permettent à deux processus de communiquer entre eux, et
éventuellement faire transiter de l’information. Les propriétés des messages
sont les suivantes :

  • Un message est unique : une fois traité, le message est détruit
  • Un message doit avoir une cible unique : un message ne peut être envoyé qu’à
    un processus donné
  • Un message ne peut relier deux évènements du même processus

L’envoi et la réception de message se fait par l’intermédiaire d’évènements
d’envoi ou de réception de messages. L’envoi de messages peut se faire en
cours de processus ou en fin de processus. La réception peut intervenir en
cours d’exécution ou pour débuter un processus.

Evènements relatifs aux messages

 

 

 

Des tâches d’envoi et de réception de messages existent et agissent de la même façon que les évènements correspondants.

Tâches d'envoi et de réception de messages

 

 

 

L’évènement d’envoi de messages peut envoyer un ou plusieurs messages alors que
la réception ne peut traiter qu’un message donné. L’évènement de réception peut
éventuellement filtrer le message à traiter à l’aide d’une condition. cela
permet de cibler précisément le cas ciblé.

Configuration de l’envoi et la réception de messages

La première étape est de modéliser deux processus qui vont communiquer entre eux en faisant apparaître les évènements d’envoi et de réception de messages.

Ajout des évènements dans le diagramme

Il ne reste plus qu’à ajouter un message :

  • sélectionner l’évènement d’envoi de processus et dans les détails Général->Message
    Sélection de l'envoi de messages
  • Ajouter le message
  • configurer le message en définissant son nom, le processus cible ainsi que la tâche de réception

Configuration du message

Faire transiter les données

Pour faire transiter des données d’un processus l’un autre, il convient de
créer des variables locales au message pour copier la valeur qui nous intéresse.

En pratique :

Tout d’abord, il faut ajouter une variable locale au message en éditant le
message que l’on vient de créer :

Et de configurer la variable locale au message en l’initialisant avec la valeur
de la variable du processus émetteur

Ajout des données

A ce stade, le message contient la donnée qui nous intéresse, mais à la

réception, il nous reste à transférer cette valeur au processus cible. Pour
cela, il suffit d’utiliser un connecteur Bonita pour mettre à jour la ou les
variables correspondantes (set variable(s)) dans le processus cible :

  • Sélectionner l’évènement de réception du message

Réception évènement réception message

  • Ajouter un connecteur en allant dans l’onglet général->Connecteurs->Ajouter…

Connecteur mise à jour de variables

  • Puis configurer le connecteur avec le nom de la variable cible et la valeur à lui donner

Mise à jour de variables

4. Corrélation cas/message

 

J’en parlais en introduction, un message doit avoir un cas cible. Or, lors de
sa définition, il n’est précisé que le processus et la tâche cible. Le filtrage
sur le cas doit se faire dans l’évènement de réception de message avec la
condition de réception.
Cette condition permet de comparer une valeur contenue dans le message avec une
valeur du processus cible. Cela permet par exemple de s’assurer que le dossier
dont l’information est contenue dans le message est bien envoyé au cas affecté
à son traitement.

Pour effectuer la corrélation entre un cas et un message reçu :

  • sélectionner l’évènement de réception du message
  • paramétrer la condition de réception du message

Corrélation

Dernière revue de presse de l’année.

SQL + NoSQL = Yes !

Ivy resolves downloads but ignores some artifacts (though not modules)

123, go!

La revue de presse d’Henri: Semaine 51

Design for developers

Using JBoss Rules (Drools) in Scala

Object Database Programming with JPA and NetBeans

Java Interface Rules

Wish List: Java Object Replacement

J2EE is NOT Completely Dead Yet – but You Can Save Time and Money using JRebel

10 Effective Ways to Become a Good Programmer

Understanding Tomcat Configuration

Let’s Play TDD #71: Poking at Listeners

Architecture Lean – Penser grand, agir petit

Retour d’expérience Scrum appliqué à un repas de noël

TOTD #152: GlassFish Installer – Typical and Custom installation

Java Spotlight Podcast 9: Holiday Greetings 2010

REST Assured – Or how to easily test REST services in Java

IWST – Time management for testers

Introduction to Spring Roo

How To Complete Stories Without Leaving Bugs Behind

OpenGL ES Tutorial for Android – Part VI – Textures

Review of Crafting Rails Applications, by José Valim

Using PowerMock with Spring integration testing

NetBeans Platform Runtime Inspector

Using GlassFish v3.1 SSH Provisioning Commands

Java Spotlight Podcast 10: Java Duchess

Finding Kth Minimum (partial ordering) – Using Tournament Algorithm

Azul Puts the Zing in Java

Mobile HTML 5.0

Linda Rising on Customer Interaction Patterns

Gartner Vendor Report: Application Infrastructure For Systematic SOA-Style Application Projects

Getting the Customer Involved

Deriving Agility from SOA and BPM – Ten Things that Separate the Winners from the Losers

Estimation Toolkit

Developing with Eclipse and Maven

Inbound & Outbound marketing

Utiliser Guice et Peaberry pour développer un plugin Eclipse

Revue de Presse Xebia

Realtime Search With Lucene at Twitter

Using Default Values for Properties in Spring

Creating JAX-WS Web Service Using Service Data Objects (SDO) Instead of JAXB-bound POJOs

How to Use Wicket With JEE6

Is it Time to Switch Back to IntelliJ?

JavaScript’s Prototypal Inheritance Explained

Java Web Application Development Kick off – Technical Items

Eight important books for software developers

Let’s Play TDD #72: Starting to Look Like a Real Application

Let’s Play TDD #73: Cycles

Let’s Play TDD #74: Number Formatting Spike

HTML5 Recipes: Using Modernizr

JSF on JBoss AS6 Final

How to Limit URI Length Without Recompiling Apache

Premiers pas avec OpenERP

Revue de presse pour la semaine 51. Joyeuses fêtes !

Video: What is GSM?

Video: Gabriel Solomon of GSM Association talks about GSM

Video: Understanding GSM and CDMA Technology

Video: Wireless Machine-to-Machine (M2M) Basics: IP Addressing, Choosing Between Dynamic and Fixed IP

Video: Wireless M2M Basics: Data Communication Path, VPN vs Plain Internet Connections

Video: Wireless Machine-to-Machine (M2M) Basics: Roaming, How it Works

Soirée Java avancé avec Olivier Croisier au Paris JUG (Annotations)

Smooks processing recipies

Web App Development using Java EE 6, GlassFish, and Eclipse – Webinar Recording

Finding Second Minimum with REPEATING elements in array

SOA and Information Risk Management

Agile/Scrum Retrospectives–Tips and Tricks

Application hors-ligne HTML5 le JavaScript

Yes, SQL!

Johanna Rothman: Managing Agile Teams

Transforming to Groovy

Josh Bloch on Java and Programming

PlantUML, un nouvel outil de génération UML

Management agile : le modèle Tannenbaum & Schmidt

Infrastructure Anti-pattern: Death by a Thousand Passwords

Enterprise 2.0 Use Cases for Semantic Web

It’s time to start talking about Java EE 7

GlassFish Tips and Links #15 : Java EE 6 adoption, J2EE 1.4, JavaOne Brazil, logging in embedded, …

Which stance should I take? The 4 quadrants of Agile Managers

Hades – JPA Repositories Done Right

SOA Design Patterns in the Cloud

Distributed Agile: Other Observations

Let’s Play TDD #70: Reflections on Incremental Design

Roundup ’10 – Teaching Computer Science

Product Management an open secret, a differenciator

Will a Two Tier Market For Developers Emerge As a Result of Scala & Clojure?

Developing in the Meta

In-Memory Data Grid (IMDG) for Linear Horizontal Scalability & Extreme Transaction Processing (XTP)

Freeware for generating UMLs

Podcast 16 – Byteman Begins

Guvnor Decision Table Progress #2

GWT : premiers contacts

7 personnes, 3 corps de métier, 48h : la recette gagnante pour une appli réussie GO4OUT !

Building a World Class Team – Sharing Knowledge Part 2

Integrating ActiveMQ With Tomcat using Global JNDI

Agile Release Planning Video

Hooking RSpec up with Arquillian via JRuby

Enjoy Hibernate Cache

Deployment Automation vs. Server Provisioning

HTML5 Recipes: Browser Capabilities Tools

Neo4j 1.2 M06 is out – Better REST Indexing and Server Plugins!

Rooting for the dream

Project Managers: The Enemy Within?

Android – Multithreading in a UI environment

What are you rewarding? – We don’t pay bonuses

What Are the Next Big Things In Open Source?

Domain Objects and Their Variants

DSLs In Action is Out

org.openide.explorer.propertysheet.PropertyPanel (Netbeans)

Java EE 6 and Eclipse Webinar – Bits, Replay and Chat

Livre blanc – Qualité logicielle

Revue de Presse Xebia

My reply to “Top 10 reasons why I don’t like JSF”

Drools migrated to Git

JavaOne Beijing Keynote screencast JavaEE/GlassFish

Three Common Application Performance Challenges for Developers

Java SE Endpoints and Providers

Bugs: Prioritising by Bucket

JavaEE Developer Survey Results From ZeroTurnaround

Dialogue sheets, retrospectives and quotes (Send me your quotes)

Model-Driven Development for SOA: Future Proofing Loosely-Coupled Applications

Laurie Williams: Getting to Comparative Agility

Node.js: Asynchronous Purity Leads to Faster Development

Doing Kanban Wrong

HTML5 Labs–A Website for Prototyping New Web Technologies

Large Scale Map-Reduce Data Processing at Quantcast

Netflix in the Cloud

What’s in Maven 3.0 for users?

Loosely Coupled Coffee Maker on the NetBeans Platform

SPaMCAST 110 – Scott Price, Load Testing

Software lessons from The Food Network

Big Balls of Mud in Agile Development: Can We Avoid Them?

Slimmed Down Software – A Lean, Groovy Approach

Breaking Down Walls, Building Bridges, and Takin’ Out the Trash

Scala Pros and Cons

Episode #071 – Java EE 7 discussion with Roberto Chinnici

TOTD #152: GlassFish Installer – Typical and Custom installation

Understanding Tomcat Configuration

Communication When It’s Not Going Your Way

Open Source: Not Everyone Is A Winner

What cooking can teach to a software developer

An Answer To Agile Development Overload?

What’s Next for jclouds?

Continuous Delivery

NoSQL at Twitter

Does Agile Limit Financial Rewards for an Individual?

Java Posse #334 – Newscast for Dec 22nd 2010 + Listener Feedback

Animez vos rétrospectives – Première partie

Le temps de la désintoxication et de la simplification

Ne prenez pas le statut auto-entrepreneur

Nous ne cesserons de le dire, les tests sont importants pour la qualité du code. Lorsque l’on écrit un connecteur pour Bonita Open Solution, il peut être intéressant d’écrire de tels tests. La procédure n’est pas compliquée du tout, il faut juste la connaître, alors voici :

Pour chaque connecteur, il convient de créer un TestCase jUnit classique. Deux tests peuvent alors être effectués : tester si la définition du connecteur est correcte, et tester le connecteur en lui même.

Comment tester la description du connecteur MyConnector ?
La procédure est simple : on récupère la classe du connecteur et on appelle la méthode Connector.validateConnector() sur cette classe et on récupère les erreurs. Le connecteur est valide si aucune erreur n’est rencontrée :

  public void testValidateConnector() throws BonitaException {
    Class connectorClass = MyConnector.class;
    List errors =
        Connector.validateConnector(connectorClass);
    assertTrue(errors.isEmpty());
  }

Comment tester le connecteur MyConnector en tant que tel ?

  public void testCreateSubfolder() throws Exception {
    // Création du connecteur
    MyConnector connector = new MyConnector();
 
    // Appel de chacun des setters pour initialiser le connecteur
    connector.setConnectorVar1("MyValue");
 
    // Exécution du connecteur
    connector.execute();
 
    // Récupération de la valeur de retour
    Boolean result connector.getBooleanOutputValue();
 
    // Vérification des valeurs retournées
    assertTrue("Devrait être vrai !", result);
  }