Ticket #377 (closed enhancement: fixed)

Opened 1 year ago

Last modified 4 months ago

Soap support

Reported by: estee Assigned to: sylvain261
Priority: normal Milestone: Jelix 1.1 beta 1
Component: jelix:core:soap Version:
Severity: normal Keywords:
Cc: Php version:
Review: review+ Hosting Provider:
Documentation needed: 0 Blocking:

Description

Bonjour, j'ai lu que Copix implémente SOAP( en utilisant extension SOAP de php 5), donc comme je préfère Jelix j'ouvre un nouveau ticket, si quelqu'un sait programmer un objet jRequest et un objet jResponse.

Attachments

soap.php (1.7 kB) - added by laurentj on 02/20/08 18:03:14.
exemple de point d'entrée pour soap
patchSoapv1_0.diff (121.8 kB) - added by sylvain261 on 03/05/08 17:25:19.
wshelper.zip (31.4 kB) - added by sylvain261 on 03/11/08 09:37:21.
Zip de jelix-www/wshelper (css+images)
patchSoapv1_1.diff (199.0 kB) - added by sylvain261 on 03/11/08 12:21:03.
Nouveau patch
soapSupport.diff (16.6 kB) - added by sylvain261 on 04/09/08 09:39:46.
Patch avec uniquement les éléments nécessaires au support SOAP (donc sans le module jWSDL)
jWSDLModule.diff (22.7 kB) - added by sylvain261 on 04/09/08 09:41:15.
Module jWSDL (génération du WSDL et de la doc des web service de l'application
testApp.diff (14.3 kB) - added by sylvain261 on 04/09/08 09:43:00.
Ajout des tests Soap à testApp (inclue la maj de testapp.mn)
build.diff (2.0 kB) - added by sylvain261 on 04/09/08 09:44:20.
Maj des manifests de jelix pour le support Soap et le module jWSDL
wshelper.diff (6.3 kB) - added by sylvain261 on 04/09/08 10:38:06.
Oubli ! Une Maj de wshelper permettant d'avoir des tableaux associatifs (patch nécessaire pour testapp)

Change History

02/20/08 18:02:34 changed by laurentj

  • review changed.

Proposition : utiliser l'api soap de php. Cependant, le point d'entrée devra être différent des autres. Voir le fichier joint soap.php

02/20/08 18:03:14 changed by laurentj

  • attachment soap.php added.

exemple de point d'entrée pour soap

02/20/08 18:05:02 changed by laurentj

Voir une classe pour la génération d'un WSDL: http://www.schlossnagle.org/~george/blog/index.php?/archives/234-WSDL-Generation.html

Cependant, pas sûr que cela nous interresse directement, dans la mesure où les actions peuvent être réparties sur plusieurs contrôleurs.

02/26/08 15:59:02 changed by laurentj

  • milestone set to Jelix 1.1.

03/05/08 17:24:12 changed by sylvain261

  • docneeded changed.

Voilà le patch apportant le support SOAP à jelix :-)

1/ Pour le soap lui même on utilise l'extension soap de php

2/ php ne permet pas la génération de WSDL en natif, j'ai fait ca via la librairie wshelper cf http://jool.nl/new/1,webservice_helper.html Initialement j'avais privilégié l'utilisation de la classe WS_gen citée ci dessus car elle est plus simple et c'est celle là qui est utilisée dans Copix. Mais en fait c'est assez daubé car ca ne gère pas correctement les tableaux (les tableaux sont de type mixed[] ce qui n'est pas compris par du java et par nusoap).

3/ Vu que wshelper permet de générer une "documentation utilisateur" des web services j'ai également repris ca (en remplacant le code XSLT par jTpl)

Pour utiliser soap dans une application il convient pour le moment:

- De copier le point d'entrée soap dans le www de l'application

- De copier le répertoire \lib\jelix-www\wshelper dans le www de l'application

- De créer un controlleur XXX.soap.php

- De documenter correctement les méthodes du controller

