<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OCTO talks ! &#187; services</title>
	<atom:link href="http://blog.octo.com/tag/services/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.octo.com</link>
	<description>Le blog d&#039;OCTO Technology, cabinet d&#039;architectes en systèmes d&#039;information</description>
	<lastBuildDate>Fri, 03 Feb 2012 13:46:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Un SI pour des tablettes (tactiles)</title>
		<link>http://blog.octo.com/un-si-pour-des-tablettes-tactiles/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=un-si-pour-des-tablettes-tactiles</link>
		<comments>http://blog.octo.com/un-si-pour-des-tablettes-tactiles/#comments</comments>
		<pubDate>Fri, 24 Sep 2010 14:16:28 +0000</pubDate>
		<dc:creator>Yannick Martel</dc:creator>
				<category><![CDATA[Architecture et technologies]]></category>
		<category><![CDATA[Management du SI]]></category>
		<category><![CDATA[Mobilité]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Tablettes]]></category>

		<guid isPermaLink="false">http://blog.octo.com/?p=15568</guid>
		<description><![CDATA[Nos DSI pensaient avoir passé un cap en mettant en place des infrastructures de site web client, boutique en ligne, support&#8230; Ca a été difficile, notamment pour rendre disponible sur des applications Internet des services de coeur de SI, qui n&#8217;avaient pas du tout été conçus dans cette logique, mais au moins on espérait en [...]
Suggestion d'articles :<ol>
<li><a href='http://blog.octo.com/sca-quel-apport-pour-la-soa/' rel='bookmark' title='SCA, quel apport pour la SOA?'>SCA, quel apport pour la SOA?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fblog.octo.com%252Fun-si-pour-des-tablettes-tactiles%252F%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22Un%20SI%20pour%20des%20tablettes%20%28tactiles%29%22%20%7D);"></div>
<p>Nos DSI pensaient avoir passé un cap en mettant en place des infrastructures de site web client, boutique en ligne, support&#8230; Ca a été difficile, notamment pour rendre disponible sur des applications Internet des services de coeur de SI, qui n&#8217;avaient pas du tout été conçus dans cette logique, mais au moins on espérait en avoir fini avec les remises en cause.</p>
<p>Et bien non: les tablettes tactiles arrivent, iPad, tablettes Android, etc., y compris en B2B, et elles vont changer certains des métiers, dont la vente et la distribution. Et comme les applications Internet, elles vont poser de nouvelles difficultés en nécessitant un accès selon de nouvelles modalités à des services parfois (souvent) profondément enfouis dans nos systèmes d&#8217;information.</p>
<p><span id="more-15568"></span></p>
<h2>Pourquoi?</h2>
<p>Partons d&#8217;une autre question: Pourquoi les applications iPhone sont-elle majoritairement agréables à utiliser et ont-elles contribué notablement au succès de ces smartphones?</p>
<p>Si je peux avancer une réponse, ce serait parce qu&#8217;elles partagent une charte ergonomique stricte et qu&#8217;elles sont construite autour de certains modes d&#8217;interaction. Ces modes d&#8217;interaction sont intuitifs, mais limités, et les applications sont conçues autour de cette limite. Elles sont également conçues autour des cas d&#8217;utilisation spécifiques les plus courants: les use cases d&#8217;un smartphone sont différents de ceux d&#8217;un PC. On va par exemple utiliser un PC pour réserver un billet d&#8217;avion, alors que le smartphone va permettre de s&#8217;enquérir des horaires, des retards et de s&#8217;enregistrer.</p>
<p>La même dichotomie se retrouve sur les tablettes tactiles vs les applications pour PC, même sur des applications d&#8217;entreprise. Imaginons un système de vente, permettant de réaliser une souscription de téléphonie mobile, un upgrade de forfait, un changement de mobile&#8230; Le cas d&#8217;usage de l&#8217;application sur PC est celui d&#8217;un opérateur en centre d&#8217;appel ou en agence, qui a déjà réalisé le dialogue avec son client et passe à la phase administrative, assis à son poste, alors que le client attend. La phase intense d&#8217;échange avec le client est plus ou moins terminée, les choix sont faits.</p>
<p>La même application sur tablette aura une autre orientation: elle va pouvoir être utilisée dès le début de la vente, alors que les choix ne sont pas réalisés. Le vendeur est en proximité physique avec le client, il dialogue avec lui et la tablette est une aide pour ce dialogue, y compris pour le client lui-même qui la voit et interagit avec. Le vendeur peut comparer des terminaux, tester la couverture, montrer des options, choisir des offres&#8230; Il n&#8217;est pas concentré sur son interaction avec son ordinateur, mais sur celle avec son client.</p>
<p>Du coup, il apparaît que l&#8217;application qui justifie d&#8217;introduire une tablette tactile en distribution ne peut pas être un simple portage technique, mais demande une réécriture avec une logique d&#8217;interaction différente. Reformater les écrans d&#8217;une application Web ou d&#8217;un portail donnant accès à plusieurs applications conçues pour un PC ne suffit pas. Il faut tout repenser en partant des cas d&#8217;utilisation les plus importants, en utilisant la grammaire d&#8217;interactions de la tablette et en veillant à ne pas détourner l&#8217;utilisateur du dialogue avec son client. Ceci implique alors d&#8217;accéder aux données et aux services du système d&#8217;information d&#8217;une manière différente des application traditionnelles, parce que la logique différente de l&#8217;application tablette et les contraintes techniques de la tablette impliquent des services et modalités d&#8217;accès nouveaux.</p>
<h2>Alors, que faire?</h2>
<p>Nous pouvons nous inspirer des démarches mises en oeuvre pour créer des applications Internet. On considère les applications Internet comme mouvantes, multiples, parfois jetables, parfois même non issues de l&#8217;entreprise mais réalisées par des tiers. Elles doivent pouvoir être réalisées rapidement avec une expertise spécifique, mais sans devoir à chaque fois affronter la complexité du système d&#8217;information et sa dette technique.</p>
<p>Pour ce faire, on mettait en place des couches de services spécifiques, isolant cette galaxie d&#8217;applications légères et agiles de la complexité du coeur de système d&#8217;information. Je propose de suivre une même démarche pour les applications tablettes, en mettant en place une couche de services adaptés à leurs besoins spécifiques, intégrant des services métiers, et peut-être des services techniques partagés.</p>
<p>En plus des cas d&#8217;utilisation spécifiques, quelles contraintes techniques nouvelles? Nous pouvons citer:</p>
<ul>
<li>des protocoles légers (REST / JSON par exemple), parce que la bande passante et la capacité de traitement du terminal &laquo;&nbsp;tablette&nbsp;&raquo; sont plus limitées que sur un PC;</li>
<li>un écran = un service, parce que la fluidité de l&#8217;interaction est primordiale, et que la capacité du terminal est limitée;</li>
<li>des données simples, parce que l&#8217;utilisateur doit rapidement s&#8217;y retrouver et que le terminal tablette ne doit pas avoir à réaliser de conversion de données complexes (pas de modèle pivot trop riche!).</li>
</ul>
<h2>Comment créer cette couche de service?</h2>
<p>Ne pas la créer: la faire émerger. S&#8217;inspirer de l&#8217;excellente <a href="http://www.universite-du-si.com/fr/conferences/4-usi-2009/sessions/821-une-demarche-pour-realiser-des-services-durables">session de l&#8217;USI 2009</a> de mes camarades Benoît Guillou et Dominique Jocal. L&#8217;essence est d&#8217;utiliser deux patterns de définition de service:</p>
<ul>
<li>au départ, un service est créé pour une application, sans préoccupation de réutilisation. Il est défini par un contrat entre un client et un fournisseur, qui repose sur sa signature et le cas d&#8217;utilisation de ce client. On a un pattern &laquo;&nbsp;consumer contract&nbsp;&raquo;, ou &laquo;&nbsp;contrat client&nbsp;&raquo;, où on ne se préoccupe pas de réutilisation, seulement d&#8217;adéquation avec un besoin. On respecte néanmoins les bonnes pratiques d&#8217;implémentation des services (nommage, granularité, gestion d&#8217;états&#8230;) et de développement;</li>
<li>lorsque des services similaires sont nécessaires pour plusieurs clients (au moins trois!), on peut envisager une mutualisation et mettre en place un pattern &laquo;&nbsp;consumer-driven contract&nbsp;&raquo;. Le contrat de service lie un fournisseur et plusieurs clients. Il repose sur la signature de service et la somme des cas d&#8217;utilisation par les clients.</li>
</ul>
<p>Pourquoi ces patterns? Ils rendent les services facilement testables, et transparents d&#8217;utilisation. Le service respecte le contrat s&#8217;il passe une somme de tests d&#8217;utilisation. On favorise ainsi une approche de développement et de design reposant sur les tests, cruciale pour sécuriser un service qui doit être d&#8217;autant plus fiable qu&#8217;il est utilisé en plusieurs endroits, et donc susceptible de générer plus de perturbations s&#8217;il dysfonctionne.</p>
<h2>En synthèse?</h2>
<p>Les tablettes arrivent, préparons-nous à en tirer partie, pour la satisfaction de nos clients et de nos salariés. Elles nous offrent l&#8217;occasion de tirer partie des enseignements collectés sur les applications Internet pour accélérer le développement d&#8217;applications utiles, performantes et agréables. Elles vont enfin nous permettre de construire des infrastructures SOA pragmatiques, dans un modèle adaptable (possibilité de réagir rapidement par rapport aux besoins nouveaux) plutôt qu&#8217;adapté (couvrant parfaitement un besoin &#8211; réel ou théorique &#8211; tel que compris à un instant donné). Ne nous en privons pas! </p>

 <img src="http://blog.octo.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=15568" width="1" height="1" style="display: none;" /><p>Suggestion d'articles :</p><ol>
<li><a href='http://blog.octo.com/sca-quel-apport-pour-la-soa/' rel='bookmark' title='SCA, quel apport pour la SOA?'>SCA, quel apport pour la SOA?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.octo.com/un-si-pour-des-tablettes-tactiles/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SCA, quel apport pour la SOA?</title>
		<link>http://blog.octo.com/sca-quel-apport-pour-la-soa/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sca-quel-apport-pour-la-soa</link>
		<comments>http://blog.octo.com/sca-quel-apport-pour-la-soa/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 08:15:08 +0000</pubDate>
		<dc:creator>Marc Bojoly</dc:creator>
				<category><![CDATA[Architecture et technologies]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[SCA]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://blog.octo.com/?p=3784</guid>
		<description><![CDATA[L&#8217;architecture SCA (Service Component Architecture) reste une initiative démocratisée relativement récemment même si la version 1.0 a été publiée il y a plus de deux ans maintenant. L&#8217;annonce d&#8217;Oracle Fusion 11G a récemment rappelé son support par différents grands éditeurs. Il n&#8217;en reste pas moins que son périmètre d&#8217;utilisation n&#8217;est pas forcément évident, d&#8217;autant plus [...]
Suggestion d'articles :<ol>
<li><a href='http://blog.octo.com/openesbsun-java-caps-6-quel-avenir/' rel='bookmark' title='OpenESB/Sun Java CAPS  6, quel avenir?'>OpenESB/Sun Java CAPS  6, quel avenir?</a></li>
<li><a href='http://blog.octo.com/spring-batch-par-quel-bout-le-prendre/' rel='bookmark' title='Spring-Batch : par quel bout le prendre ?'>Spring-Batch : par quel bout le prendre ?</a></li>
<li><a href='http://blog.octo.com/un-si-pour-des-tablettes-tactiles/' rel='bookmark' title='Un SI pour des tablettes (tactiles)'>Un SI pour des tablettes (tactiles)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fblog.octo.com%252Fsca-quel-apport-pour-la-soa%252F%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22SCA%2C%20quel%20apport%20pour%20la%20SOA%3F%22%20%7D);"></div>
<p>L&#8217;architecture SCA (Service Component Architecture) reste une initiative démocratisée relativement récemment même si la version 1.0 a été publiée il y a plus de deux ans maintenant. L&#8217;annonce d&#8217;Oracle Fusion 11G a récemment rappelé son support par différents grands éditeurs. Il n&#8217;en reste pas moins que son périmètre d&#8217;utilisation n&#8217;est pas forcément évident, d&#8217;autant plus qu&#8217;il s&#8217;agit d&#8217;un des nombreux sigles associés à SOA : WS-*, BPEL, JBI, SDO&#8230; Nous allons tâcher au sein de cet article de clarifier les potentialités de cette norme et de proposer des contextes qui me semblent propices pour en tirer profit.</p>
<p><span id="more-3784"></span></p>
<h4>Introduction à SCA</h4>
<p>Cette norme est désormais portée par le consortium <a title="Norme SCA au sein de l'OASIS" href="http://www.oasis-opencsa.org/sca">OASIS</a>.<br />
L&#8217;architecture SCA se base sur la notion de composants indépendants à la fois du langage et de la technologie. Son objectif est de standardiser la notion d&#8217;injection et d&#8217;interface pour tous les middlewares et tous les langages. Cela doit permettre d&#8217;écrire des composants en Java, C++, Cobol, BPEL etc. et de les interconnecter plus simplement qu&#8217;en combinant l&#8217;ensemble des technologies de web services nécessaires pour arriver au même résultat. Dans l&#8217;optique de cette norme, pour être efficace, une architecture SOA nécessite d&#8217;être implémentée à base de composants configurables. Les services web deviennent alors les interfaces de ces composants SCA. Ceux-ci comportent dans la terminologie de la norme :</p>
<ul>
<li>Des <strong>services</strong>, c&#8217;est à dire les interfaces exposées</li>
<li>Des <strong>références</strong>, c&#8217;est à dire les interfaces d&#8217;autres services que ce composant consomme</li>
<li>Des <strong> propriétés</strong>, qui permettent de le configurer</li>
</ul>
<div id="attachment_4139" class="wp-caption aligncenter" style="width: 301px"><img class="size-full wp-image-4139" title="Composant SCA" src="http://blog.octo.com/wp-content/uploads/2009/07/Composant.PNG" alt="Composant SCA" width="291" height="224" /><p class="wp-caption-text">Composant SCA</p></div>
<p>.<br />
SCA va de paire avec la norme <a title="Norme SDO au sein de l'OASIS" href="http://www.osoa.org/display/Main/Service+Data+Objects+Home">Service Data Object</a> qui vise à fournir un accès à toutes les sources de données pour tous les langages. SDO permet de définir un ensemble de données (un DataSet) que l&#8217;on peut extraire, modifier, échanger &#8211; par exemple entre composants SCA &#8211; et redonner à la source de données pour reporter les modifications.</p>
<h4>Quelle limitation SCA permet de résoudre ?</h4>
<p>Aujourd&#8217;hui en 2009, on cherche à l&#8217;intérieur d&#8217;une application à réutiliser du code par assemblage de classes, utilisation de frameworks. Les SI sont moins en silot que par le passé : différentes applications utilisent un service web que propose une application dépositaire d&#8217;une fonction partagée. Aujourd&#8217;hui cependant chaque application utilise un nombre modéré de services externes, réellement partagés avec d&#8217;autres applications.<br />
L&#8217;objectif de SCA  &#8211; faciliter la réutilisation des services en les combinant &#8211; trouve peu d&#8217;écho aujourd&#8217;hui ou le nombre de services utilisés reste modéré.</p>
<p>Alors existe-t-il des limitations que SCA permettrait de résoudre? Nous pensons que les difficultés <strong>d&#8217;assemblage</strong> de services, la <strong>complexité</strong> liés aux <strong>nombreuses</strong> normes SOA et de <strong>couplage au mode de transport</strong> peuvent nécessiter une réponse globale comme SCA si une application est réalisée majoritairement par assemblage de briques <strong>métier</strong> à <strong>forte granularité</strong> et <strong>développées par des équipes différentes</strong>. Lors de l&#8217;université du SI, le rendez-vous annuel des geeks et des boss organisé par Octo Technology, Jean-René Lyon a présenté au cours de sa session <a href="http://usi2009.universite-du-si.com/webcast-5-5-The.times.they.are.a.changin.html" class="broken_link">The times they are a changing</a> la vision d&#8217;une informatique différente où les applications seraient construites à 80% à partir de fondations métier communes assemblées (à partir de 11 min. 30 dans la vidéo).<br />
Dans l&#8217;optique d&#8217;une informatique basée ainsi sur la réutilisation massive de très nombreux composants métiers, des limitations pourraient apparaître au niveau de l&#8217;assemblage et SCA pourrait être une réponse unificatrice. Cependant, le développement informatique actuel ne fonctionne pas (encore ?) de cette façon.</p>
<h4>Positionnement de SCA aujourd&#8217;hui</h4>
<p>Aujourd&#8217;hui, le SI reste composé d&#8217;applications dialoguant entre elles via des services. L&#8217;application est homogène, développée par une seule équipe. Sa modularité interne doit rester souple, simple à mettre en oeuvre, car la priorité reste la livraison de l&#8217;application complète et non la réutilisation. Le framework Spring de par sa simplicité est devenu le standard de fait pour organiser la modularité à l&#8217;intérieur d&#8217;une application.<br />
Le dialogue avec le monde extérieur, exposition et consommation de services partagés, écrits dans des technologies différentes, reste d&#8217;un autre domaine : celui de <strong>l&#8217;intégration</strong>. Le coût du dialogue avec les autres équipes (dans quel élément du WSDL se trouve la date valeur?), la coordination des cycles de vie (montée de version, compatibilité), les soucis de disponibilité dans le cas d&#8217;un service distant font que le SI n&#8217;est pas une agrégation homogène de composants mais plutôt une intégration de différentes applications. De très nombreuses solutions existent. Là encore SCA n&#8217;apporte rien de nouveau face à l&#8217;intégration par injection des piles web services comme CXF dans Spring.<br />
Aujourd&#8217;hui SCA est mis en avant dans les solutions des éditeurs d&#8217;EAI ou d&#8217;ESB : cela structure ces produits et cela assied leur image de pérennité. Cependant dans la pratique deux EAI implémentant SCA comme Oracle Fusion Middleware ou Tibco ActiveMatrix ne peuvent pas échanger des composants SCA développés l&#8217;un avec l&#8217;autre. L&#8217;accès depuis l&#8217;un de ces produits à un composant SCA exposé par une application nécessitera un paramétrage équivalent à un appel de web service.<br />
Aujourd&#8217;hui SCA apparaît plus comme un standard de plus dont la valeur ajoutée reste faible par rapport aux outils déjà en place.</p>
<h4>SCA peut-il améliorer mon architecture SOA?</h4>
<p>Aujourd&#8217;hui les problématiques techniques traitées par SCA sont bien connues et peuvent être gérées de différentes manières, SCA -étant l&#8217;une d&#8217;entre elle. Aboutir à une architecture de fondations telle que décrite par Jean René Lyon nécessite de résoudre d&#8217;autres enjeux <strong>primordiaux</strong> préalablement à une n ième standardisation de packaging</p>
<ul>
<li>réussir <strong>l&#8217;adaptabilité</strong> du composant: rendre paramétrable et extensible un composant fait appel à des techniques de design et de construction d&#8217;interface et d&#8217;implémentation interne spécifiques, qui plus est au niveau composant et non au niveau applicatif. On ne peut pas dire que les bonnes pratiques soient servies sur un plateau, on aurait aimé que SCA traite ce point là où les manques sont bien plus nombreux.</li>
<li><strong>la gestion des données</strong> : un composant contrat doit stocker des données. Chaque composant doit il créer un silo de données, charge à l&#8217;assemblage de coordonner les différents silos?</li>
<li><strong>la dynamique d&#8217;un projet multi-équipes</strong> : comment définir une représentation commune de deux métiers? SCA s&#8217;appuie sur XML ou sur les interfaces de langages objets maîtrisés depuis près de 10 ans. Les outils sont là mais la réalisation d&#8217;une interface de service reste un travail complexe</li>
</ul>
<p>A mon sens, aujourd&#8217;hui, l&#8217;architecture SOA ne souffre pas de difficultés techniques mais avant tout de difficultés méthodologiques. Lorsque celles-ci seront levées petit à petit, la quantité de code réutilisé pourra croître. Si cela doit passer par une plus forte agrégation de services, ou par plus de paramétrage (évolution du service vers le composant), SCA pourrait avoir sa place mais la concurrence sera forte avec les technologies en place. Pour conclure nous vous donnerons trois références qui adressent ces difficultés méthodologiques</p>
<ul>
<li>La session <a href="http://usi2009.universite-du-si.com/webcast-5-44-Une.demarche.pour.realiser.des.services.durables.html" class="broken_link">une démarche pour réaliser des services durables</a> qui aborde les difficultés méthodologiques de réaliser des services web dans un SI</li>
<li>L&#8217;initiative du <a href="http://www.ceisar.fr/">CEISAR</a> qui réalise des publications sur l&#8217;architecture d&#8217;entreprise et dont la prochaine publication annoncée par Jean René Lyon dans sa session portera le thème des fondations d&#8217;entreprise</li>
</ul>
<p>Par Dominique Jocal et Marc Bojoly</p>

 <img src="http://blog.octo.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=3784" width="1" height="1" style="display: none;" /><p>Suggestion d'articles :</p><ol>
<li><a href='http://blog.octo.com/openesbsun-java-caps-6-quel-avenir/' rel='bookmark' title='OpenESB/Sun Java CAPS  6, quel avenir?'>OpenESB/Sun Java CAPS  6, quel avenir?</a></li>
<li><a href='http://blog.octo.com/spring-batch-par-quel-bout-le-prendre/' rel='bookmark' title='Spring-Batch : par quel bout le prendre ?'>Spring-Batch : par quel bout le prendre ?</a></li>
<li><a href='http://blog.octo.com/un-si-pour-des-tablettes-tactiles/' rel='bookmark' title='Un SI pour des tablettes (tactiles)'>Un SI pour des tablettes (tactiles)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.octo.com/sca-quel-apport-pour-la-soa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monsieur Jourdain et la SOA</title>
		<link>http://blog.octo.com/monsieur-jourdain-et-la-soa/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=monsieur-jourdain-et-la-soa</link>
		<comments>http://blog.octo.com/monsieur-jourdain-et-la-soa/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 10:12:39 +0000</pubDate>
		<dc:creator>Sylvain Fagnent</dc:creator>
				<category><![CDATA[Brèves de consultants]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://blog.octo.com/?p=1820</guid>
		<description><![CDATA[Mr Jourdain fait de la prose ou des vers sans qu’il n’en sût rien. Bon, nous le savons depuis la 5e ! Et comme Molière avait le don d’écrire des universalités humaines et intemporelles, il est certain qu’aujourd’hui autour de nous et dans bien des domaines il y a des Mr Jourdain qui s’ignorent. Projetons [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fblog.octo.com%252Fmonsieur-jourdain-et-la-soa%252F%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22Monsieur%20Jourdain%20et%20la%20SOA%22%20%7D);"></div>
<p><strong> Mr Jourdain fait de la prose ou des vers sans qu’il n’en sût rien</strong>. Bon, nous le savons depuis la 5e ! Et comme Molière avait le don d’écrire des universalités humaines et intemporelles, il est certain qu’aujourd’hui autour de nous et dans bien des domaines il y a des Mr Jourdain qui s’ignorent. <strong>Projetons donc ce monsieur Jourdain dans l’IT de 2009. Quelle pourrait être la chose qu’il fît depuis pas mal de temps sans qu’il n’en sût rien. Ne serait ce pas de la SOA par hasard ? </strong> Reprenons une définition communément rencontrée d’un service. Je cite rapidement et pour l’essentiel :</p>
<ul>
<li><em>Standardisation </em>: Les services exposés respectent les mêmes règles de standardisation.</li>
<li><em>Couplage lâche</em> : Le contrat de service impose un couplage lâche vis-à-vis de ses clients</li>
<li><em>Autonomie </em>: Le service est autonome car il ne fait pas appel à aucun autre système tiers. Il n’en n’est pas dépendant. Ce qui par ailleurs le rend prédictible.</li>
<li><em>Abstraction </em>: Le contrat de service n’expose que les informations essentielles à son invocation.</li>
<li><em>Composition </em>: Le service peut participer à une composition d’appel de services.</li>
<li><em>Sans état</em> : Le service ne conserve aucun état (résultats d’exécution ou autres).</li>
</ul>
<p><span id="more-1820"></span></p>
<p><strong>Le formalisme posé, maintenant, prenons notre regard de béotien</strong> et cherchons qu’est ce que l’on pourrait appeler effectivement service. Décréter qu’un système (application ou pas) devient un service, décréter que l’on va <strong>mettre en place une architecture SOA, c’est tout à fait louable mais croyez vous que cela se décrète ? </strong> Imposer peut être, pendant un temps. Si le système répond aux attentes il deviendra service dans les faits sinon, il sera contourné et patatras, il tombera aux oubliettes. <strong>Et des services en fait il y en a peu. Car l’épreuve du temps et la patine font naître ou disparaître les candidats aux services.</strong> Pardon ? Cela vous fait penser à une forme de <strong>darwinisme</strong>. L’analogie est pertinente en effet ! Prenons une architecture autour d’un ou des systèmes COBOL disons mis en place il y a déjà pas mal de temps (durée à l’appréciation du lecteur). Ces services COBOL, se sont pérennisés dans le temps, les moins utiles ont disparu, les autres se sont enrichis, ont été challengés par les utilisateurs (entendons les applications). <strong>Les plus « résistants » sont restés : sorte de sélection naturelle. </strong></p>
<p>Bien que l’on puisse les spécifier les services naissent, meurent et surtout évoluent dans le temps pour aboutir pour ceux qui sont en effet utilisés à des <strong>services métier transverses, fiables, stables et simples</strong>. Pour quelle échelle de temps ? Des années. Pardon ? Oui des années la stabilité d’un service transverse s’obtient au bout de plusieurs mois voire années ? Mais comment peut-il être adopté s’il met autant de temps à se stabiliser ? C’est que dès le départ il aura répondu à un besoin (une attente) fort qui fait que beaucoup l’auront adopté, puis challengé, amélioré et au final stabilisé il aura du passer toutes ces épreuves pour être admis au rang des services. Ou bien il va naitre dans un coin du SI pour une application donnée seule, puis digne d’intérêt une deuxième va vouloir l’utiliser, puis une troisième etc., sans qu’au départ on ait pu l’imaginer. <strong>Finalement, être un service cela ne se décrète pas, cela se mérite. </strong></p>
<p>Prenons un autre exemple que sont les portails. On disait (il y a 5 ans) que tout allait être service et que l’on pourrait agréger des dizaines de services dans notre portail. Au final, que consulte l’utilisateur lambda : le CAC40, la météo et l’horoscope. C’est peu. Certains rétorquerons, dans « le monde professionnel monsieur, les services sont autrement plus nombreux et complexes ».  Essayons ! Qu’est ce qui est susceptible d’intéresser et de motiver une équipe pour développer son application en s’appuyant sur des services transverses. Simple d’usage, transverse, performant, fiable et stable, si l’un de ces critères n’est pas respecté, le risque de rejet des utilisateurs (applications) est élevé. Prouvez-le ! Bon. S’il n’est pas <strong>transverse</strong>, peu d’applications l’utiliseront, est ce alors un service ? <strong>Performance </strong>: si son temps de réponse dégrade mes propres performances, je vais très vite l’abandonner. <strong>Fiabilité </strong>: un SLA en décalage (non compatible) avec le mien : c’est qu’il n’est pas fiable à mes yeux. Continuons, <strong>instable</strong>, aïe celui-ci est délicat, car on ne peut le juger que dans la durée. De plus, au début le service risque d’évoluer et c’est normal. Mais il n’en reste pas moins que si les couts de maintenance et de tests côté utilisateurs sont trop importants (suite aux évolutions) cela me fera réfléchir à une alternative via un développement maison par exemple. <strong>Complexe </strong>à consommer/utiliser : une notice de plus 3 pages, une ambigüité des cas d’utilisation et/ou de la gestion d’erreurs me feront prendre un risque d’un usage biaisé voire erroné.</p>
<p><strong>Alors dans les back office COBOL (plutôt ancien ;-) ) que constate t on ? </strong>Qu’il existe des services transverses exposés depuis pas mal de temps et qui « rendent bien service ».</p>
<p>Des exemples, tirés de la vraie vie :</p>
<ul>
<li>calculer de l’octroi de crédit pour un tiers (Finance),</li>
<li>récupérer un numéro de téléphone disponible (Telecom),</li>
<li>la CB XXX XXX est-elle en opposition (Monétique),</li>
<li>ouvrir un compte (Multi métier),</li>
<li>obtenir les ratings d’un tiers (Finance),</li>
<li>déclarer un sinistre (Assurance),</li>
<li>éditer un chèque de remboursement/indemnisation (Assurance),</li>
<li>obtenir un devis/tarification d&#8217;un produit (Multi métier, ….),</li>
<li>souscrire à un produit (Multi métier, …).</li>
<li>…</li>
</ul>
<p>Tous <strong>ces services, au sein des entreprises sont relativement peu nombreux et sont en fait les services frontaux métiers qui ont fait leur preuve et qu’un grand nombre d’applications comprennent et utilisent.</strong> Ils masquent la complexité des implémentations sous jacentes. Si l’on devait regarder plus précisément s’ils respectent le formalisme évoqué ci-dessus. On s’apercevrait que oui. Mais vous l’avez compris le débat n’est pas là. D’ailleurs, l’article de <strong>Anne Thomas Manes</strong> (<a href="http://apsblog.burtongroup.com/2009/01/soa-is-dead-long-live-services.html"> SOA is Dead; Long Live Services</a>) constate d’une manière assez similaire qu’en <strong>parlant SOA chacun s’est perdu dans des débats technologiques sans fin en oubliant l’essentiel : l’architecture et les services</strong>.</p>
<p>Alors que dans les faits, juste à côté de lui, <strong>de la SOA, pardon du service, Mr Jourdain en faisait dans son SI depuis des lustres, sans qu’il n’en sût rien. Quoi que, il fallait juste lui dire. Peut être alors se serait il poser les bonnes questions quand il a voulu faire de la SOA. </strong></p>

 <img src="http://blog.octo.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1820" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.octo.com/monsieur-jourdain-et-la-soa/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>La stratégie de test d&#8217;une architecture REST (2/3) &#8211; Test d’intégration</title>
		<link>http://blog.octo.com/la-strategie-de-test-dune-architecture-rest-13-test-dintegration/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=la-strategie-de-test-dune-architecture-rest-13-test-dintegration</link>
		<comments>http://blog.octo.com/la-strategie-de-test-dune-architecture-rest-13-test-dintegration/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 16:29:06 +0000</pubDate>
		<dc:creator>Benoit Guillou</dc:creator>
				<category><![CDATA[Architecture et technologies]]></category>
		<category><![CDATA[développements]]></category>
		<category><![CDATA[intégration]]></category>
		<category><![CDATA[jersey]]></category>
		<category><![CDATA[productivité]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[webservices]]></category>

		<guid isPermaLink="false">http://blog.octo.com/?p=835</guid>
		<description><![CDATA[Cet article est le deuxième d’une série de 3 articles traitant de la stratégie de test d’une architecture REST. Il fait suite au billet sur le test unitaire d’une ressource REST. Pour rappel nous allons, par l’exemple, mettre en pace une stratégie de test sur un code d’exposition de web services REST en Java. L&#8217;exemple [...]
Suggestion d'articles :<ol>
<li><a href='http://blog.octo.com/la-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource/' rel='bookmark' title='La stratégie de test d&#8217;une architecture REST (1/3) &#8211; Test unitaire d’une ressource'>La stratégie de test d&#8217;une architecture REST (1/3) &#8211; Test unitaire d’une ressource</a></li>
<li><a href='http://blog.octo.com/rest-en-java-avec-la-jsr-311/' rel='bookmark' title='REST en JAVA avec la JSR-311'>REST en JAVA avec la JSR-311</a></li>
<li><a href='http://blog.octo.com/versioning-de-services-rest/' rel='bookmark' title='Versioning de services REST'>Versioning de services REST</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fblog.octo.com%252Fla-strategie-de-test-dune-architecture-rest-13-test-dintegration%252F%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22La%20strat%C3%A9gie%20de%20test%20d%27une%20architecture%20REST%20%282%2F3%29%20-%20Test%20d%E2%80%99int%C3%A9gration%22%20%7D);"></div>
<p>Cet article est le deuxième d’une série de 3 articles traitant de la stratégie de test d’une architecture REST. Il fait suite au <a href="http://blog.octo.com/la-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource/">billet </a>sur le test unitaire d’une ressource REST. Pour rappel nous allons, par l’exemple, mettre en pace une stratégie de test sur un code d’exposition de web services REST en Java. L&#8217;exemple de code se basera sur le framework REST Jersey, implémentation de référence de Sun de la JSR-311 déjà présentée dans un précédent <a href="http://blog.octo.com/rest-en-java-avec-la-jsr-311/">article </a>. Le but de ces trois articles est de présenter un harnais de tests pouvant couvrir la mise en place de Web services REST. Ce deuxième article s’attardera sur les tests d’intégration tandis qu’un prochain article traitera des tests de recette.<br />
<span id="more-835"></span></p>
<h3>USE CASE (Rappel)</h3>
<p>RESTune est une application fictive de vente de musique en ligne. Cette application permet :</p>
<ul>
<li>de lister l&#8217;ensemble des albums : GET http://&#8230;/albums</li>
<li>de récupérer un album en fournissant son identifiant : GET http://&#8230;/albums/12133</li>
<li>de créer un album : POST http://&#8230;/albums</li>
</ul>
<h4>Architecture générale de l&#8217;application (Rappel)</h4>
<p>RESTune est une application Java classique n-tiers :</p>
<ul>
<li>une couche DAO (framework Hibernate)</li>
<li>une couche Service</li>
<li>une couche Webservice (framework Jersey + JAXB pour la sérialisation / désérialisation)</li>
<li>une gestion des beans par le framework Spring</li>
</ul>
<h3>Le test d’intégration</h3>
<p>Par définition, le test d’intégration valide la cohérence d’une fonctionnalité dans son ensemble. Dans le cas de l’implémentation d’une ressource REST, il est nécessaire de traverser toutes les couches de l’application &#8211; de l&#8217;appel HTTP au WS REST jusqu&#8217;à la base de données dans notre exemple. Cette fois, l&#8217;ensemble de notre pile logicielle Spring + Hibernate + Jaxb + Jersey sera mise en jeu. Le but n&#8217;est bien évidemment pas de tester les frameworks mais l&#8217;utilisation qui en est faite et la cohérence de l&#8217;ensemble.</p>
<h4>Environnement léger de test d’intégration</h4>
<p>Le dispositif présenté ci-dessus permet de disposer sur le poste développeur d’un serveur d’application (Jetty) et d’une base de données en mémoire (HSQLDB). Ces deux outils ont, en autres, la particularité d’être légers et rapides. L’intérêt de ce dispositif est de créer un contexte se rapprochant le plus possible de la réalité (serveur d’application + base de données) tout en ne sacrifiant pas les performances. Cette plateforme permet d’exécuter des tests sur le poste développeur tout en s’autorisant à passer sur une plateforme d’intégration moyennant configuration (via Maven par exemple – cf <a name="maven"></a>).</p>
<p>La classe de test AbstractWebRunnerTestCase permet de lancer un Jetty, de déployer l&#8217;application RESTune décrite par son fichier web.xml. L’utilisation du <a href="http://blogs.sun.com/sandoz/entry/jersey_client_api">client Jersey</a> permet de simplifier la manipulation de ressources REST par rapport à un client HTTP tel HTTPClient. A noter que ce client, prévu initialement pour faciliter les tests unitaires du framework Jersey, est un maintenant un composant a part entière du framework. Il peut donc permettre de réaliser la partie Cliente d’une application REST, tout comme tester une autre implémentation REST que Jersey (RESTLET, RESTeasy, …).</p>

<div class="wp_codebox"><table><tr id="p8357"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code" id="p835code7"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> AbstractWebRunnerTestCase <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">int</span> port <span style="color: #339933;">=</span> <span style="color: #cc66cc;">9797</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> url<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> Server server<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> Client client<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">protected</span> AbstractWebRunnerTestCase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">url</span> <span style="color: #339933;">=</span> <span style="color: #003399;">String</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://localhost:%s/&quot;</span>, port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">// Helper pour manipuler les ressources</span>
<span style="color: #000000; font-weight: bold;">protected</span> WebResource getResource<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> relativeUrl<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #003399;">String</span> realUrl <span style="color: #339933;">=</span> url <span style="color: #339933;">+</span> relativeUrl<span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">return</span> client.<span style="color: #006633;">resource</span><span style="color: #009900;">&#40;</span>realUrl<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
@BeforeClass
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
server <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Server<span style="color: #009900;">&#40;</span>port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// On lance le serveur Jetty</span>
WebAppContext webAppContext <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WebAppContext<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;src/main/webapp&quot;</span>, <span style="color: #0000ff;">&quot;/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
webAppContext.<span style="color: #006633;">setConfigurationClasses</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">&quot;org.mortbay.jetty.webapp.WebInfConfiguration&quot;</span>,
<span style="color: #0000ff;">&quot;org.mortbay.jetty.webapp.WebXmlConfiguration&quot;</span>, <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
server.<span style="color: #006633;">addHandler</span><span style="color: #009900;">&#40;</span>webAppContext<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> server.<span style="color: #006633;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Création d'un client Jersey client = Client.create();</span>
<span style="color: #009900;">&#125;</span>
@AfterClass
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> tearDown<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>server <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
server.<span style="color: #006633;">stop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Prenons l’exemple de la recherche d’album par identifiant : GET http://&#8230;/albums/{id}</p>
<p>Le code à tester</p>

<div class="wp_codebox"><table><tr id="p8358"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p835code8"><pre class="java" style="font-family:monospace;">@GET
@Path<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/{id}&quot;</span><span style="color: #009900;">&#41;</span>
@Produces<span style="color: #009900;">&#40;</span>MediaType.<span style="color: #006633;">APPLICATION_XML</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> AlbumXmlBean getAlbumById<span style="color: #009900;">&#40;</span>@PathParam<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;id&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #003399;">Long</span> id<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> AlbumNotFoundException <span style="color: #009900;">&#123;</span>
Album album <span style="color: #339933;">=</span> albumService.<span style="color: #006633;">getAlbumById</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> AlbumXmlBean<span style="color: #009900;">&#40;</span>album<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Méthode testée unitairement, il reste cependant à vérifier :<br />
- Le Verbe http autorisé (configuré par l’annotation @GET)<br />
- Le MediaType autorisé @Produces(MediaType.APPLICATION_XML)<br />
- L&#8217;utilisation des Providers / ExceptionMappers (cf JSR-311)<br />
- L’Enchainement des traitements et intégration des couches applicatives (JAXB, appel au DAO, appel à la DB).</p>
<h3>Exemple de test d’intégration du cas Nominal</h3>
<p>Ce test traverse l’ensemble des couches de l’application, de l’appel HTTP à l’appel à la base de données. Il permet de valider entièrement la réponse en vérifiant le code retour http et le contenu de la réponse.</p>

<div class="wp_codebox"><table><tr id="p8359"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code" id="p835code9"><pre class="java" style="font-family:monospace;">@RunWith<span style="color: #009900;">&#40;</span>SpringJUnit4ClassRunner.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>
@ContextConfiguration<span style="color: #009900;">&#40;</span>locations <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">&quot;classpath:applicationContext.xml&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AlbumsResourceIntTest <span style="color: #000000; font-weight: bold;">extends</span> AbstractWebRunnerTestCase <span style="color: #009900;">&#123;</span>
@Autowired
HibernateTemplate hibernateTemplate<span style="color: #339933;">;</span>
@Test
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> getAlbumByIdNominalCase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">// Setup</span>
Album kidA <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Album<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 kidA.<span style="color: #006633;">setReleaseDate</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 kidA.<span style="color: #006633;">setTitle</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Kid A&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 hibernateTemplate.<span style="color: #006633;">save</span><span style="color: #009900;">&#40;</span>kidA<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 AlbumXmlBean expectedKidAXmlBean <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> AlbumXmlBean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 expectedKidAXmlBean.<span style="color: #006633;">setId</span><span style="color: #009900;">&#40;</span>kidA.<span style="color: #006633;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 expectedKidAXmlBean.<span style="color: #006633;">setTitle</span><span style="color: #009900;">&#40;</span>kidA.<span style="color: #006633;">getTitle</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #666666; font-style: italic;">// Test</span>
WebResource resource <span style="color: #339933;">=</span> getResource<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;albums/&quot;</span> <span style="color: #339933;">+</span> kidA.<span style="color: #006633;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Assert</span>
<span style="color: #666666; font-style: italic;">// Validation du code retour</span>
ClientResponse clientResponse <span style="color: #339933;">=</span> resource.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>ClientResponse.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> assertEquals<span style="color: #009900;">&#40;</span>Status.<span style="color: #006633;">OK</span>.<span style="color: #006633;">getStatusCode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, clientResponse.<span style="color: #006633;">getStatus</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Validation de l'entité contenu dans la réponse</span>
AlbumXmlBean retrievedAlbumXmlBean <span style="color: #339933;">=</span> resource.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>AlbumXmlBean.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
assertNotNull<span style="color: #009900;">&#40;</span>retrievedAlbumXmlBean<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
assertEquals<span style="color: #009900;">&#40;</span>expectedKidAXmlBean, retrievedAlbumXmlBean<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>Les possibilités offertes par Maven Gestion des configurations<a></a></h3>
<p>Les tests d’intégration peuvent être exécutés à deux niveaux grâce à la gestion <a href="http://maven.apache.org/guides/introduction/introduction-to-profiles.html">profils Maven</a>. En effet, Maven offre la possibilité, par simple configuration, de gérer différents environnements (développeur, intégration, recette, production par exemple).</p>
<h4>Test d’intégration développeur</h4>
<p>Sur le poste développeur, priorité à la rapidité d’exécution. Etant donné qu’il y a un appel HTTP + JDBC, on ne se place plus dans une problématique de test unitaire mais bien de test d’intégration. Ces tests pourraient donc être qualifiés de tests d’intégration développeur.</p>

<div class="wp_codebox"><table><tr id="p83510"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p835code10"><pre class="dos" style="font-family:monospace;">mvn test –Pdeveloppement</pre></td></tr></table></div>

<p>Moyennant configuration dans le POM, les tests seront exécutés dans un environnement « développement » (Jetty + HSQLDB).</p>
<h4>Test d’intégration</h4>
<p>Le test d’intégration se doit de s’effectuer dans un environnement le plus proche possible de celui de production. Ce profil chargera donc l’environnement d’intégration complet : on peut par exemple garder Jetty pour l’exécution des tests mais attaquer la base d’intégration (avec ses propres données, son propres schémas, …). Plus complet mais aussi plus long à tester ! Ce genre de tests pourra être évité sur le poste du développeur et être exécuté par l’automate de build (tous les soirs par exemple).</p>

<div class="wp_codebox"><table><tr id="p83511"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p835code11"><pre class="dos" style="font-family:monospace;">mvn test –Pintegration</pre></td></tr></table></div>

<p>Il est donc possible de séparer les tests unitaires des tests d’intégration grâce à la configuration Maven.<br />
Le plugin Jetty</p>

<div class="wp_codebox"><table><tr id="p83512"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p835code12"><pre class="dos" style="font-family:monospace;">mvn jetty:run</pre></td></tr></table></div>

<p>Le plugin Jetty (maven-jetty-plugin) permet de pouvoir lancer un serveur d’application léger et de déployer l’application en cours de développement. Un fois lancé, Jetty prend automatiquement en compte les modifications de code et de configuration. Cela peut notamment servir de démo pour que vous puissiez tester avec votre browser web préféré. Il est possible par exemple avec Firefox et son plugin Poster de tester le POST d’un XML sur une url.</p>
<h3>Conclusion</h3>
<p>Les tests d’intégration permettent de tester l’ensemble de la fonctionnalité offerte par la ressource, en invoquant l’ensemble de la pile logicielle. Ces tests sont par essence plus longs à jouer. La plateforme de test Jetty + HSQLDB est une réelle alternative permettant de tester au plus vite, dans un environnement plus riche que celui proposé par les tests unitaires. Maven offre de plus la possibilité de pouvoir piloter l’environnement sur lesquels ces tests sont exécutés par simple configuration. L’automate de build pourra alors construire l’application en exécutant au préalable les tests d’intégration sur une plateforme plus complète. Ces tests permettent de mitiger les risques sur :</p>
<ul>
<li>Les codes retour et le contenu des réponses</li>
<li>L’utilisation des annotations du framework Jersey</li>
<li>MIME Type</li>
<li>L’utilisation des Providers  / ExceptionMapper</li>
<li>L’URI de la ressource</li>
<li>La sérialisation / désérialisation des objets</li>
</ul>
<p>Prochainement, nous étudierons plus en détails le test de recette d’une ressource REST. Pour être plus précis, ce dernier article exposera un moyen de réaliser et d’automatiser <a href="http://www.dotnetguru.org/articles/dossiers/fitnesse/article.htm" class="broken_link">les tests de recette</a>, autre moyen de valider/assurer la non-régression d’un service et d’avoir un feedback au plus tôt.</p>
<p>NB : Le code de RESTune est disponible <a href="http://forge.octo.com/svn/java/trunk/octo-samples/jersey-rest-sample/">ici</a>.</p>

 <img src="http://blog.octo.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=835" width="1" height="1" style="display: none;" /><p>Suggestion d'articles :</p><ol>
<li><a href='http://blog.octo.com/la-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource/' rel='bookmark' title='La stratégie de test d&#8217;une architecture REST (1/3) &#8211; Test unitaire d’une ressource'>La stratégie de test d&#8217;une architecture REST (1/3) &#8211; Test unitaire d’une ressource</a></li>
<li><a href='http://blog.octo.com/rest-en-java-avec-la-jsr-311/' rel='bookmark' title='REST en JAVA avec la JSR-311'>REST en JAVA avec la JSR-311</a></li>
<li><a href='http://blog.octo.com/versioning-de-services-rest/' rel='bookmark' title='Versioning de services REST'>Versioning de services REST</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.octo.com/la-strategie-de-test-dune-architecture-rest-13-test-dintegration/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>La stratégie de test d&#8217;une architecture REST (1/3) &#8211; Test unitaire d’une ressource</title>
		<link>http://blog.octo.com/la-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=la-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource</link>
		<comments>http://blog.octo.com/la-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 15:29:19 +0000</pubDate>
		<dc:creator>Benoit Guillou</dc:creator>
				<category><![CDATA[Architecture et technologies]]></category>
		<category><![CDATA[développements]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jersey]]></category>
		<category><![CDATA[productivité]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[tests]]></category>

		<guid isPermaLink="false">http://new-blog.octo.com/?p=733</guid>
		<description><![CDATA[Cet article est le premier d’une série de 3 articles traitant de la stratégie de test d’une architecture REST. Il fait suite au billet sur les types de test utilisés sur un projet Agile. Par l&#8217;exemple, nous allons mettre en place une stratégie de tests sur un code d&#8217;exposition de web services REST en Java. L&#8217;exemple [...]
Suggestion d'articles :<ol>
<li><a href='http://blog.octo.com/la-strategie-de-test-dune-architecture-rest-13-test-dintegration/' rel='bookmark' title='La stratégie de test d&#8217;une architecture REST (2/3) &#8211; Test d’intégration'>La stratégie de test d&#8217;une architecture REST (2/3) &#8211; Test d’intégration</a></li>
<li><a href='http://blog.octo.com/rest-en-java-avec-la-jsr-311/' rel='bookmark' title='REST en JAVA avec la JSR-311'>REST en JAVA avec la JSR-311</a></li>
<li><a href='http://blog.octo.com/versioning-de-services-rest/' rel='bookmark' title='Versioning de services REST'>Versioning de services REST</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fblog.octo.com%252Fla-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource%252F%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22La%20strat%C3%A9gie%20de%20test%20d%27une%20architecture%20REST%20%281%2F3%29%20-%20Test%20unitaire%20d%E2%80%99une%20ressource%22%20%7D);"></div>
<p>Cet article est le premier d’une série de 3 articles traitant de la stratégie de test d’une architecture REST. Il fait suite au <a href="http://blog.octo.com/quels-sont-les-types-de-tests-que-l%E2%80%99on-utilise-sur-un-projet-agile">billet</a> sur les types de test utilisés sur un projet Agile. Par l&#8217;exemple, nous allons mettre en place une stratégie de tests sur un code d&#8217;exposition de web services REST en Java. L&#8217;exemple de code se basera sur le framework REST Jersey, RI de Sun de la JSR-311 déjà présenté dans un précédent <a href="http://blog.octo.com/index.php/2008/09/27/145-rest-en-java-avec-la-jsr-311">article</a>. Le but de ces trois articles est de présenter un harnais de tests pouvant couvrir la mise en place de Web services REST. Ce premier article s’attardera sur les tests unitaires tandis que les suivants étudieront les tests d’intégration puis les tests de recette.</p>
<p><span id="more-733"></span></p>
<h3>Use Case</h3>
<p>RESTune est une application fictive de vente de musique en ligne. Cette application permet :</p>
<ul>
<li>de lister l&#8217;ensemble des albums : <code>GET http://.../albums</code></li>
<li>de récupérer un album en fournissant son identifiant : <code>GET http://.../albums/12133</code></li>
<li>de créer un album : <code>POST http://.../albums</code></li>
</ul>
<h3>Architecture générale de l&#8217;application</h3>
<p>RESTUne est une application Java classique n-tiers :</p>
<ul>
<li>une couche DAO (framework Hibernate)</li>
<li>une couche Service</li>
<li>une couche Webservice (framework Jersey + JAXB pour la sérialisation / désérialisation)</li>
<li>une gestion des beans par le framework Spring</li>
</ul>
<p style="text-align: center;"><img class="aligncenter" src="http://blog.octo.com/wp-content/uploads/2009/02/architecturegenerale.png" alt="Architecture générale" /></p>
<h3>Le test unitaire</h3>
<p>Le test unitaire est le premier maillon de la stratégie de test. Partant de la loi du <span>Defect Cost Increase </span>(plus un défaut est détecté tard, plus il coûte cher), le test unitaire (ou test du développeur) joue un rôle crucial. Il permet de valider que le code développé est conforme aux intentions du développeur. Partant du principe que tout test rejouable est de facto un test de non-regression, l’ensemble des tests unitaires d’une application constitue un patrimoine inestimable. Un test est par définition répétable, automatique, indépendant mais surtout pour le développeur impatient, il doit être rapide ! Nous allons donc mettre en place une stratégie de test unitaire légère et rapide.<br />
Pour rappel, <span>Michaël Feathers</span> définit dans <span>Working Effectively With Legacy Code</span> un test unitaire de la façon suivante :</p>
<ul>
<li> Il ne communique pas avec la base de données</li>
<li>Il ne communique pas avec d’autres ressources sur le réseau</li>
<li>Il ne manipule pas un ou plusieurs fichiers</li>
<li>Il peut s’exécuter en même temps que les autres tests unitaires</li>
<li>On ne doit pas faire quelque chose de spécial, comme éditer un fichier de configuration, pour l’exécuter</li>
</ul>
<p style="text-align: center;"><img class="aligncenter" src="http://blog.octo.com/wp-content/uploads/2009/02/tu1.png" alt="Test unitaire" /></p>
<h3>Le pattern &laquo;&nbsp;couche d’exposition fine&nbsp;&raquo;</h3>
<p>Le test unitaire se borne à valider la couche d&#8217;exposition de services. Dans les applications Web classiques, il est préférable de ne laisser que très peu de logique au niveau de la couche présentation. D’un point de vue design, l’application y gagne en lisibilité et en testabilité. Il est facile de faire le parallèle avec la couche d’exposition. Plus elle sera fine et ne comportera des données propres à l’exposition, plus elle sera simple à tester. En REST, l&#8217;exposition de services se fait bien entendu au moyen de ressources.</p>
<p>La JSR-311 se basant sur des beans annotés, il est simple de tester unitairement ces beans hors de tout contexte. Nous allons donc tester notre ressource Album en isolation.<br />
Le code d’exposition de la ressource est le suivant :</p>
<pre>@Singleton
@Path("/albums")
public class AlbumsResource { 

@Context
private UriInfo uriInfo;
@Inject
AlbumService albumService;
[...]
@POST
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_XML)
public Response postAlbum(AlbumXmlBean albumXmlBean)
{
Album album = albumXmlBeanToAlbum(albumXmlBean);
try {
albumService.save(album);
}
catch (AlbumAlreadyExists e) {
return Response.status(Status.CONFLICT).entity("Album with title " + album.getTitle() + " already exists").build();
}
AlbumXmlBean albumXmlBeanAfterSave = albumToAlbumXmlBean(album);
// Building URI
UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
URI uri = uriBuilder.path(albumXmlBeanAfterSave.getId().toString()).build();
return Response.created(uri).entity(albumXmlBeanAfterSave).build();
}
[...]
}</pre>
<h3>Le pattern Mock Object</h3>
<p>Le pattern Mock Object ou bouchonnage permet d’isoler ma ressource Album de ses dépendances et de se conformer à la définition de test unitaire faite par Feathers. Nous allons donc mocker les couches inférieures grâce au framework <a href="http://unitils.org/summary.html">Unitils</a>. Unitils est un framework qui permet de simplifier les tests unitaires. Il permet entre autres de simplifier l’écriture de Mock grâce à <a href="http://www.easymock.org/">EasyMock</a>.</p>
<pre>@RunWith(UnitilsJUnit4TestClassRunner.class)
public class AlbumsResourceUTest {
// Objet du test
@TestedObject
AlbumsResource albumsResource;

// Mock + injection dans l'objet du test
@RegularMock
@InjectIntoByType
AlbumService albumService;

// Mock + injection dans l'objet du test
@RegularMock
@InjectIntoByType
UriInfo uriInfo;

// Simple mock
@Mock
UriBuilder uriBuilder;
[...]
}</pre>
<p>Easymock permet en un minimum de code de disposer d&#8217;objet mocké que l&#8217;on va pouvoir maîtriser afin de mener à bien nos tests. Pour information, la méthode <code>EasyMock.expect(…)</code> permet de valider l&#8217;utilisation des objets mockés (nombre d&#8217;appel, arguments, …) tout en manipulant leur comportement.</p>
<h3>Exemple : Test unitaire du cas nominal</h3>
<p>Ce test permet de valider le comportement nominal du service. Il vérifie la réponse de la ressource, le code retour ainsi que l&#8217;appel à la méthode sous-jacente <code>albumService.save()</code>.</p>
<pre>@Test
public void postAlbumNominalCase() throws URISyntaxException {
// Setup
Album album = new Album(); album.setTitle("In Rainbows");
album.setId(new Long(32));
albumXmlBean.setTitle("In Rainbows");
albumXmlBean.setId(album.getId());
URI expectedUri = new URI("http://test");

// Mock expectations
albumService.save(album);
EasyMock.expect(uriInfo.getAbsolutePathBuilder()).andReturn(uriBuilder);
EasyMock.expect(uriBuilder.path(album.getId().toString())).andReturn(uriBuilder);
EasyMock.expect(uriBuilder.build()).andReturn(expectedUri); EasyMockUnitils.replay();

// Test
Response response = albumsResource.postAlbum(albumXmlBean);

// Asserts
assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
AlbumXmlBean returnedAlbumXmlBean = (AlbumXmlBean) response.getEntity();
assertTrue(response.getMetadata().containsKey("Location"));

URI returnedUri = (URI) response.getMetadata().get("Location").get(0);
assertEquals(expectedUri, returnedUri); assertEquals(albumXmlBean, returnedAlbumXmlBean);</pre>
<p>Il est dès lors possible de construire tous les cas de test en pilotant ces mocks. Par exemple le test suivant valide qu’à la levée d’une exception <code>AlbumAlreadyExistsException</code>, le web service renvoie un code retour CONFLICT (409) :</p>
<h3>Conclusion</h3>
<p>Les tests unitaires sur un service web permettent de tester en isolation une ressource (sans Spring + Hibernate + Jaxb + Jersey). Quand on connait le contexte que traine chacun de ces frameworks, on s&#8217;aperçoit qu&#8217;on arrive à tester au maximum notre ressource de manière simple (manipulation de POJOs). Ces tests seront d’autant plus fréquemment rejoués qu’ils sont rapides à exécuter et participeront donc à la qualité générale de l’application. A travers ces tests, il est possible de valider que la ressource mise en place est conforme aux intentions du développeur :</p>
<ul>
<li>en vérifiant l&#8217;appel aux méthodes sous-jacente (vérification de l&#8217;appel de méthodes, des arguments)</li>
<li>en simulant les exceptions et en validant le comportement de la couche d&#8217;exposition</li>
<li>en validant les codes retours et le contenu des réponses répondant aux différents use cases du service</li>
</ul>
<p>Le test unitaire est le premier maillon du harnais de tests. Nous verrons dans les articles suivants dans quelle mesure les tests d&#8217;intégration et les tests de recette participent eux aussi à la mise en place d&#8217;une stratégie de test efficace.</p>
<p>Rq : Vous pouvez me <a href="mailto:bguillou@octo.com">contacter </a>si vous désirez le code complet de RESTune</p>

 <img src="http://blog.octo.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=733" width="1" height="1" style="display: none;" /><p>Suggestion d'articles :</p><ol>
<li><a href='http://blog.octo.com/la-strategie-de-test-dune-architecture-rest-13-test-dintegration/' rel='bookmark' title='La stratégie de test d&#8217;une architecture REST (2/3) &#8211; Test d’intégration'>La stratégie de test d&#8217;une architecture REST (2/3) &#8211; Test d’intégration</a></li>
<li><a href='http://blog.octo.com/rest-en-java-avec-la-jsr-311/' rel='bookmark' title='REST en JAVA avec la JSR-311'>REST en JAVA avec la JSR-311</a></li>
<li><a href='http://blog.octo.com/versioning-de-services-rest/' rel='bookmark' title='Versioning de services REST'>Versioning de services REST</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.octo.com/la-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>De la réussite durable d’une démarche SOA</title>
		<link>http://blog.octo.com/de-la-reussite-durable-dune-demarche-soa/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=de-la-reussite-durable-dune-demarche-soa</link>
		<comments>http://blog.octo.com/de-la-reussite-durable-dune-demarche-soa/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 22:59:53 +0000</pubDate>
		<dc:creator>Olivier Mallassi</dc:creator>
				<category><![CDATA[Méthodologie et conduite du changement]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://new-blog.octo.com/2008/11/21/de-la-reussite-durable-dune-demarche-soa/</guid>
		<description><![CDATA[<p align="justify">Trop souvent les démarches SOA adressent uniquement les problématiques d'architectures techniques et fonctionnelles,  au dépend des enjeux humains et organisationnels inhérents à la transformation qu'impose la SOA au SI.</p>]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fblog.octo.com%252Fde-la-reussite-durable-dune-demarche-soa%252F%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22De%20la%20r%C3%A9ussite%20durable%20d%E2%80%99une%20d%C3%A9marche%20SOA%22%20%7D);"></div>
<p align="justify">Trop souvent les démarches SOA adressent uniquement les problématiques d&#8217;architectures techniques et fonctionnelles,  au dépend des enjeux humains et organisationnels inhérents à la transformation qu&#8217;impose la SOA au SI.</p>
<p><span id="more-161"></span></p>
<h3>La SOA doit aider à fédérer une communauté de partenaires et à maintenir l&#8217;adaptabilité du SI</h3>
<p align="justify"><strong>Dans les échanges qu&#8217;a l&#8217;entreprise avec ses partenaires extérieurs divers</strong>, la nécessité de mettre en place et d&#8217;utiliser des services ne se discute plus. L&#8217;entreprise s&#8217;ouvre, s&#8217;interconnecte, fournit et consomme de l&#8217;information, participe à des chaînes de valeur : <strong>cherche à fédérer autour de sa plateforme</strong>. Dans <strong>l&#8217;extension de cette approche vers l&#8217;intérieur</strong>, l&#8217;entreprise cherche à maitriser les processus métier et à répondre à des enjeux tels que le <strong>cross-selling</strong>, le <strong>respect du time-to-market</strong> de nouveaux produits, la possibilité d&#8217;absorber des reconfigurations sectorielles&#8230;<br /><strong>La DSI occupe une place prépondérante dans cette transformation</strong> et les enjeux invoqués se déclinent alors essentiellement dans la mutualisation des règles métiers, la gouvernance et la qualité de la donnée, la gestion des échanges inter/intra entreprise, <strong>la recherche de l&#8217;efficacité des projets informatiques</strong> (en favorisant par exemple l&#8217;interopérabilité des applications de générations ou de technologies différentes) et <strong>l&#8217;adaptabilité du SI aux évolutions métiers</strong>. </p>
<h3>Le SI &nbsp;&raquo; mute &nbsp;&raquo; d&#8217;un SI en silos vers un SI proposant des services partagés</h3>
<p align="justify">Un consensus semble établi sur le fait que la SOA est un des meilleurs candidats pour adresser l&#8217;ensemble de ces enjeux. Mais les SI d&#8217;aujourd&#8217;hui sont constitués d&#8217;applications et de sources de données variées, basées sur des technologies hétérogènes et souvent gérées par des organisations cloisonnées. La SOA tire ses gênes de cette complexité et propose <strong>une architecture qui présente fonctions et informations du SI sous forme de &laquo;&nbsp;services&nbsp;&raquo; interopérables</strong> et faiblement couplés. <strong>L&#8217;architecture du SI s&#8217;organise </strong>alors à travers la factorisation des éléments communs, l&#8217;élimination des redondances, la réutilisation de services <strong>avec comme conséquence la &laquo;&nbsp;mutation&nbsp;&raquo; d&#8217;un SI en silo vers un SI proposant des services partagés</strong> </p>
<p align="center"><img height="283" alt="" width="464" align="middle" src="/wp-content/uploads/images/silo-soa.png" /></p>
<p align="left">  Reste qu&#8217;une telle <strong>mise en oeuvre est souvent synonyme de désillusions voire de douleurs</strong>&#8230;</p>
<ul>
<li>
<div align="justify"><strong>une augmentation drastique des dépendances entre les applications et les équipes</strong> avec des difficultés lors de la planification des développements, lors de la définition et la mise à disposition des contrats de services, des impacts sur les processus de gestion des évolutions ou de correction des anomalies qui doit prendre en compte les divers consommateurs, un &nbsp;&raquo; run &nbsp;&raquo; qui peut avoir à assurer la disponibilité de multiples versions de services, la promesse de découplage qui fait oublier que l&#8217;ensemble des applications mises à contribution risquent de devoir s&#8217;aligner sur le SLA le plus exigeant </div>
</li>
<li>
<div align="justify"><strong>une mise en oeuvre prématurée d&#8217;outils comme les ESB ou les BPM</strong>. Utiliser à bon escient et dans des organisations suffisamment matures, ces outils permettent d&#8217;optimiser certains comportements (sécurité, routage, administration&#8230;). A l&#8217;inverse, ils peuvent devenir une contrainte et une source de complexité</div>
</li>
<li>
<div align="justify"><strong>une approche uniquement &nbsp;&raquo; bottom-up &nbsp;&raquo; qui mène à des échanges points à points non maitrisés</strong> et une très faible réutilisabilité</div>
</li>
<li>
<div align="justify"><strong>une approche uniquement &nbsp;&raquo; top-down &nbsp;&raquo; qui imagine des SI &nbsp;&raquo; tout services &laquo;&nbsp;</strong> ; créant des formats pivots &nbsp;&raquo; a priori &nbsp;&raquo; alors que beaucoup d&#8217;applications ne sont pas prêtes ou normalisant &nbsp;&raquo; à tout va &nbsp;&raquo; les référentiels au risque de limiter la performance générale des services</div>
</li>
</ul>
<h3>Une démarche SOA doit se décliner sur trois axes : les technologies, l&#8217;architecture du SI et les aspects organisationnels et humains</h3>
<p align="justify"><strong>La mise en oeuvre d&#8217;une architecture SOA doit être pragmatique et dimensionnée en fonction de la complexité de l&#8217;architecture cible et de la maturité de l&#8217;organisation</strong> pour supporter humainement, techniquement et financièrement cette architecture. </p>
<p align="justify">Mais quelque soit le niveau de complexité et de maturité, <strong>la réalisation d&#8217;une architecture SOA se décline sur trois axes: les technologies, l&#8217;architecture du SI et les aspects organisationnels et humains</strong>. </p>
<p align="justify"><strong>L&#8217;axe technologique embrasse l&#8217;ensemble des aspects de l&#8217;architecture applicative et de l&#8217;expertise technique et vise à plus de simplicité</strong>. L&#8217;émergence d&#8217;architectures dites &laquo;&nbsp;orientées ressources&nbsp;&raquo; (ROA) et plus légères que les approches dites &laquo;&nbsp;classiques&nbsp;&raquo; (SOAP) rebattent les cartes et promettent de meilleures interopérabilité et productivité mais cela nécessite d&#8217;appliquer des principes d&#8217;architecture différents et potentiellement complémentaires. Parallèlement, la sécurisation des services doit privilégier une approche pilotée par les risques plutôt qu&#8217;une approche totalement sécuritaire et permettre l&#8217;utilisation de moyens techniques adaptés en termes de propriétés et de coûts. Enfin, les différentes plateformes de développement sont relativement matures mais reste à maîtriser leur déploiement (contract-first, code-first), industrialiser leur utilisation afin que leur usage dans le flux de développement ne soit un frein ni à la productivité, ni à la testabilité.  </p>
<p align="justify"><strong>Le second axe regroupe les disciplines de l&#8217;architecture de SI, la modélisation des processus métier et promeut des architectures simples et évolutives,  des standards opérationnels</strong>. Il est aujourd&#8217;hui nécessaire de mixer approche organique et approche légaliste. L&#8217;approche organique, permet de faire &nbsp;&raquo; émerger &nbsp;&raquo; des services au sein de projets et facilite la découverte d&#8217;une direction opérable à coûts et risques optimisés à partir d&#8217;un existant en terme de code, de compétences techniques et fonctionnelles. Mais cette approche sera cadrée par l&#8217;approche légaliste permettant d&#8217;aligner les différents acteurs sur une intention commune, une vision partagée. De ce mélange des deux approches apparaît une direction unique et utile : des modèles et des standards applicables rapidement par les projets et améliorés de façon continue grâce au &laquo;&nbsp;retour terrain&nbsp;&raquo;. </p>
<p align="justify">Enfin <strong>l&#8217;organisation et les dynamiques d&#8217;équipes devront évoluer pour &laquo;&nbsp;s&#8217;aligner&nbsp;&raquo; sur ces notions de &laquo;&nbsp;services&nbsp;&raquo; et intégrer un mode de développement lui aussi distribué</strong>. Des aspects souvent oubliés mais qui imposent à l&#8217;organisation de se transformer pour faire émerger des équipes responsables (c&#8217;est à dire garantes de la sémantique, de l&#8217;intéropérabilité, de la non régression, du SLA&#8230;) des services. Cette mise en oeuvre du changement, passera par l&#8217;adaptation des processus de développement, de l&#8217;organisation du travail et par la remise en cause de la classique contractualisation entre équipes. Cette transformation se traduira par une spécialisation des équipes par &nbsp;&raquo; bouquet de services &laquo;&nbsp;, une diminution des chaines de responsabilités afin de polariser les équipes sur un unique but qu&#8217;est le &laquo;&nbsp;service&nbsp;&raquo;, une évolution des processus de développement vers du plus &laquo;&nbsp;itératif-incrémental&nbsp;&raquo;. </p>
<p align="justify">Quant à <strong>la Gouvernance</strong>, cette dernière <strong>aura à charge de préciser les standards à appliquer sur chacun des ces trois axes</strong>. </p>
<p align="justify">Ainsi, pour que l&#8217;augmentation des dépendances entre services et équipes n&#8217;aboutisse pas à une paralysie générale lors de la transformation du SI vers une architecture de services, les équipes devront maîtriser les outils et méthodes de l&#8217;amélioration continue : développement incrémental et itératif, testabilité du SI, architecture organique, standards émergeants, responsabilisation des hommes</p>
<div align="left"><font size="2"></font><font color="#808080">Issu de discussions &nbsp;&raquo; endiablées &nbsp;&raquo; avec Damien Joguet, Dominique Jocal, Eric Biernat et Pierre Pezziardi    ;o)</font></div>

 <img src="http://blog.octo.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=161" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.octo.com/de-la-reussite-durable-dune-demarche-soa/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>REST en JAVA avec la JSR-311</title>
		<link>http://blog.octo.com/rest-en-java-avec-la-jsr-311/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rest-en-java-avec-la-jsr-311</link>
		<comments>http://blog.octo.com/rest-en-java-avec-la-jsr-311/#comments</comments>
		<pubDate>Sat, 27 Sep 2008 13:28:21 +0000</pubDate>
		<dc:creator>Benoit Guillou</dc:creator>
				<category><![CDATA[Architecture et technologies]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[webservices]]></category>

		<guid isPermaLink="false">http://new-blog.octo.com/2008/09/27/rest-en-java-avec-la-jsr-311/</guid>
		<description><![CDATA[<meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <meta name="ProgId" content="Word.Document" /> <meta name="Generator" content="Microsoft Word 11" /> <meta name="Originator" content="Microsoft Word 11" /> <link rel="File-List" href="file:///C:%5CDOCUME%7E1%5Cbeg%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C12%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>   Normal   0   21   false   false   false   MicrosoftInternetExplorer4 </xml>< ![endif]--><!--[if gte mso 9]>< ![endif]--><style type="text/css"> <!--  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	font-size:12.0pt;"Times New Roman"; 	mso-fareast-"Times New Roman";} @page Section1 	{size:612.0pt 792.0pt; 	margin:70.85pt 70.85pt 70.85pt 70.85pt;} div.Section1 	{page:Section1;} --></style><!--[if gte mso 10]> <style>  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:"Tableau Normal"; 	mso-style-parent:""; 	font-size:10.0pt;"Times New Roman";} </style> < ![endif]-->La <a href="http://jcp.org/en/jsr/detail?id=311"><strong>JSR 311</strong> <strong>JAX-RS</strong></a> est le pendant REST de la <a href="http://jcp.org/en/jsr/detail?id=224"><strong>JSR 224 JAX-WS</strong></a>.Elle marque la volonté de la part de la communauté Java de cadrer, tout comme pour la stack WS-*, le développement des applications JAVA orientées ressources. Bien qu'étant sur le point d'être finalisée (elle vient de passer le <a href="http://www.infoq.com/news/2008/09/jsr311-approved">Final Approval Ballot</a>), elle est déjà implémentée par la plupart des frameworks REST du moment (Jersey, RESTeasy, CXF, une extension existe pour Restlet, ...). La suite de ce billet présente les annotations de la JSR en regard des principes REST qu'elles mettent en oeuvre. <script type="text/javascript"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta><meta name="ProgId" content="Word.Document"></meta><meta name="Generator" content="Microsoft Word 11"></meta><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5Cbeg%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C12%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>   Normal   0   21   false   false   false   MicrosoftInternetExplorer4 </xml>< ![endif]--><!--[if gte mso 9]>< ![endif]--><style> <!--  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	font-size:12.0pt;"Times New Roman"; 	mso-fareast-"Times New Roman";} @page Section1 	{size:612.0pt 792.0pt; 	margin:70.85pt 70.85pt 70.85pt 70.85pt;} div.Section1 	{page:Section1;} --> </style><!--[if gte mso 10]> <style>  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:"Tableau Normal"; 	mso-style-parent:""; 	font-size:10.0pt;"Times New Roman";} </style> < ![endif]--> <p>La <b>JSR 311</b> <b>JAX-RS</b> [<i>Java</i><i><sup>TM</sup> API for RESTful Web Services]</i> est le pendant REST de la <b>JSR 224 JAX-WS</b> <i> [Java</i><i><sup>TM</sup> API for XML-Based Web Service].</i> Elle marque la volonté de la part de la communauté Java de cadrer, tout comme pour la stack WS-*, le développement des applications JAVA orientées ressources. Bien qu’étant sur le point d’être finalisée (dernier stade : <i>Final Approval Ballot</i>), elle est déjà implémentée par la plupart des frameworks REST du moment (Jersey, RESTeasy, CXF, une extension Restlet…). </p> <p>La suite de ce billet présente les annotations de la JSR en regard des principes REST qu’elles mettent en œuvre. </p> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); </link></meta></script><script type="text/javascript"> var pageTracker = _gat._getTracker("UA-3350117-4"); pageTracker._initData(); pageTracker._trackPageview(); </script>
Suggestion d'articles :<ol>
<li><a href='http://blog.octo.com/des-principes-rest-pour-realiser-du-mashup/' rel='bookmark' title='Des principes (ou quelques idées&#8230;) REST et du Mashup'>Des principes (ou quelques idées&#8230;) REST et du Mashup</a></li>
<li><a href='http://blog.octo.com/la-strategie-de-test-dune-architecture-rest-13-test-dintegration/' rel='bookmark' title='La stratégie de test d&#8217;une architecture REST (2/3) &#8211; Test d’intégration'>La stratégie de test d&#8217;une architecture REST (2/3) &#8211; Test d’intégration</a></li>
<li><a href='http://blog.octo.com/la-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource/' rel='bookmark' title='La stratégie de test d&#8217;une architecture REST (1/3) &#8211; Test unitaire d’une ressource'>La stratégie de test d&#8217;une architecture REST (1/3) &#8211; Test unitaire d’une ressource</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fblog.octo.com%252Frest-en-java-avec-la-jsr-311%252F%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22REST%20en%20JAVA%20avec%20la%20JSR-311%22%20%7D);"></div>
<p>La <b>JSR 311</b> <b>JAX-RS</b> [<i>Java</i><i><sup>TM</sup> API for RESTful Web Services]</i> est le pendant REST de la <b>JSR 224 JAX-WS</b> <i> [Java</i><i><sup>TM</sup> API for XML-Based Web Service].</i> Elle marque la volonté de la part de la communauté Java de cadrer, tout comme pour la stack WS-*, le développement des applications JAVA orientées ressources. Bien qu’étant sur le point d’être finalisée (dernier stade : <i>Final Approval Ballot</i>), elle est déjà implémentée par la plupart des frameworks REST du moment (Jersey, RESTeasy, CXF, une extension Restlet…). </p>
<p>La suite de ce billet présente les annotations de la JSR en regard des principes REST qu’elles mettent en œuvre. </p>
<p><span id="more-126"></span></p>
<p>Quels sont donc les apports de cette JSR dans le développement d&#8217;applications Java orientées ressources ? Afin de respecter le style architectural REST, il est nécessaire de suivre certaines règles. Ces règles vous pouvez les retrouver dans la <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">thèse </a>de Roy Fielding, le livre <a href="http://oreilly.com/catalog/9780596529260/">Restful Web Services</a> ou avec une simple recherche sur le Web. Dans cet article, je me suis librement inspiré d&#8217;une <a href="http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-5425&#038;yr=2008&#038;track=nextweb">présentation </a>de Paul Sandoz (commiteur Jersey / JSR-311) à Java One. Les exemples de code présentés utilisent Jersey <sup>[1]</sup>.</p>
<div> </div>
<div><strong><font size="5">Principe 1 &#8211; Give everything an ID : Une ressource / un identifiant<br /></font></strong></div>
<h2>
<p>La ressource REST</p>
</h2>
<p>En REST, une ressource représente une chose suffisamment importante à vos yeux pour être référencée. Ce n&#8217;est pas obligatoirement l&#8217;exposition d&#8217;un tuple de votre base de données. Cela peut tout aussi bien être le résultat d&#8217;un algorithme, un document, une liste d&#8217;objets sérialisés, &#8230; De manière générale, tout ce qui peut être stocké sur un ordinateur ou représenté sous la forme d&#8217;un flux de bits peut être considéré comme une ressource. </p>
<p>Les exemples présentés ci-après ont été développés grâce à Jersey, la RI (<i>Reference Implementation</i>) de Sun, qui semble à l’heure actuelle, être le framework REST plus mature. La version 1.0 devrait paraître à la fin du mois de Septembre. Il est dors et déjà utilisable en version 0.9 avec de multiples fonctionnalités (intégration avec Spring, client de test, …). Le but de cet article n’étant pas d’exposer les fonctionnalités de Jersey, nous resterons concentrés sur les spécificités de la JSR-311. Un article dédié à l’utilisation de Jersey paraîtra prochainement sur ce même blog.</p>
<p>On référence une ressource en lui associant un identifiant unique : on s&#8217;appuie sur la notion d&#8217;URI du protocole HTTP. C&#8217;est le moyen univoque d&#8217;accéder à une ressource. </p>
<h3>
<div>Quelques exemples d&#8217;URI </div>
</h3>
<ul>
<li>
<p>http://www.monserveur.com/customers : Pointe sur l&#8217;ensemble des clients</p>
</li>
<li>
<p>http://www.monserveur.com/customers/12 : Pointe sur le client dont l&#8217;identifiant technique est 12</p>
</li>
<li>
<p>http://www.monserveur.com/orders/XXXX/customers : Pointe sur les clients dont l&#8217;ordre à pour identifiant XXXX</p>
</li>
</ul>
<h2>
<div>Annotation @Path</div>
</h2>
<p>La JSR-311 définit l&#8217;annotation @Path : elle permet de lier une ressource à une URI.</p>

<div class="wp_codebox"><table><tr id="p12613"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p126code13"><pre class="java" style="font-family:monospace;">@Path<span style="color: #009900;">&#40;</span>“<span style="color: #339933;">/</span>customers”<span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CustomersResource <span style="color: #009900;">&#123;</span>
@GET
<span style="color: #000000; font-weight: bold;">public</span> Customer getCustomer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>…<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<div>On accède à la racine de la ressource <em>Customers</em> par le chemin <em>http://monServeur/monContexte/customers</em></div>
<div> </div>
<div>
<h2>Annotations @Path, @PathParam, @QueryParam</h2>
<p> L&#8217;annotation @Path en combinaison avec les @PathParam / @QueryParam permet de gérer les URLs paramètrables.</p>
<p>Vous souhaitez accéder à une ressource Customer, dont l&#8217;identifiant unique est son adresse mail.  On souhaite donc effectuer une requête du type : GET <em>http://monServeur/monContexte/customers/toto@toto.com</em></div>

<div class="wp_codebox"><table><tr id="p12614"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p126code14"><pre class="java" style="font-family:monospace;">@Path<span style="color: #009900;">&#40;</span>“<span style="color: #339933;">/</span>customers”<span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CustomersResource <span style="color: #009900;">&#123;</span>
@GET
@Path<span style="color: #009900;">&#40;</span>“<span style="color: #339933;">/</span><span style="color: #009900;">&#123;</span>email<span style="color: #009900;">&#125;</span>”<span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> Customer getCustomer<span style="color: #009900;">&#40;</span>@PathParam<span style="color: #009900;">&#40;</span>“email”<span style="color: #009900;">&#41;</span> <span style="color: #003399;">String</span> emailAddress<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>…<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<div>@Path gère donc les URLs paramétrables de type : http://monServeur/monContexte/customers/{email}. @PathParam(&laquo;&nbsp;email&nbsp;&raquo;) récupère la valeur {email} contenue dans URL paramètrable de ce type.</div>
<p>De même, @QueryParam(&laquo;&nbsp;maVar&nbsp;&raquo;) retourne la valeur du paramètre de l&#8217;url http://monServeur/monContexte/customers/{email}?maVar=12.</p>
<h1>
<div><strong><font size="5">Principe 2 &#8211; </font></strong><strong><font size="5">Use standard methods : utilisation </font></strong><strong><font size="5">des méthodes HTTP</font></strong></div>
</h1>
<h2></h2>
<p>Les architectures REST doivent respecter le standard HTTP, tant dans les codes retours que dans l&#8217;utilisation même des verbes HTTP (définie par la <strong><a href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</a></strong> ).<em> <meta name="ProgId" content="Word.Document" /> </p>
<table style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; background: rgb(153, 204, 255) none repeat scroll 0% 0%; width: 95.4pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="127">
<div align="center"><b>Méthodes</b></div>
</td>
<td style="border-style: solid solid solid none; border-color: windowtext windowtext windowtext -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; background: rgb(153, 204, 255) none repeat scroll 0% 0%; width: 365.2pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="487">
<div align="center"><b>But</b></div>
</td>
</tr>
<tr>
<td style="border-style: none solid solid; border-color: -moz-use-text-color windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 95.4pt;" valign="top" width="127">
<div align="center">GET</div>
</td>
<td style="border-style: none solid solid none; border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 365.2pt;" valign="top" width="487">
<p>Accéder à une ressource,   potentiellement en cache.</p>
</td>
</tr>
<tr>
<td style="border-style: none solid solid; border-color: -moz-use-text-color windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 95.4pt;" valign="top" width="127">
<div align="center">POST</div>
</td>
<td style="border-style: none solid solid none; border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 365.2pt;" valign="top" width="487">
<p>Créer une ressource (identifiant   inconnu)</p>
</td>
</tr>
<tr>
<td style="border-style: none solid solid; border-color: -moz-use-text-color windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 95.4pt;" valign="top" width="127">
<div align="center">PUT</div>
</td>
<td style="border-style: none solid solid none; border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 365.2pt;" valign="top" width="487">
<p>Créer / Mettre à jour une   ressource (identifiant connu)</p>
</td>
</tr>
<tr>
<td style="border-style: none solid solid; border-color: -moz-use-text-color windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 95.4pt;" valign="top" width="127">
<div align="center">DELETE</div>
</td>
<td style="border-style: none solid solid none; border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 365.2pt;" valign="top" width="487">
<div>Supprimer une ressource</div>
</td>
</tr>
<tr>
<td style="border-style: none solid solid; border-color: -moz-use-text-color windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 95.4pt;" valign="top" width="127">
<div align="center">HEAD</div>
</td>
<td style="border-style: none solid solid none; border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 365.2pt;" valign="top" width="487">
<p>Identique à GET mais aucun   contenu dans le corps la réponse. Utile notamment pour vérifier la validité   d’une ressource,  son accessabilité, …</p>
</td>
</tr>
</tbody>
</table>
<p></em></p>
<p>Ces méthodes permettent de manipuler des ressources désignées par leur URI . <br /> 
<ul>
<li>
<div> GET sur http://www.monserveur.com/customers : Totalité des clients</div>
</li>
<li>
<div>POST sur http://www.monserveur.com/customers : Création d&#8217;un client </div>
</li>
</ul>
<h2>
<div>@GET, @POST, @DELETE, @PUT, @HEAD</div>
</h2>
<div>

<div class="wp_codebox"><table><tr id="p12615"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p126code15"><pre class="java" style="font-family:monospace;">@GET
@Path<span style="color: #009900;">&#40;</span>“<span style="color: #339933;">/</span><span style="color: #009900;">&#123;</span>email<span style="color: #009900;">&#125;</span>”<span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> Customer getCustomer<span style="color: #009900;">&#40;</span>@PathParam<span style="color: #009900;">&#40;</span>“email”<span style="color: #009900;">&#41;</span> <span style="color: #003399;">String</span> emailAddress<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>…<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Dans l&#8217;exemple ci-dessus, l&#8217;annotation @GET, associée au @Path, permet de router toutes les requêtes de type GET /customers/{email} sur la méthode getCustomer(String email). @GET, @POST, @DELETE, @PUT, @HEAD agissent simplement en combinaison de @PATH comme un <em>dispatcher</em>.</p>
<h1>
<div><strong><font size="5">Principe 3 &#8211; </font></strong><strong><font size="+0"><strong><font size="5">Link things together :</font></strong></font></strong> <strong><font size="5">Lier les ressources entre elles.</font></strong></div>
</h1>
<p>Afin de permettre la navigabilité entre les ressources exposées, il est nécessaire de les lier entres elles. </p>
<p><span lang="FR"><code><span lang="FR"><img height="93" width="402" border="1" src="/wp-content/uploads/images/customerxml.JPG" alt="" /></span></code> </span></p>

<div class="wp_codebox"><table><tr id="p12616"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p126code16"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Context</span>
<span style="color: #000000; font-weight: bold;">private</span> UriInfo uriInfo<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Injecté directement dans la ressource</span>
…
<span style="color: #666666; font-style: italic;">// Récupere le path courant</span>
UriBuilder uriBuilder <span style="color: #339933;">=</span> uriInfo.<span style="color: #006633;">getAbsolutePathBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Crée l’uri pour accéder à la nouvelle ressource</span>
URI uri <span style="color: #339933;">=</span> uriBuilder.<span style="color: #006633;">path</span><span style="color: #009900;">&#40;</span>customer.<span style="color: #006633;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">build</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Retourne la réponse avec la nouvelle ressource</span>
<span style="color: #000000; font-weight: bold;">return</span> Response.<span style="color: #006633;">created</span><span style="color: #009900;">&#40;</span>uri<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">entity</span><span style="color: #009900;">&#40;</span>customer<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">build</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Dans cet exemple, on utilise les champs location et entity définit dans une  réponse HTTP : </p>
<ul>
<li>
<p> <span style="font-style: italic;">location : l&#8217;uri de nouvelle ressource Customer </span></p>
</li>
<li><span style="font-style: italic;">entity : représentation de la ressource Customer créé. </span></li>
</ul>
<div><strong><font size="5">Principe 4 &#8211; Multiple representations : Multiplicité des représentations</font></strong></div>
<p>Pour une ressource, identifiée par une URI, on peut avoir de multiples représentations.</p>
<p>Les plus courantes étant : </p>
<ul>
<li>
<p>XML</p>
</li>
<li>
<p>JSON</p>
</p>
</li>
<li>
<p>(X)HTML</p>
</p>
</li>
<li>
<p>ATOM</p>
</li>
</ul>
<p>Ce principe repose sur la négociation de contenu possible grâce à HTTP. A l&#8217;envoi d&#8217;une requête HTTP, le champ <span style="font-style: italic;">Accept défini dans le header de la requête http, peut prendre plusieurs valeurs (classés par ordre de préférences) et permet de choisir le format de représentation mise à disposition pour la ressource.<br clear="all" /></span></p>
<p>Exemple d&#8217;un GET sur maps.google.fr avec Firefox<br /><a href="http://news.google.fr/nwshp?hl=fr&#038;tab=wn"> </p>
<p></a></p>
<p><code><br />
GET Host maps.google.fr<br />
User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1<br />
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8<br />
Accept-Language fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3<br />
Accept-Encoding gzip,deflate<br />
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7<br />
Keep-Alive 300<br />
Connection keep-alive<br />
Referer http://news.google.fr/nwshp?hl=fr&#038;tab=wn<br />
</code></p>
<h2>@Produces, @Consumes</h2>
<p>On accède à partir d&#8217;une unique URL à une multiplicité de représentations d&#8217;une même ressource. On utilisera les annotations @Produces et @Consumes pour gérer en entrée / sortie les multiples représentations d&#8217;une ressource.</p>
<ul>
<li>
<p>@Produces : désigne le format de représentation de la ressource.</p>
</li>
<li>
<p>@Consumes : désigne le format de consommation de la méthode Java.</p>
</li>
</ul>

<div class="wp_codebox"><table><tr id="p12617"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p126code17"><pre class="java" style="font-family:monospace;">@GET
&nbsp;
@Consumes<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>”application<span style="color: #339933;">/</span>xml”<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
&nbsp;
@Produces<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>”application<span style="color: #339933;">/</span>xml”,”application<span style="color: #339933;">/</span>json”<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
&nbsp;
Order getOrder<span style="color: #009900;">&#40;</span>@PathParam<span style="color: #009900;">&#40;</span>”order_id”<span style="color: #009900;">&#41;</span> <span style="color: #003399;">String</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
…
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>La méthode getOrder consomme du XML et peut produire en fonction du client, un représentation  XML ou JSON.</p>
<h2>@Provider</h2>
<p>La notion de <em>Provider</em> peut intervenir lorsque l&#8217;on souhaite gérer finement la représentation de ses ressources. En effet, la majorité des frameworks REST offre de base la capacité de sérialiser/désérialiser des beans JAXB (soit en utilisant des annotations, soit générés à partir d&#8217;un XSD).  Le Provider autorise un traitement spécifique en entrée et / ou en sortie sur un objet Java. </p>

<div class="wp_codebox"><table><tr id="p12618"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code" id="p126code18"><pre class="java" style="font-family:monospace;">@Produces<span style="color: #009900;">&#40;</span>”text<span style="color: #339933;">/</span>plain”<span style="color: #009900;">&#41;</span>
&nbsp;
Content getContent<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
…
&nbsp;
<span style="color: #000000; font-weight: bold;">return</span> content<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Dans cet exemple, une méthode retourne une représentation text/plain d&#8217;une ressource <em>Content</em>. Pour maitriser le formatage en sortie de cet objet, nous pouvons définir notre propre <em>Provider</em> de <em>Content</em>.</p>

<div class="wp_codebox"><table><tr id="p12619"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p126code19"><pre class="java" style="font-family:monospace;">@Produces<span style="color: #009900;">&#40;</span>”text<span style="color: #339933;">/</span>plain”<span style="color: #009900;">&#41;</span>
@<span style="color: #003399;">Provider</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ContentProvider <span style="color: #000000; font-weight: bold;">implements</span> MessageBodyWriter <span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> writeTo<span style="color: #009900;">&#40;</span>Content p,<span style="color: #000000; font-weight: bold;">Class</span> type, Type genericType, <span style="color: #003399;">Annotation</span> annotations<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>,MediaType mediaType, MultivaluedMapOutputStream out<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span> <span style="color: #009900;">&#123;</span>
&nbsp;
out.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span>”<span style="color: #009900;">&#91;</span>Content<span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> “<span style="color: #339933;">+</span> content.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>…
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Il nous est possible d&#8217;utiliser le même méchanisme pour créer une représentation HTML si notre client est un browser, du JSON si c&#8217;est un client AJAX, du XML si c&#8217;est une application, etc. </p>
<div>
<h2>@Provider / ExceptionMapper </h2>
</p></div>
<p>Un <em>Provider</em> peut vous être utile pour traiter les cas d&#8217;erreur. En effet, il est possible de mapper une exception vers une réponse HTTP spécifique. Vous n&#8217;avez surement pas envie de polluer votre code d&#8217;exposition avec de multiples  try / catch pour renvoyer :</p>
<ul>
<li>
<p>si c&#8217;est une IllegalArgumentException : un BAD_REQUEST</p>
</p>
</li>
<li>
<p>si c&#8217;est un CustomerNotFound : un NOT_FOUND</p>
</li>
</ul>
<p>Pour se faire, le composant <span style="font-style: italic;">ExceptionMapper<monexception></monexception><span style="font-style: italic;"> est un <em>Provider</em> qui  permet d&#8217;attraper toutes les exceptions d&#8217;un certain type et de renvoyer une réponse selon vos désidératas :</span></span></p>
<p>Par exemple, vous souhaitez renvoyer BAD_REQUEST dès qu&#8217;est levée une exception de type IllegalArgumentException.</p>
<p></p>

<div class="wp_codebox"><table><tr id="p12620"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p126code20"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Provider</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> RuntimeMapper <span style="color: #000000; font-weight: bold;">implements</span> ExceptionMapper <span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> Logger logger <span style="color: #339933;">=</span> Logger.<span style="color: #006633;">getLogger</span><span style="color: #009900;">&#40;</span>getClass<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> Response toResponse<span style="color: #009900;">&#40;</span><span style="color: #003399;">IllegalArgumentException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">return</span> Response.<span style="color: #006633;">status</span><span style="color: #009900;">&#40;</span>Status.<span style="color: #006633;">BAD_REQUEST</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">entity</span><span style="color: #009900;">&#40;</span>e.<span style="color: #006633;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">build</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h1>Conclusion</h1>
<p>Comme évoqué précédemment la JSR-311 encadre le développement des applications REST. Les annotations permettent de mettre en oeuvre certains principes REST de manière concise, le code d&#8217;exposition s&#8217;en trouvant par la même occasion allégé. En lisant le code JAVA d&#8217;une ressource, il est très simple de voir à quelle URI elle est attachée, le format de consommation / exposition sans être gêné par la génération des codes d&#8217;erreurs ou l&#8217;étape de marshalling / unmarshalling des ressources par exemple.  Cependant, ce n&#8217;est qu&#8217;un framework technique à la disposition du développeur. Le design de ressources reste une étape primordiale dans la mise en oeuvre d&#8217;une architecture orientée ressources. La JSR ne générera pas pour vous une architecture RESTful mais vous permettra de les exposer au plus vite.</p>
<p>
<sup>[1]</sup><br />
<em>Les exemples présentés ont été développés grâce à Jersey , la RI (Reference Implementation) de Sun, qui semble à l&#8217;heure actuelle, être le framework REST plus mature. La version 1.0 devrait paraître à la fin du mois de Septembre. Il est dors et déjà utilisable en version 0.9 avec de multiples fonctionnalités (intégration avec Spring, client de test, &#8230;). Le but de cet article n&#8217;étant pas d&#8217;exposer les fonctionnalités de Jersey, nous sommes restés concentrés sur les spécificités de la JSR-311. Un article dédié à l&#8217;utilisation de Jersey paraîtra prochainement sur ce même blog.</em></p>
</div>

 <img src="http://blog.octo.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=126" width="1" height="1" style="display: none;" /><p>Suggestion d'articles :</p><ol>
<li><a href='http://blog.octo.com/des-principes-rest-pour-realiser-du-mashup/' rel='bookmark' title='Des principes (ou quelques idées&#8230;) REST et du Mashup'>Des principes (ou quelques idées&#8230;) REST et du Mashup</a></li>
<li><a href='http://blog.octo.com/la-strategie-de-test-dune-architecture-rest-13-test-dintegration/' rel='bookmark' title='La stratégie de test d&#8217;une architecture REST (2/3) &#8211; Test d’intégration'>La stratégie de test d&#8217;une architecture REST (2/3) &#8211; Test d’intégration</a></li>
<li><a href='http://blog.octo.com/la-strategie-de-test-d-une-architecture-rest-1-3-test-unitaire-dune-ressource/' rel='bookmark' title='La stratégie de test d&#8217;une architecture REST (1/3) &#8211; Test unitaire d’une ressource'>La stratégie de test d&#8217;une architecture REST (1/3) &#8211; Test unitaire d’une ressource</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.octo.com/rest-en-java-avec-la-jsr-311/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

