Appeler un service web externe depuis Salesforce

Comment pouvons-nous appeler un web service hébergé sur un domaine distant depuis Salesforce ?

Commentez Donner une note à l'article (5)

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Il peut arriver d'appeler une fonctionnalité disponible sur un domaine distant du nôtre afin d'importer des données ou d'exécuter un traitement. Par exemple, nous pouvons vouloir accéder aux informations de l'utilisateur disponible sur le domaine A ou alors de modifier ses informations. De même qu'à titre informatif, énormément de sites internet proposent leur propre service web tels que TwitterTwitter, FacebookFacebook ou encore AppleApple (iTunes). Depuis l'API d'iTunes, vous avez la possibilité de faire une recherche avec des mots-clés (paramètre term) en spécifiant le store (paramètre country), le nombre de résultats désirés (paramètre limit) ou encore le type de résultat affiché (paramètre entity) (films, musiques, livres, etc.). Dans ce tutoriel, nous allons étudier comment appeler un service web externe à partir de Salesforce. Il faut savoir que généralement, les services web répondent avec un format JSON ou XML, mais ce n'est pas le cas de Salesforce, il examine la réponse et génère automatiquement une classe avec ses propriétés contenant le résultat de la requête ainsi que le client adéquat.

Pour ce faire, nous allons avoir besoin d'un fichier WSDL que nous allons par la suite transmettre à Salesforce pour qu'il puisse générer tout seul la classe Apex grâce à WSDL2Apex qui servira de client.

Avant d'aller plus loin, je vous propose quelques rappels sur les termes qui vont être abordés tout au long de ce tutoriel :

SalesforceSalesforce est un CRM (Customer Relationship Manager) orienté SaaSSaaS (Software as a Service) et PaaSPaaS (Platform as a Service) permettant la gestion des relations clients d'une entreprise ;

XMLXML (Extensible Markup Language) signifiant Langage de Balisages Extensibles est un format de fichier permettant de définir différents espaces de noms pour y placer différents langages de programmation accompagnés de leurs spécificités (vocabulaire et grammaire) ;

JSONJSON (JavaScript Object Notation) est un format de données permettant de représenter des données comme le permet XML ;

WSDLWSDL (Web Services Description Language) est comme son nom l'indique, un fichier au format XML décrivant le web service, c'est-à-dire les méthodes que vous pouvez appeler avec les paramètres attendus, la valeur de retour ainsi que les types de ces valeurs et l'URL d'appel de ce web service pour faire simple ;

Apex, est un langage de programmation côté serveur permettant de modifier la logique métier et le traitement des données.

II. Prérequis

Avant toute chose, vous devez disposer d'une instance afin de pouvoir suivre ce tutoriel. Si ce n'est pas le cas, je vous invite à vous rendre à cette adresseadresse. Salesforce met à disposition plusieurs types d'instances qui proposent différentes fonctionnalités et donc, à différents prix (prix par licence utilisateur par mois). La seule instance que vous pourrez généreusement obtenir de la part de Salesforce est celle de développement (celle que je vous propose via le lien du dessus) qui, comme son nom l'indique, sert à tester et développer des services. Je vous laisse juger par vous-même la grille tarifairegrille tarifiare sur les diverses instances que propose le CRM.

III. Bien construire son WSDL

