[JAVA] Utilisation SOAPI / API OVH

Fermé
Cléclé66 Messages postés 181 Date d'inscription dimanche 23 septembre 2012 Statut Membre Dernière intervention 9 août 2016 - Modifié par Cléclé66 le 21/06/2014 à 19:23
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 24 juin 2014 à 00:26
Bonjour,

Je suis en train d'essayer de créer une connexion en java sur mon serveur OVH grâce à leur api mais je n'arrive pas a voir quel est le rapport avec ce fichier https://www.ovh.com/soapi/soapi-dlw-latest.wsdl mais apparemment j'ai besoin de l'intégrer dans mon code :
package net.ovh.vps*****.api;

import com.ovh.soapi.manager.DedicatedInfoReturn;
import com.ovh.soapi.manager.ManagerPortType;
import com.ovh.soapi.manager.ManagerService;

public class Main {

 public static void main(String[] args) {

  
  ManagerPortType soapi = new ManagerService().getManagerPort();

  // Login
  String session = soapi.login("********-ovh", "********", "fr", false);

  // DedicatedInfo
  DedicatedInfoReturn result = soapi.dedicatedInfo(session,
    "vps*****.ovh.net");
  System.out.println(result);

  // Logout
  soapi.logout(session);
 }
}


Est-ce que quelqu'un pourrai m'aider svp ?

2 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
21 juin 2014 à 20:31
Bonjour,

Un WSDL permet de décrire avec un web service SOAP, alors je ne connais pas spécifiquement l'API d'OVH mais j'imagine que c'est une surcouche Java qui permet d'établir les connexions avec les différents web services.

Par exemple au début du WSDL tu as des définitions de types XML qui pourront être échangés entre l'application cliente et le web service.

<xsd:element name="mailingListModeratorDel">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="session" type="xsd:string" nillable="true" />
      <xsd:element name="domain" type="xsd:string" nillable="true" />
      <xsd:element name="ml" type="xsd:string" nillable="true" />
      <xsd:element name="email" type="xsd:string" nillable="true" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

Il y a fort à parier que dans l'API Java tu es une classe MailingListModeratorDel ou avec un nom proche, qui aura pour attributs des String session, domain, ml et email.

Puis dans la deuxième moitié du WSDL tu as les différents services accessibles et leurs paramètres. Par exemple tout à la fin :

<wsdl:service name="managerService">
  <wsdl:port name="managerPort" binding="wsdlns:managerBinding">
    <soap:address location="https://www.ovh.com:1664" />
  </wsdl:port>
</wsdl:service>

Tu auras là aussi une classe quelque part dans ton API Java une méthode qui prendra en paramètre un objet managerBinding appelé managerPort et qui dans son code fait un appel web service managerService...

Le WSDL c'est la base du web service, il est forcément nécessaire pour permettre le web service. Après il y a l'API Java qui donne des facilités pour utiliser le web service, j'imagine qu'il doit y a avoir des API dans d'autres langages, et si pour je ne sais quel raison tu voudrais utiliser le web service sans aucune API tu pourrais le faire sans problème, il suffit juste de connaître l'emplacement du WSDL.

Tu peux par exemple installer SoapUI, un logiciel qui permet de faire des requêtes sur n'importe quel web service directement de XML à XML. Il suffit juste de lui indiquer le WSDL pour qu'il aille lire les différents services et types de données utilisables, et il te pré-rempli le XML de chaque requête, il faut juste remplacer les points d'interrogations.
0
Cléclé66 Messages postés 181 Date d'inscription dimanche 23 septembre 2012 Statut Membre Dernière intervention 9 août 2016 77
21 juin 2014 à 20:37
Ok merci beaucoup pour ta réponse détaillé !
Je vais voir tout ça et je te répond si c'est bon ;)
Merci encore !
0
Cléclé66 Messages postés 181 Date d'inscription dimanche 23 septembre 2012 Statut Membre Dernière intervention 9 août 2016 77
21 juin 2014 à 20:48
En fait, le truc c'est que je veux développer une application java mais il y a besoin du fichier .wsdl la console m'indique :