- De se rendre sur index.php?module=jWSDL&action=WSDL:index pour visualiser la doc que ça créé (les éventuels pbs sont affichés) et y a un lien vers le WSDL du service pour pouvoir implémenter le client soap.

Voilà j'espère que pour mon 1er patch j'ai pas été trop mauvais ;-)

03/05/08 17:25:19 changed by sylvain261

  • attachment patchSoapv1_0.diff added.

03/06/08 13:39:19 changed by laurentj

  • owner deleted.
  • component changed from jelix:core request to jelix:core:soap.

03/06/08 19:30:41 changed by laurentj

  • review set to review?.

03/06/08 22:36:58 changed by laurentj

  • review changed from review? to review-.

Quelques remarques générales :

  • première chose à faire : fait "accept ticket" (en bas du ticket ;-) ) (si tu veux continuer à bosser sur ce ticket bien sûr)
  • joindre un zip avec les images à ajouter, elles ne peuvent être incluses dans le patch
  • bizarrement, il y a des fichiers en double dans le diff
  • pour la lib wshelper : il n'y a pas de fichier indiquant la licence, d'où la classe provient etc.. Il faut joindre les éventuels fichiers genre CREDITS, VERSION, LICENCE etc ou équivalent distribués dans l'archive d'origine.
  • Ajouter également un fichier lib/wshelper/jelix.patch, contenant un diff des modifs effectués sur les fichiers d'origines de wshelper (pas nécessaire par contre de l'indiquer dans les fichiers .mn)

lib/jelix-modules/jWSDL/controllers/WSDL.classic.php

+        $rep = $this->getResponse('html');
+        $rep->addHttpHeader('Content-Type','text/html;charset=UTF-8',false);

Pourquoi spécifier le content type ? il est déjà spécifié par le jResponseHtml.

+        if(sizeof($webservices) == 0){
+            throw new Exception("There is not web services available");
+        }