Maintenant que nous possédons notre instance Salesforce (vous pouvez vous y connecter à l'adresse login.salesforce.comlogin.salesforce.com), nous devons avoir notre WSDL en notre possession afin de le transmettre à Salesforce, mais pas de souci, je vous en propose un (disponible à la fin de ce tutoriel dans les ressources). Le service web que nous allons invoquer propose les mêmes services qu'une simple calculatrice, nous allons pouvoir :

  • additionner ;
  • soustraire ;
  • multiplier ;
  • diviser.

Malgré ma faible expérience en ce qui concerne les WSDL, j'ai jusqu'à ce jour été confronté à de multiples reprises à des refus de la part du CRM de Salesforce pour valider mes WSDL suite à leur mauvaise structure (Salesforce juge mal construit) et j'ai dû par conséquent, les modifier moi-même. Je vais vous citer plusieurs messages d'erreur que vous pouvez rencontrer avec leurs explications et leurs solutions. À noter qu'un message d'erreur peut avoir plusieurs causes et plusieurs solutions.

Voici donc quelques messages d'erreur que vous êtes susceptible d'obtenir :

Unable to find schema for element; {http://tempuri.org/}GetConsumerData

Comme son nom l'indique, le schéma (la description) pour l'élément GetConsumerData n'est pas connu de Salesforce (il ne le trouve pas dans votre WSDL). Vous pouvez vérifier que votre élément est bien disposé dans le même namespace que son appelant, ou vérifier que vous n'avez pas un schéma imbriqué dans un second schéma.

Error: Failed to parse wsdl: Found schema import from location http://127.0.0.1/?xsd=xsd0. External schema import not supported

Cela signifie que la définition de vos schémas ne doit pas être accessible via une URL, le WSDL doit donc être « plat » et pour cela, vous devez copier le contenu du schéma via l'URL et ensuite le coller à l'intérieur du WSDL.

Error: Failed to parse wsdl: Found more than one wsdl:binding

Votre WSDL contient sûrement plusieurs balises wsdl:binding, vous devez soit supprimer le contenu de la deuxième (ou de la première suivant votre besoin) soit de supprimer celui comportant les éléments soap12 puisque cela n'est pas supporté par Salesforce.

Error: Failed to parse wsdl: schema:targetNamespace can not be null

Vous avez besoin d'ajouter un paramètre targetNamespace ainsi qu'une value à l'intérieur de l'élément schéma. Vous pouvez choisir n'importe quel espace de nom, http://toto.com ferait très bien l'affaire.

Error: Failed to parse wsdl: Unsupported Schema element found http://www.w3.org/2001/XMLSchema:attribute. At: 310:64

Vous devez sûrement avoir ces attributs quelque part dans votre WSDL :

 
Sélectionnez
<xs:attribute name="FactoryType" type="xs:QName" />
<xs:attribute name="Id" type="xs:ID" />
<xs:attribute name="Ref" type="xs:IDREF" />

Vous pouvez les remplacer par ceux-ci :

 
Sélectionnez
<xs:element name="FactoryType" nillable="true" type="xs:string" />
<xs:element name="Id" nillable="true" type="xs:string" />
<xs:element name="Ref" nillable="true" type="xs:string" />

Je partage également un articlearticle de Daniel Ballinger qui m'a fortement été utile à comprendre certains de ces messages d'erreur.

IV. Autoriser votre site dans Salesforce

Afin que vous puissiez faire appel au web service, vous devez faire connaître son domaine à Salesforce, dans notre cas, il s'agit de http://ws1.parasoft.com/glue/calculator. Connectez-vous à votre instance Salesforce et rendez-vous à ce chemin « Setup => Administration Setup => Remote Site Settings ». Une fois à destination, cliquez sur « New Remote Site » et renseignez les champs obligatoires demandés (le nom et l'URL du domaine) puis cochez la checkbox pour rendre ce domaine actif et enfin, validez le tout.

N'oubliez pas de spécifier le numéro du port si celui-ci est différent de 80, par exemple : http://ws1.parasoft.com/glue/calculator:1024


Salesforce n'accepte pas tous les ports, veillez bien à ce que celui-ci soit l'un de ceux-ci :

  • 80 (HTTP) ;
  • 443 (HTTPS) ;
  • [1024 - 65535] (pas besoin d'être administrateur pour pouvoir les utiliser).
Image non disponible

V. Générer le client à l'aide de votre WSDL

Une fois notre domaine accepté par Salesforce, il est temps de lui transmettre notre WSDL pour qu'il puisse générer tout seul le client (une classe Apex) grâce à WSDL2Apex. Rendez-vous à « Setup => App Setup => Develop => Apex Classes ». Ensuite, cliquez sur « Generate from WSDL » et donnez votre WSDL à Salesforce pour qu'il le parse et qu'il s'assure qu'il est valide (bien formé), il ne doit pas être plus gros que 1MB.

Image non disponible

Dans le cas où il ne parvient pas à le parser correctement, vous obtiendrez un message d'erreur (voir chapitre III. Bien construire son WSDL). Maintenant que le WSDL est bien parsé, Salesforce vous proposera de choisir les noms de vos sous-classes (il vous demandera autant de noms que votre document comporte de namespaces), mais il vous en proposera automatiquement en fonction de vos espaces de noms.

Image non disponible

Maintenant que vous avez choisi vos noms, il ne vous reste plus qu'à valider. Si par bonheur tout se passe bien, votre client sera automatiquement généré, mais dans le cas contraire, vous obtiendrez un message d'erreur avec, en prime, le code qui aurait dû être généré dans un champ de type « textarea » (je vous rappelle que je vous mets à disposition en bas de l'article, le WSDL que j'utilise pour ce tutoriel et il est accepté sans souci par Salesforce).

Si dans votre WSDL, vous utilisez des noms réservés en tant que nom pour des éléments, par exemple long ou int, Salesforce les renommera automatiquement en rajoutant un __x, ce qui donne long__x pour long, vous l'aurez bien compris.

VI. Appel du service web

Tout le travail est presque fini, il ne nous reste plus qu'à appeler notre web service, nous allons joindre la méthode additionner en lui fournissant comme demandé, deux paramètres de type double : 5.2 et 3.7. La méthode devrait donc nous retourner en principe 8.9.

 
Sélectionnez
Double double1 = 5.2;
Double double2 = 3.7;
CalculatorWebService.ICalculator myWebService = new CalculatorWebService.ICalculator();
myWebService.timeout_x = 120000;
Double result = myWebService.add(double1, double2);
System.debug('******');
System.debug(result);
System.debug('******');

Par défaut, Salesforce règle un timeout (attribut timeout__x (en millisecondes) correspondant au nom de la classe de votre balise binding) de 10 secondes, mais il est tout à fait possible de le modifier arbitrairement en spécifiant une valeur allant jusqu'à 120 secondes, c'est ce qui est fait pour l'exemple.

Et voici le résultat :

Image non disponible

Nous pouvons constater que le web service nous retourne bien le résultat de 8.9 comme prévu.

VII. Conclusion

Nous arrivons à la fin de ce tutoriel, vous avez pu constater que d'un côté, Salesforce est très capricieux en ce qui concerne le fait d'accepter un WSDL, mais d'un autre côté, une fois que vous avez passé l'étape de son parsage, c'est pratiquement gagné puisqu'il génère tout seul un client grâce à WSDL2Apex, nous pouvons donc penser que c'est un mal pour un bien.

Pour résumer le tout, vous devez :

  • renseigner le domaine de votre service web à Salesforce pour que vous puissiez l'appeler ;
  • fournir un WSDL à Salesforce qu'il va par la suite parser, analyser et s'en inspirer pour générer le client (une à plusieurs classes Apex) ;
  • appeler votre service web.

VIII. Ressources

Comme je vous l'avais promis, je vous fournis le WSDL (iciWSDL) utilisé durant cet article pour que vous soyez certain- qu'il est accepté et que vous puissiez vérifier, par vous-même, ce que j'ai dit.

De plus, voici quelques liens qui concernent la documentation officielle de Salesforce sur ce qu'il faut savoir à propos des web services, cela peut vous être utile :

. Appeler un webservice externe depuis SalesforceAppeler un webservice externe depuis Salesforce

. Création d'un client à partir d'un WSDLCréation d'un client à partir d'un WSDL

IX. Remerciements

Je souhaite remercier tous ceux qui ont permis à cet article de voir le jour, je parle de vermine et de Viduc.

En complément sur Developpez.com

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2013 Aurélien Laval. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.