Exception in thread "main" com.sun.xml.internal.ws.wsdl.parser.InaccessibleWSDLException: 2 counts of InaccessibleWSDLException.

java.io.IOException: Got https://www.ovh.com/soapi/* while opening stream from https://www.ovh.com/soapi/*
java.io.IOException: Got https://www.ovh.com/soapi/*?wsdl while opening stream from https://www.ovh.com/soapi/*?wsdl

Donc ce que je voudrai c'est relier le .wsdl a mon projet java
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
21 juin 2014 à 21:09
Je n'ai pas trouvé l'API Java sur le site d'OVH pour la télécharger.

Quelle est la trace complète de l'exception ?
0
Cléclé66 Messages postés 181 Date d'inscription dimanche 23 septembre 2012 Statut Membre Dernière intervention 9 août 2016 77
21 juin 2014 à 21:49
Exception in thread "main" com.sun.xml.internal.ws.wsdl.parser.InaccessibleWSDLException: 2 counts of InaccessibleWSDLException.

java.io.IOException: Got https://www.ovh.com/soapi/* while opening stream from https://www.ovh.com/soapi/*
java.io.IOException: Got https://www.ovh.com/soapi/*?wsdl while opening stream from https://www.ovh.com/soapi/*?wsdl

at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
at javax.xml.ws.Service.<init>(Unknown Source)
at com.ovh.soapi.manager.ManagerService.<init>(ManagerService.java:46)
at net.ovh.vps71396.api.Main.main(Main.java:12)
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
21 juin 2014 à 22:12
Vu l'erreur ça plante sur new javax.xml.ws.Service(), sauf que c'est une méthode qui prend deux paramètres dont le wsdlDocumentLocation.

https://docs.oracle.com/javase/7/docs/api/javax/xml/ws/Service.html#constructor_detail

Vu que tu as accès à l'API est-ce que tu pourrais m'indiquer le code du constructeur de la classe ManagerService, pour voir comment il détermine la valeur passée ligne 46 à ce constructeur ?

Sinon, indiques moi comment tu as téléchargé l'API et je la récupérerai pour décortiquer le code à ce niveau, il est peut-être nécessaire d'avoir un fichier de configuration, mais de toute évidence "https://www.ovh.com/soapi/*?wsdl" n'est pas une valeur correcte, il faudrait avoir "soapi-dlw-latest".
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
22 juin 2014 à 17:48
Je n'ai pas de compte OVH alors je n'ai pas pu tester, mais voici une conversion vite faite des API PHP/Python de OVH en Java. Il y a sûrement des bugs, mais c'est un point de départ... Si tu as l'occasion de l'utiliser et de corriger les bugs, n'hésite pas à partager le code correct ;-)

Remarque : il n'y a pas de convertisseur JSON standard en Java, du coup j'ai juste mis une interface JsonParser, il faudra l'implémenter pour pouvoir passer d'un String à un objet Json et inversement. On pourra utiliser des bibliothèques comme google-gson, Jackson ou bien d'autres.

package test;

import ovh.api.JsonParser;
import ovh.api.OvhApi;
import ovh.api.OvhApi.Cluster;

public class Test
{
    private static class JsonParserTest implements JsonParser<String, String>
    {
        @Override
        public String convert(String json)
        {
            return json;
        }
    };
    
    public static void main(String[] args)
    {
        OvhApi<String, String> ovh = new OvhApi<String, String>(Cluster.OVH_API_EU, "applicationKey", "applicationSecret", "consumerKey", new JsonParserTest());
        
        String result = ovh.get("/me", null);
        
        System.out.println(result);
    }
}

package ovh.api;