Est-ce indispensable de générer une exception ici ? ne pourrait-on pas afficher simplement le message dans le template ? Je ne pense pas que le fait qu'il n'y ait pas de services disponibles soit une erreur. (après tout, en général on ne génère pas une exception quand on affiche une liste vide de news, d'enregistrements quelconques..).

+            if (empty($module) || empty($controller)) {
+                throw new Exception("Unable to generate WSDL. Invalid service name (Syntax is \$module~\$controller)");
+            }

Il est préférable d'avoir les messages dans un fichier properties, et donc d'utiliser jException("la.cle.de.la.locale", $parametres_printf); (remarque valable partout où il est utilisé Exception)

pour le reste du module jWSDL, et la classe jWSDL, je regarderais plus tard.

lib/jelix-scripts/templates/www/soap.php.tpl

+//handling the request
+if(isset($HTTP_RAW_POST_DATA) && ($HTTP_RAW_POST_DATA!='')){
+    $requestSoap = $HTTP_RAW_POST_DATA;
+}else{
+    $requestSoap = file("php://input");
+    $requestSoap = implode(" ", $requestSoap);
+}

Ne pourrait-on pas déplacer ça dans jSoapRequest::_construct ? En gros rassembler tout ce qui concerne l'analyse de la requete http dans jSoapRequest, puisque c'est son rôle.

lib/jelix/core/jCoordinator.class.php

 
-        $this->response = $ctrl->{$this->action->method}();
+        if($this->request->type == 'soap'){
+            $this->response = call_user_func_array (array($ctrl, $this->action->method),$this->request->soapArgs);
+        }else{
+            $this->response = $ctrl->{$this->action->method}();
+        }

Je n'aime pas du tout ça. D'une part parce qu'on se retrouve à gérer un cas spécifique, c'est pas propre. Mais aussi, chez 95% des utilisateurs de jelix et de la vie d'une appli classique, il n'y a pas de soap, et donc ce test et le premier block du test peut être considéré comme du code mort (perf, tout ça..). Je vois donc deux solutions :

  • est ce que les arguments aux methodes des contrôleurs sont vraiment nécessaires à wshelper ? Ne se base-t-il pas uniquement sur la doc en commentaire ? Si ce n'est pas nécessaire, on met alors les arguments dans params de request, et on a ainsi un fonctionnement dans le contrôleur comme pour les autres types de requêtes. Si c'est nécessaire, peut être peut-on aussi modifier wshelper pour ne pas qu'il analyse les arguments ? (si la doc est suffisement complète, ça devrait le faire non ?)
  • si ce n'est pas possible, peut être modifier un peu jCoordinator, de façon à ce que l'appel de la méthode soit faite dans une nouvelle méthode protégée de jCoordinator. Ainsi pour soap, on crée une nouvelle classe jSoapCoordinator, héritant de jCoordinator, qui surcharge cette nouvelle méthode. Et bien sûr, dans soap.php, on utilisera jSoapCoordinator au lieu de jCoordinator. D'ailleurs peut être peut-on en profiter pour migrer des trucs de soap.php vers jSoapCoordinator, afin que soap.php soit le plus léger possible.

lib/jelix/core/request/jSoapRequest.class.php

+        $this->_initUrlDatas(); //Necessry because the controller is not yet initialised

Il faudrait alors surcharger la méthode init de jRequest en lui faisant rien faire, car elle est appelée par jCoordinator, et donc sans cette surcharge _initUrlDatas est appelé deux fois.

lib/jelix/core/response/jResponseSoap.class.php

+        global $soapServer;
+        if(!isset($soapServer)){
+            $soapServer = new SoapServer(null, array('soap_version' => SOAP_1_1, 'encoding' => $gJConfig->charset, 'uri' => $_SERVER['PHP_SELF']));
+        }

Ce global, c'est bof (bon tu va me dire, y a d'autres globals, mais moins y en a mieux c'est). Ne pourrais-ton pas en fait faire en sorte que l'objet SoapServer? soit une propriété de jSoapRequest plutôt ? Il serait ainsi instancié dans jSoapRequest::initService(). Un autre avantage, c'est que ce test isset devient inutile, car on est sûr ainsi que si outputError est appelé, c'est qu'il y a un jSoapRequest instancié, donc un SoapServer? instancié.

C'est tout pour le moment, je n'ai pas testé encore. À propos de test, ce qui serait bien c'est d'inclure des tests dans testapp, d'appel à des services web. Avec SoapClient? ça devrait se faire rapidement ? (j'ai pas regardé, peut être est-ce plus long à faire que j'imagine).

Bon sinon merci pour tout le boulot effectué jusque là :-)

03/06/08 22:41:08 changed by laurentj

Si ça t'intéresse, je te met "owner" du composant jelix:core:soap. Ainsi si il y a des bugs ou des évolutions demandées sur le support de soap dans jelix, tu en sera informé, tu pourras ainsi corriger ou faire la review des patchs proposés sur soap (et tu auras un accès subversion pour commiter).

03/07/08 13:50:04 changed by sylvain261

  • status changed from new to assigned.
  • owner set to sylvain261.

03/11/08 09:37:21 changed by sylvain261

  • attachment wshelper.zip added.

Zip de jelix-www/wshelper (css+images)

03/11/08 09:41:39 changed by sylvain261

J’ai tenu compte de l’ensemble de tes remarques.
Y a notamment désormais un jSoapController et des controlleurs de tests dans testapp C’est désormais bcp plus propre :-)
Concernant le isset() dans jSoapResponse, je l’ai déplacé dans jSoapController. Il reste indispensable de faire ce test compte tenu que l’erreur a put se produire durant la génération du WSDL et donc avant l’instanciation de soapServer.
Pour tester, le contenu de jelix-www/wshelper est à placer dans le www de testApp dans le rep jelix/wshelper.
Je finalise le patch puis je le poste.

03/11/08 12:21:03 changed by sylvain261

  • attachment patchSoapv1_1.diff added.

Nouveau patch

03/11/08 12:26:18 changed by sylvain261

  • review changed from review- to review?.

