developer.jelix.org is not used any more and exists only for history. Post new tickets on the Github account.
developer.jelix.org n'est plus utilisée, et existe uniquement pour son historique. Postez les nouveaux tickets sur le compte github.

Opened 13 years ago

Closed 13 years ago

Last modified 12 years ago

#377 closed enhancement (fixed)

Soap support

Reported by: estee Owned by: sylvain261
Priority: normal Milestone: Jelix 1.1 beta 1
Component: jelix:core:soap Version:
Severity: normal Keywords:
Cc: Blocked By:
Blocking: Documentation needed: no
Hosting Provider: Php version:

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 (9)

soap.php (1.7 KB) - added by laurentj 13 years ago.
exemple de point d'entrée pour soap
patchSoapv1_0.diff (121.8 KB) - added by sylvain261 13 years ago.
wshelper.zip (31.4 KB) - added by sylvain261 13 years ago.
Zip de jelix-www/wshelper (css+images)
patchSoapv1_1.diff (199.0 KB) - added by sylvain261 13 years ago.
Nouveau patch
soapSupport.diff (16.6 KB) - added by sylvain261 13 years ago.
Patch avec uniquement les éléments nécessaires au support SOAP (donc sans le module jWSDL)
jWSDLModule.diff (22.7 KB) - added by sylvain261 13 years ago.
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 13 years ago.
Ajout des tests Soap à testApp (inclue la maj de testapp.mn)
build.diff (2.0 KB) - added by sylvain261 13 years ago.
Maj des manifests de jelix pour le support Soap et le module jWSDL
wshelper.diff (6.3 KB) - added by sylvain261 13 years ago.
Oubli ! Une Maj de wshelper permettant d'avoir des tableaux associatifs (patch nécessaire pour testapp)

Download all attachments as: .zip

Change History (26)

comment:1 Changed 13 years ago by laurentj

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

Changed 13 years ago by laurentj

exemple de point d'entrée pour soap

comment:2 Changed 13 years ago 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.

comment:3 Changed 13 years ago by laurentj

  • Milestone set to Jelix 1.1

comment:4 Changed 13 years ago by sylvain261

  • Documentation needed unset

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 ;-)

Changed 13 years ago by sylvain261

comment:5 Changed 13 years ago by laurentj

  • Component changed from jelix:core request to jelix:core:soap
  • Owner laurentj deleted

comment:6 Changed 13 years ago by laurentj

  • review set to review?

comment:7 Changed 13 years ago 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à :-)

comment:8 Changed 13 years ago 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).

comment:9 Changed 13 years ago by sylvain261

  • Owner set to sylvain261
  • Status changed from new to assigned

Changed 13 years ago by sylvain261

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

comment:10 Changed 13 years ago 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.

Changed 13 years ago by sylvain261

Nouveau patch

comment:11 Changed 13 years ago by sylvain261

  • review changed from review- to review?

comment:12 Changed 13 years ago 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 :-)

comment:13 Changed 13 years ago by Lipki

Moi aussi :)

Changed 13 years ago by sylvain261

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

Changed 13 years ago by sylvain261

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

Changed 13 years ago by sylvain261

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

Changed 13 years ago by sylvain261

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

comment:14 Changed 13 years ago 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.

Changed 13 years ago by sylvain261

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

comment:15 Changed 13 years ago by laurentj

  • Documentation needed set
  • Resolution set to fixed
  • review changed from review? to review+
  • Status changed from assigned to closed

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 :-)

comment:16 Changed 13 years ago by estee

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

comment:17 Changed 12 years ago by laurentj

  • Documentation needed unset
Note: See TracTickets for help on using tickets.