public interface JsonParser<JsonIn, JsonOut>
{
    /**
     * @param json
     *            Json Java object
     * @return Json String
     */
    public String convert(JsonIn json);
    
    /**
     * @param json
     *            Json String
     * @return Json Java object
     */
    public JsonOut convert(String json);
}

package ovh.api;

import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Scanner;

public class OvhApi<JsonIn, JsonOut>
{
    public static enum Cluster
    {
        OVH_API_EU("https://api.ovh.com/1.0"),
        OVH_API_CA("https://ca.api.ovh.com/1.0");
        
        private final String root;
        
        private Cluster(String root)
        {
            this.root = root;
        }
        
        public String getRoot()
        {
            return root;
        }
    }
    
    private final String applicationKey;
    private final String applicationSecret;
    private final String consumerKey;
    private final Cluster root;
    private final long timeDelta;
    
    private final JsonParser<JsonIn, JsonOut> parser;
    
    private static final String AUTH_TIME = "/auth/time";
    
    /**
     * Construct a new wrapper instance.
     * 
     * @param root
     *            the ovh cluster you want to call
     * @param applicationKey
     *            your application key given by OVH on application registration
     * @param applicationSecret
     *            your application secret given by OVH on application registration
     * @param consumerKey
     *            the consumer key you want to use, if any, given after a credential request
     */
    public OvhApi(Cluster root, String applicationKey, String applicationSecret, String consumerKey, JsonParser<JsonIn, JsonOut> parser)
    {
        this.applicationKey = applicationKey;
        this.applicationSecret = applicationSecret;
        this.consumerKey = consumerKey;
        this.root = root;
        
        this.timeDelta = timeDelta();
        
        this.parser = parser;
    }
    
    /**
     * Get the delta between this computer and the OVH cluster to sign further queries
     * 
     * @return delta in seconds
     */
    private long timeDelta()
    {
        try
        {
            Scanner sc = new Scanner(new URL(root.getRoot() + AUTH_TIME).openStream());
            long serverTime = sc.nextLong();
            sc.close();
            
            long currentTime = new Date().getTime() / 1000;
            
            return currentTime - serverTime;
        }
        catch (Exception e)
        {
            throw new RuntimeException("Can't compute time drift for " + root, e);
        }
    }
    
    /**
     * This is the main method of this wrapper. It will sign a given query and return its result.
     * 
     * @param method
     *            the HTTP method of the request (get/post/put/delete)
     * @param path
     *            the url you want to request
     * @param content
     *            the object you want to send in your request (will be automatically serialized to JSON)
     * @return
     */
    private JsonOut call(String method, String path, JsonIn content)
    {
        String url = root.getRoot() + path;
        
        try
        {
            String body = content == null ? "" : parser.convert(content);
            
            long now = new Date().getTime() / 1000 + timeDelta;
                        
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            
            con.setRequestMethod(method);
            con.setRequestProperty("Content-Type", "application/json");
            con.setRequestProperty("X-Ovh-Application", applicationKey);
            con.setRequestProperty("X-Ovh-Consumer", consumerKey);
            con.setRequestProperty("X-Ovh-Signature", "$1$" + hash(applicationSecret + "+" + consumerKey + "+" + url + "+" + body + "+" + now));
            con.setRequestProperty("X-Ovh-Timestamp", String.valueOf(now));
            
            if (!body.isEmpty())
            {
                con.setDoOutput(true);
                con.setRequestProperty("Content-Length", Integer.toString(body.length()));
                con.getOutputStream().write(body.getBytes("UTF8"));
            }
            
            StringBuilder response = new StringBuilder();
            
            Scanner sc = new Scanner(con.getInputStream());
            
            while (sc.hasNextLine())
                response.append(sc.nextLine());
            
            sc.close();
            
            return parser.convert(response.toString());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Can't call " + method + " on " + url, e);
        }
    }
    