03/17/08 23:53:12 changed by laurentj

  • review changed from review? to review-.

Il semble que tu as un problème dans ta manière de faire ton patch (voir fr/patchs). La plupart des fichiers sont en doubles comme je te l'avais déjà fait remarqué. Je m'y perd dans le fichier diff, et quand je l'applique, les nouveaux fichiers contiennent deux fois le même contenu. Bref, il n'est pas utilisable en l'état. je viens par exemple de passer 3/4 d'heure rien que pour intégrer lib/wshelper dans le trunk.

De plus le patch contient des suppressions de lignes de code qui n'ont pas lieu d'être. Tu as sûrement dû faire ton patch sans mettre à jour tes fichiers locaux par rapport au trunk. Enfin, tu utilises les sauts de lignes windows (\r\n) plutôt que unix (\n). Il faut régler ton éditeur correctement.

Pour les images et la feuille de style css, ils sont trop spécifiques à l'original wshelper. Je n'incluerais donc pas ces images et cette feuille de style. Il faudrait faire une css plus simple et plus neutre (pas besoin d'images).

Pour le reste:

  • lib/jelix-scripts/templates/www/soap.php.tpl ok
  • lib/jelix/core/jCoordinator.class.php ok pour callAction
  • lib/jelix/utils/jWSDL.class.php
  • lib/jelix/core/response/jResponseSoap.class.php

lib/jelix/core/jSoapCoordinator.class.php

+    protected function callAction($ctrl){
+        $this->response = call_user_func_array (array($ctrl, $this->action->method),$this->soapArgs);
+    }

On ne peut vraiment pas fusionner soapArgs avec request->params ? et supprimer les arguments sur les méthodes des controleurs (sans supprimer le commentaire pour wshelper) ? Tu ne m'a pas repondu sur la question de savoir si le commentaire des méthodes de controleurs suffisait pour wshelper, ou si il fallait vraiment absolument mettre ces paramètres php. En gros, avoir donc

    protected function callAction($ctrl){
        $this->request->params = array_merge($this->soapArgs, $this->request->params);
        $this->response = call_user_func_array (array($ctrl, $this->action->method));
    }

Et dans le contrôleur :

    /** 
     * Test with a simple parameter
     * @param string $name
     * @return string
     */
    function hello() {
        $rep = $this->getResponse('soap');
        $rep->response = "Hello ".$this->param('name');
        return $rep;
    }

Est-ce donc possible :-) ?

+        $this->soapServer->setObject($this);

Gros problème de sécurité potentiel ici. Car cela veut dire que l'on peut appeler en SOAP des méthodes natives de jCoordinator. L'objet sur lequel il y a le _call doit être une classe à part sans d'autres méthodes que le _call. La classe jSoapHandler était ce qu'il fallait (mais l'inclure dans le même fichier que jSoapCoordinator n'est pas un mal).

+        if(isset($this->soapServer)){
+            return $this->soapServer;
+        }else{

je préfère que soapServer soit une propriété définie dans la classe, et que le test compare cette propriété à null.

lib/jelix/core/request/jSoapRequest.class.php

+            die("Soap Call require GET parameter \"service\"");

Y a pas plus propre comme sortie ? Comme générer une vraie reponse erreur soap ? ($soapServer->fault ou un truc comme ça)

Pour les tests dans testapp, il faudrait intégrer aussi des tests unitaires (dans modules/jelix-tests/tests/) mais je pourrais le faire si tu n'as pas le temps.

J'attend ton nouveau patch :-)

04/04/08 09:50:16 changed by Lipki

Moi aussi :)

04/09/08 09:39:46 changed by sylvain261

  • attachment soapSupport.diff added.

Patch avec uniquement les éléments nécessaires au support SOAP (donc sans le module jWSDL)

04/09/08 09:41:15 changed by sylvain261

  • attachment jWSDLModule.diff added.

