Le module de gestion de la connexion de Salesforce vers Mercedes Cloud (1/3) : Techniques utilisées

Dans les deux premières parties nous avons parlé de l’API Mercedes et on l’a utilisée ‘à la main’ avec CuRL en ligne de commande, puis on a regardé comment utiliser et configurer Salesforce,  puis  programmer des composants visuels avec Salesforce et enfin comment stocker et lire en mode programmation des données dans Salesforce.

Maintenant, on regarde comment programmer ces API Mercedes que l’on a manipulé en CuRL avec les outils de programmation de Salesforce.

1.         La page qui permet de recevoir l’autorisation

Quand on appelé le mécanisme de Mercedes pour obtenir le code d’autorisation, on allait sur une URL Mercedes avec nos données de l’application (dont le client id) , c’était l’étape A ; puis l’utilisateur tapait ses données de connexion pour autoriser l’application (étape B) ; et enfin Mercedes renvoyait sur une page de l’application en passant le code d’autorisation en paramètre (étape C).

L’URL de l’étape C ressemblait à ceci, avec le code obtenu en rouge :

https://localhost/?code=6e9d89c4-a374-4bb9-8c88-673034f87342

Parce qu’on avait dit que la redirect URL de l’application était https://localhost/.

En Salesforce on a besoin de faire une page web qui va savoir lire le paramètre code pour qu’on puisse l’utiliser par la suite.

Le code de la page est simple. Ce sera une page Visual Force, vide pour le moment

<apex:page controller="Mercedes_API_Authorization_Ctrl">
</apex:page>

Avec un controller Mercedes_API_Authorization_Ctrl qui :

  • Stocke le code d’autorisation (en bleu)
  • Lit le paramètre passé quand la page se charge. (en orange).
public class Mercedes_API_Authorization_Ctrl {
    public String authorizationCode { get; set; }
 
public Mercedes_API_Authorization_Ctrl(){
   authorizationCode =
apexpages.currentpage().getparameters().get('code');
}
}

Pour faire plus visible, on peut aussi modifier la page pour qu’elle affiche le paramètre obtenu

<apex:page controller= »Mercedes_API_Authorization_Ctrl »>
  Authorization : {! authorizationCode}
</apex:page>

 

On doit ajouter cette redirect URL à l’application déclarée chez Mercedes :

Essayons d’ouvrir la première URL (etape A), avec la bonne redirect URL (en vert), puis suivons les étapes, on arrive à :

https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/authorize?response_type=code&client_id=36f504aa-f141-41ad-93ae-09603cddf507&redirect_uri=https%3A%2F%2Fc.eu16.visual.force.com%2Fapex%2FMercedes_API_Authorization&scope=mb:user:pool:reader%20mb:vehicle:status:general

 

On sait récupérer dans SF le code d’autorisation !

 

2.         Le code pour demander le jeton de session

 

Après avoir reçu le code d’autorisation, quand on travaillait à la main :

  • on devait récupérer les jetons de session
  • on pouvait récupérer les données avec l’API

Maintenant on doit faire la même chose qu’on faisait en Curl, mais en SF, avec le langage APEX.

Avec CuRL, à chaque fois :

  • on créait la requête (la commande tapée)
  • on l’exécutait (appel du serveur Mercedes par le serveur Salesforce), en lançant la commande
  • on traitait le résultat (en le lisant)

On va faire la même chose en programmant.

L’appel CuRL pour l’obtention de la session était

curl -X POST "https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token" \
-H "authorization: Basic ZGY4YTczYmUtYTY4Zi00.....hMWQwLWRjMmM0ZWI4MTU0ZA==" \
-H "content-type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&code=297ded07-43ea-4fcc-ab73-6b6376d787ca&redirect_uri=https%3A%2F%2Flocalhost.com"

Le Code correspondant en Apex est

  • Préparation de la requête
// creation d’une requête HTTP
HttpRequest req = new HttpRequest();
req.setMethod('POST');

// vers le serveur Mercedes
req.setEndpoint('https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token');

// avec le bon code d’auorisation
req.setHeader('authorization', 'Basic ZGY4YTczYmUtYTY4Zi0.....2NiZTMxYmUxMDM5OjBlYjRmMGE0LTM1YzgtNDc0Ny1hMWQwLWRjMmM0ZWI4MTU0ZA==');
req.setHeader('content-type', 'application/x-www-form-urlencoded');

// avec le message de demande de session
String messageBody =
'grant_type=authorization_code'
+'&code=297ded07-43ea-4fcc-ab73-6b6376d787ca'    +'&redirect_uri=https%3A%2F%2Fc.eu16.visual.force.com%2Fapex%2FMercedes_API_Authorization';
req.setBody(messageBody);
  • Exécution de la requête
//Execute de la requête HTTP
Http http = new Http();
HTTPResponse res = http.send(req);
  • Lecture de la réponse et traitement (juste un affichage)
String jsonResponse = res.getBody();

Map<String, Object> results = (Map<String, Object>)

JSON.deserializeUntyped(jsonResponse);

String access_token = (String)  results.get('access_token');
String token_type   = (String)  results.get('token_type');
Integer expires_in = (Integer) results.get('expires_in');
String refresh_token=  (String)  results.get('refresh_token');
String scope         = (String)  results.get('scope');

System.debug('access_token:' + access_token);
System.debug('token_type:' + token_type);
System.debug('expires_in:' + expires_in);
System.debug('refresh_token:' + refresh_token);
System.debug('scope:' + scope); 

Voici ce qu’on obtient en debug quand on lance le code dans la Console

3.         Le code pour faire un appel API : liste des voitures

De même, pour obtenir la liste des véhicules, on appelait avec CuRL

curl -X GET "https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles"  -H "accept: application/json"  -H "authorization: Bearer f9da01aa-0c07-412b-bb0c-f31a7b413b7b"

On fait les mêmes étapes en Apex :

  • Préparation de la requête (on passe le token obtenu comme avec CuRL)
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setHeader('authorization', 'Bearer '+access_token );
req.setHeader('accept', 'application/json');
req.setEndpoint('https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles');
  • Exécution de la requête
Http http = new Http();
HTTPResponse res = http.send(req);
  • Lecture de la réponse et traitement (ici on imprime juste la liste)
String jsonResponse = res.getBody();
System.debug('response:' + jsonResponse);

Voici ce qu’on obtient dans le Debug :

Et voici ! Reste à intégrer ce code manipulé à la main dans une application… Ce sera l’objet des travaux du prochain post !