{"id":737,"date":"2019-06-18T17:43:12","date_gmt":"2019-06-18T16:43:12","guid":{"rendered":"http:\/\/wollef.org\/?p=737"},"modified":"2019-06-18T17:43:12","modified_gmt":"2019-06-18T16:43:12","slug":"se-connecter-au-cloud-mercedes-depuis-salesforce","status":"publish","type":"post","link":"https:\/\/wollef.org\/blog\/se-connecter-au-cloud-mercedes-depuis-salesforce\/","title":{"rendered":"Le module de gestion de la connexion de Salesforce vers Mercedes Cloud (1\/3) : Techniques utilis\u00e9es"},"content":{"rendered":"<p>Dans les deux premi\u00e8res parties nous avons <a href=\"http:\/\/wollef.org\/fr\/connectons-nous-au-serveur-cloud-de-mercedes-12-utiliser-les-api-avec-curl\/\">parl\u00e9 de l\u2019API Mercedes et on l\u2019a utilis\u00e9e \u2018\u00e0 la main\u2019 avec CuRL en ligne de commande<\/a>, puis on a regard\u00e9 comment <a href=\"http:\/\/wollef.org\/fr\/a-la-decouverte-de-salesforce-creer-son-compte-et-configurer\/\">utiliser et configurer Salesforce,<\/a>\u00a0 puis\u00a0\u00a0<a href=\"http:\/\/wollef.org\/fr\/a-la-decouverte-de-salesforce-developper-des-composants-visuels\/\">programmer des composants visuels avec Salesforce<\/a>\u00a0et enfin comment <a href=\"http:\/\/wollef.org\/fr\/a-la-decouverte-de-salesforce-stocker-des-donnees-sur-le-serveur-salesforce\/\">stocker\u00a0et lire en mode programmation des\u00a0donn\u00e9es dans Salesforce<\/a>.<\/p>\n<p>Maintenant, on regarde comment programmer ces API Mercedes que l&#8217;on a manipul\u00e9 en CuRL avec les outils de programmation de Salesforce.<\/p>\n<h1><a name=\"_Toc6859841\"><\/a>1.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 La page qui permet de recevoir l\u2019autorisation<\/h1>\n<p>Quand on appel\u00e9 le m\u00e9canisme de Mercedes pour obtenir le code d\u2019autorisation, on allait sur une URL Mercedes avec nos donn\u00e9es de l\u2019application (dont le client id) , c\u2019\u00e9tait l\u2019\u00e9tape A\u00a0; puis l\u2019utilisateur tapait ses donn\u00e9es de connexion pour autoriser l\u2019application (\u00e9tape B)\u00a0; et enfin Mercedes renvoyait sur une page de l\u2019application en passant le code d\u2019autorisation en param\u00e8tre (\u00e9tape C).<\/p>\n<p>L\u2019URL de l\u2019\u00e9tape C ressemblait \u00e0 ceci, avec le code obtenu en rouge\u00a0:<\/p>\n<p><strong>https:\/\/localhost\/<\/strong>?<strong>code<\/strong>=<span style=\"color: red;\">6e9d89c4-a374-4bb9-8c88-673034f87342<\/span><\/p>\n<p>Parce qu\u2019on avait dit que la redirect URL de l\u2019application \u00e9tait <strong>https:\/\/localhost\/<\/strong>.<\/p>\n<p>En Salesforce on a besoin de faire une page web qui va savoir lire le param\u00e8tre <strong>code<\/strong> pour qu\u2019on puisse l\u2019utiliser par la suite.<\/p>\n<p>Le code de la page est simple. Ce sera une page Visual Force, vide pour le moment<\/p>\n<pre><code>&lt;apex:page controller=\"<strong>Mercedes_API_Authorization_Ctrl<\/strong>\"&gt;\n&lt;\/apex:page&gt;\n<\/code><\/pre>\n<p>Avec un controller <strong>Mercedes_API_Authorization_Ctrl<\/strong> qui\u00a0:<\/p>\n<ul>\n<li>Stocke le code d\u2019autorisation (en bleu)<\/li>\n<li>Lit le param\u00e8tre pass\u00e9 quand la page se charge. (en orange).<\/li>\n<\/ul>\n<pre><code>public class <strong>Mercedes_API_Authorization_Ctrl<\/strong> {\n<strong>\u00a0\u00a0\u00a0 public String authorizationCode { get; set; }<\/strong>\n\u00a0\npublic Mercedes_API_Authorization_Ctrl(){\n<strong>   authorizationCode =<\/strong>\n<strong>apexpages.currentpage().getparameters().get('code');<\/strong>\n}\n}\n<\/code><\/pre>\n<p>Pour faire plus visible, on peut aussi modifier la page pour qu\u2019elle affiche le param\u00e8tre obtenu<\/p>\n<p>&lt;apex:page controller=&#8221;Mercedes_API_Authorization_Ctrl&#8221;&gt;<br \/>\n<strong>\u00a0 Authorization : {! authorizationCode}<\/strong><br \/>\n&lt;\/apex:page&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>On doit ajouter cette redirect URL \u00e0 l\u2019application d\u00e9clar\u00e9e chez Mercedes\u00a0:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-740\" src=\"http:\/\/wollef.org\/wp-content\/uploads\/2019\/10\/con1-1-300x167.png\" alt=\"\" width=\"551\" height=\"307\" \/><\/p>\n<p>Essayons d\u2019ouvrir la premi\u00e8re URL (etape A), avec la bonne redirect URL (en vert), puis suivons les \u00e9tapes, on arrive \u00e0\u00a0:<\/p>\n<pre><code>https:\/\/api.secure.mercedes-benz.com\/oidc10\/auth\/oauth\/v2\/authorize?response_type=code&amp;client_id=36f504aa-f141-41ad-93ae-09603cddf507&amp;redirect_uri=https%3A%2F%2Fc.eu16.visual.force.com%2Fapex%2FMercedes_API_Authorization&amp;scope=mb:user:pool:reader%20mb:vehicle:status:general\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<p>On sait r\u00e9cup\u00e9rer dans SF le code d&#8217;autorisation\u00a0!<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-741\" src=\"http:\/\/wollef.org\/wp-content\/uploads\/2019\/10\/con2-300x35.png\" alt=\"\" width=\"506\" height=\"59\" \/><\/p>\n<p>&nbsp;<\/p>\n<h1><a name=\"_Toc6859842\"><\/a>2.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Le code pour demander le jeton de session<\/h1>\n<p>&nbsp;<\/p>\n<p>Apr\u00e8s avoir re\u00e7u le code d\u2019autorisation, quand on travaillait \u00e0 la main\u00a0:<\/p>\n<ul>\n<li>on devait r\u00e9cup\u00e9rer les jetons de session<\/li>\n<li>on pouvait r\u00e9cup\u00e9rer les donn\u00e9es avec l\u2019API<\/li>\n<\/ul>\n<p>Maintenant on doit faire la m\u00eame chose qu&#8217;on faisait en Curl, mais en SF, avec le langage APEX.<\/p>\n<p>Avec CuRL, \u00e0 chaque fois\u00a0:<\/p>\n<ul>\n<li>on cr\u00e9ait la requ\u00eate (la commande tap\u00e9e)<\/li>\n<li>on l&#8217;ex\u00e9cutait (appel du serveur Mercedes par le serveur Salesforce), en lan\u00e7ant la commande<\/li>\n<li>on traitait le r\u00e9sultat (en le lisant)<\/li>\n<\/ul>\n<p>On va faire la m\u00eame chose en programmant.<\/p>\n<p>L\u2019appel CuRL pour l\u2019obtention de la session \u00e9tait<\/p>\n<pre><code>curl -X POST \"https:\/\/api.secure.mercedes-benz.com\/oidc10\/auth\/oauth\/v2\/token\" \\\n-H \"authorization: Basic ZGY4YTczYmUtYTY4Zi00.....hMWQwLWRjMmM0ZWI4MTU0ZA==\" \\\n-H \"content-type: application\/x-www-form-urlencoded\" \\\n-d \"grant_type=authorization_code&amp;code=297ded07-43ea-4fcc-ab73-6b6376d787ca&amp;redirect_uri=https%3A%2F%2Flocalhost.com\"<\/code><\/pre>\n<p>Le Code correspondant en Apex est<\/p>\n<ul>\n<li><strong>Pr\u00e9paration de la requ\u00eate<\/strong><\/li>\n<\/ul>\n<pre><code>\/\/ creation d\u2019une requ\u00eate HTTP\nHttpRequest req = new HttpRequest();\nreq.setMethod('POST');\n\n\/\/ vers le serveur Mercedes\nreq.setEndpoint('https:\/\/api.secure.mercedes-benz.com\/oidc10\/auth\/oauth\/v2\/token');\n\n\/\/ avec le bon code d\u2019auorisation\nreq.setHeader('authorization', 'Basic ZGY4YTczYmUtYTY4Zi0.....2NiZTMxYmUxMDM5OjBlYjRmMGE0LTM1YzgtNDc0Ny1hMWQwLWRjMmM0ZWI4MTU0ZA==');\nreq.setHeader('content-type', 'application\/x-www-form-urlencoded');\n\n\/\/ avec le message de demande de session\nString messageBody =\n'grant_type=authorization_code'\n+'&amp;code=297ded07-43ea-4fcc-ab73-6b6376d787ca'\u00a0\u00a0\u00a0 +'&amp;redirect_uri=https%3A%2F%2Fc.eu16.visual.force.com%2Fapex%2FMercedes_API_Authorization';\nreq.setBody(messageBody);<\/code><\/pre>\n<ul>\n<li><strong>Ex\u00e9cution de la requ\u00eate<\/strong><\/li>\n<\/ul>\n<pre><code>\/\/Execute de la requ\u00eate HTTP\nHttp http = new Http();\nHTTPResponse res = http.send(req);\n<\/code><\/pre>\n<ul>\n<li><strong>Lecture de la r\u00e9ponse et traitement<\/strong> (juste un affichage)<\/li>\n<\/ul>\n<pre><code>String jsonResponse = res.getBody();\n\nMap&lt;String, Object&gt; results = (Map&lt;String, Object&gt;)\n\nJSON.deserializeUntyped(jsonResponse);\n\nString access_token = (String)\u00a0 results.get('access_token');\nString token_type \u00a0 = (String)\u00a0 results.get('token_type');\nInteger expires_in = (Integer) results.get('expires_in');\nString refresh_token=\u00a0 (String)\u00a0 results.get('refresh_token');\nString scope \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = (String)\u00a0 results.get('scope');\n\nSystem.debug('access_token:' + access_token);\nSystem.debug('token_type:' + token_type);\nSystem.debug('expires_in:' + expires_in);\nSystem.debug('refresh_token:' + refresh_token);\nSystem.debug('scope:' + scope);\u00a0\n<\/code><\/pre>\n<p>Voici ce qu\u2019on obtient en debug quand on lance le code dans la Console<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-742\" src=\"http:\/\/wollef.org\/wp-content\/uploads\/2019\/10\/con3-300x124.png\" alt=\"\" width=\"651\" height=\"269\" \/><\/p>\n<h1><a name=\"_Toc6859843\"><\/a>3.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Le code pour faire un appel API\u00a0: liste des voitures<\/h1>\n<p>De m\u00eame, pour obtenir la liste des v\u00e9hicules, on appelait avec CuRL<\/p>\n<pre><code>curl -X GET \"https:\/\/api.mercedes-benz.com\/experimental\/connectedvehicle\/v1\/vehicles\"\u00a0 -H \"accept: application\/json\"\u00a0 -H \"authorization: Bearer <strong>f9da01aa-0c07-412b-bb0c-f31a7b413b7b<\/strong>\"<\/code><\/pre>\n<p>On fait les m\u00eames \u00e9tapes en Apex\u00a0:<\/p>\n<ul>\n<li><strong>Pr\u00e9paration de la requ\u00eate <\/strong><em>(on passe le token obtenu comme avec CuRL)<\/em><\/li>\n<\/ul>\n<pre><code>HttpRequest req = new HttpRequest();\nreq.setMethod('GET');\nreq.setHeader('authorization', 'Bearer '+<strong>access_token<\/strong> );\nreq.setHeader('accept', 'application\/json');\nreq.setEndpoint(<strong>'https:\/\/api.mercedes-benz.com\/experimental\/connectedvehicle\/v1\/vehicles'<\/strong>);\n<\/code><\/pre>\n<ul>\n<li><strong>Ex\u00e9cution de la requ\u00eate<\/strong><\/li>\n<\/ul>\n<pre><code>Http http = new Http();\nHTTPResponse res = http.send(req);<\/code><\/pre>\n<ul>\n<li><strong>Lecture de la r\u00e9ponse et traitement<\/strong> <em>(ici on imprime juste la liste) <\/em><\/li>\n<\/ul>\n<pre><code>String jsonResponse = res.getBody();\nSystem.debug('response:' + jsonResponse);\n<\/code><\/pre>\n<p>Voici ce qu\u2019on obtient dans le Debug :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-743\" src=\"http:\/\/wollef.org\/wp-content\/uploads\/2019\/10\/con4-300x153.png\" alt=\"\" width=\"645\" height=\"329\" \/><\/p>\n<p>Et voici ! Reste \u00e0 int\u00e9grer ce code manipul\u00e9 \u00e0 la main dans une application&#8230; Ce sera l&#8217;objet des travaux du prochain post !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dans les deux premi\u00e8res parties nous avons parl\u00e9 de l\u2019API Mercedes et on l\u2019a utilis\u00e9e \u2018\u00e0 la main\u2019 avec CuRL en ligne de commande, puis on a regard\u00e9 comment utiliser et configurer Salesforce,\u00a0 puis\u00a0\u00a0programmer des composants visuels avec Salesforce\u00a0et enfin comment stocker\u00a0et lire en mode programmation des\u00a0donn\u00e9es dans Salesforce. Maintenant, on regarde comment programmer ces <a class=\"read-more\" href=\"https:\/\/wollef.org\/blog\/se-connecter-au-cloud-mercedes-depuis-salesforce\/\">Continue Reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[30,33,40,49,18,20],"tags":[],"class_list":["post-737","post","type-post","status-publish","format-standard","hentry","category-cars-and-clouds","category-apex","category-curl","category-mercedes","category-salesforce","category-soql"],"_links":{"self":[{"href":"https:\/\/wollef.org\/blog\/wp-json\/wp\/v2\/posts\/737","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wollef.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wollef.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wollef.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wollef.org\/blog\/wp-json\/wp\/v2\/comments?post=737"}],"version-history":[{"count":0,"href":"https:\/\/wollef.org\/blog\/wp-json\/wp\/v2\/posts\/737\/revisions"}],"wp:attachment":[{"href":"https:\/\/wollef.org\/blog\/wp-json\/wp\/v2\/media?parent=737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wollef.org\/blog\/wp-json\/wp\/v2\/categories?post=737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wollef.org\/blog\/wp-json\/wp\/v2\/tags?post=737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}