Module jWSDL (génération du WSDL et de la doc des web service de l'application

04/09/08 09:43:00 changed by sylvain261

  • attachment testApp.diff added.

Ajout des tests Soap à testApp (inclue la maj de testapp.mn)

04/09/08 09:44:20 changed by sylvain261

  • attachment build.diff added.

Maj des manifests de jelix pour le support Soap et le module jWSDL

04/09/08 09:56:30 changed by sylvain261

  • review changed from review- to review?.
  • summary changed from Classe Soap -> jSoapRequest et jResponseSoap to Soap support.

Voilà ! :-)
Enfin :-) J'ai finit par avoir le temps nécessaire pour m'en occuper.
Quelques remarques :

  • J'ai donc fait 4 patchs séparés afin de faciliter les éventuels retours.
  • Pour la doc, le css existant utilisé pour la page par défaut d'une appli nouvelle créé ne me plaisant pas j'ai pris le parti d'utiliser le css du site jelix.org. Ca me semble pertinent pour à l'avenir pouvoir faire évoluer les choses de façon cohérentes.
  • Pour les tests unitaires, à vrai dire j'ai pas vraiment le temps ni vraiment le savoir faire (ca viendra...), ça me plairait que tu t'en occupes et ainsi je pourrait voir quel aura été ta démarche pour les implémenter.

04/09/08 10:38:06 changed by sylvain261

  • attachment wshelper.diff added.

Oubli ! Une Maj de wshelper permettant d'avoir des tableaux associatifs (patch nécessaire pour testapp)

04/14/08 16:07:43 changed by laurentj

  • status changed from assigned to closed.
  • docneeded set to 1.
  • review changed from review? to review+.
  • resolution set to fixed.

Toujours des problèmes (mineurs) avec les patchs :

  • le patch a été généré à partir d'un sous répertoire de lib/, et non à partir de trunk/
  • Toujours des problèmes avec les retours chariots ...

jSoapCoordinator

    var $wsdl;

    var $soapServer;

var n'est plus utilisé en PHP5. C'est quoi donc ? public ? protected ?

jSoapHandler

    /**
    * Coordinator
    */
    var $jelix;

Idem. Et il n'y a pas le type.. Le nom n'est pas non plus très parlant.

       $this->jelix->request->params['action'] = $this->jelix->request->params['action'].':'.$soapOperationName;

utiliser l'operateur .=

       $i = 0;
       foreach(array_keys($operationParams) as $paramName){
           $this->jelix->request->params[$paramName] = $soapArgs[$i];
           $i++;
       }

On peut utiliser la clé directement pour $i :

       foreach(array_keys($operationParams) as $i=>$paramName){
           $this->jelix->request->params[$paramName] = $soapArgs[$i];
       }

jWSDL.class.php

commentaires en français..

soap.php.tpl

	$config_file = 'index/config.ini.php'; 

Non, chaque point d'entrée a son propre fichier de configuration, vu qu'ils n'ont pas le même usage. donc ici cela doit être soap/config.ini.php

Pour la doc, le css existant utilisé pour la page par défaut d'une appli nouvelle créé ne me plaisant pas j'ai pris le parti d'utiliser le css du site jelix.org. Ca me semble pertinent pour à l'avenir pouvoir faire évoluer les choses de façon cohérentes.

Y a plein de trucs dans cette feuille de style totalement inutile. Vaut mieux utiliser la feuille jelix.css fournie dans jelix, quitte à l'améliorer un peu.

soap_doc.tpl n'a pas un HTML très très propre :-p

Bon, j'ai corrigé moi même toutes ces petites choses, histoire qu'on ait dans le trunk un premier truc qui fonctionne assez rapidement.

Donc c'est dans le trunk. Merci pour ce gros patch :-)

04/14/08 17:38:25 changed by estee

"Sans vouloir" polluer le topic, un énorme!!! Merci pour ce patch qui rends Jelix encore plus incontournable.

07/11/08 14:53:42 changed by laurentj

  • docneeded deleted.
Download in other formats: Comma-delimited Text Tab-delimited Text RSS Feed