    private static String hash(String message) throws NoSuchAlgorithmException
    {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(message.getBytes());
        
        byte byteData[] = md.digest();
        
        StringBuilder sb = new StringBuilder();
        
        for (int i = 0; i < byteData.length; i++ )
            sb.append(Integer.toString( (byteData[i] & 0xff) + 0x100, 16).substring(1));
        
        return sb.toString();
    }
    
    public JsonOut get(String path, JsonIn content)
    {
        return call("GET", path, content);
    }
    
    public JsonOut put(String path, JsonIn content)
    {
        return call("PUT", path, content);
    }
    
    public JsonOut post(String path, JsonIn content)
    {
        return call("POST", path, content);
    }
    
    public JsonOut delete(String path, JsonIn content)
    {
        return call("DELETE", path, content);
    }    
}
0
Cléclé66 Messages postés 181 Date d'inscription dimanche 23 septembre 2012 Statut Membre Dernière intervention 9 août 2016 77
22 juin 2014 à 19:50
Merci je vais me pencher dessus ;)
0
Cléclé66 Messages postés 181 Date d'inscription dimanche 23 septembre 2012 Statut Membre Dernière intervention 9 août 2016 77
Modifié par KX le 23/06/2014 à 07:54
Voila j'ai bien suivi tout ce que tu as dis mais il m'affiche l'erreur comme quoi il n'arrive pas a recevoir les données :

Exception in thread "main" java.lang.RuntimeException: Can't call GET on https://api.ovh.com/1.0/me
at ovh.api.OvhApi.call(OvhApi.java:138)
at ovh.api.OvhApi.get(OvhApi.java:159)
at test.Test.main(Test.java:22)

Peut tu tester voir si avec toi ça marche avec :
applicationKey = Supprimé par la modération
applicationSecret = Supprimé par la modération
Et le consumerKey sert a avoir un "pass" soit un token pour créer une session et pouvoir accéder à l'api. Je n'ai pas vu que tu l'avais inséré dans le code et je ne trouve pas comment l'avoir.
Je pense aussi qu'au niveau de la 14ème ligne de la classe OvhApi :

        OVH_API_EU("https://api.ovh.com/1.0"),

Ce doit être :

        OVH_API_EU("https://eu.api.ovh.com/1.0"),

Peut-tu m'éclairer ?
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
23 juin 2014 à 07:59
Bonjour,

J'ai modifié ton message pour ne pas que l'on te pique les login/mot de passe, je les ai marqué dans un coin et j'essaierai de regarder ce qui coince.

Pour l'histoire du "pass" je l'ai vu passer dans le code Python, mais il n'y était pas dans le code PHP, du coup je ne savais pas si fallait le mettre, peut-être qu'en PHP il y a un token déjà tout fait et qu'en Java il faudrait plutôt faire comme en Python ? Je regarderai...

Et sinon https://eu.api.ovh.com/1.0 redirige vers https://api.ovh.com/1.0 donc peu importe.

Remarque : pour l'exception, ce n'est pas cette partie là qui est intéressante pour comprendre le problème, mais plutôt le "caused by" qui est en dessous.
0
Cléclé66 Messages postés 181 Date d'inscription dimanche 23 septembre 2012 Statut Membre Dernière intervention 9 août 2016 77
23 juin 2014 à 11:36
Apparemment c'est le Scanner a la ligne 127 si j'ai bien compris :

Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: https://eu.api.ovh.com/1.0/me
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at ovh.api.OvhApi.call(OvhApi.java:127)
... 2 more

Donc une question de réponse du serveur non ?
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
23 juin 2014 à 18:48
Ligne 127, oui, mais ce n'est pas le Scanner qui plante mais le con.getInputStream(), car en effet le serveur envoie une réponse 400 (il n'a pas compris la requête), je vais regarder un peu, avec tes accréditations je vais pouvoir faire des tests pour voir ce qui coince, en particulier sur le "pass" qui manquerait...
0