Madjid Bouchaïr 2 mai À gmantele Bonjour, je suis le stagiaire informatique dont vous a parlé André dans son mail du 12 avril. Ma problématique est la suivante : Je dois créer une API Rest se connectant à un VOSpace en utilisant Python. Le but est de manipuler des fichiers sur un file system ubuntu depuis l'API. Pour se faire, je dois utiliser votre librairie UWS Java afin de faire mes tests sur les commandes asynchrones (copyNode, PushToVoSpace...). Nous n'avons, pour l'instant, pas encore de serveur configuré pour VOSpace, ni de protocol UWS déployé pour ces tests. J'aimerais donc déployer le fichier jar sur un serveur web (comme la section démo http://cdsportal.u-strasbg.fr/uwstuto/basic.html). Le but est de créer un "dummy" job depuis l'API : 1. Création d'un JOB 2. Attendre que la commande PHASE=RUN soit envoyé sur la redirection UWS 3. Effectuer l'action sur mon file system ubuntu 4. Signaler à UWS que l'action a bien été faite. J'aimerais savoir s'il était possible d'envoyer un POST afin de passer la phase en COMPLETED ou ERROR ? Ou dois-je simplement attendre la fin du temps d'exécution ? Si vous avez un draft de la section "Getting started" qui n'est pas disponible sur le site du CDS, je serais preneur. Pour l'instant je me base sur http://cdsportal.u-strasbg.fr/uwstuto/reminder.html pour la compréhension des commandes possibles. Cordialement, Madjid Bouchair Stagiaire informatique au Centre des Données astronomiques de Strasbourg ********************************************************************************************************************************************************* Gregory Mantelet 2 mai À moi Bonjour Madjid, Comme je disais à André, désolé du manque de documentation pour cette librairie....je n'ai plus la possibilité de travailler à plein temps sur mes librairies et une écriture propre de leur documentation requiert beaucoup de temps. Toutefois, j'ai rendu disponible au téléchargement des WAR d'exemple afin de combler ce manque autant que possible: 1- Pour la dernière version officielle (4.1), vous trouverez le WAR d'exemple dans la page "Download". Une fois l'archive décompressée, vous trouverez dans le répertoire "src" toutes les sources Java nécessaires à une utilisation de la librairie. 2- Pour une version beta (4.2), vous trouverez les liens de téléchargement du WAR exemple et du JAR de la lib. beta dans le petit bloc jaune en haut de la home page. Cette version a pour unique but d'introduction à la prochaine version du protocole UWS: 1.1. Donc vous pouvez jeter un coup d'oeil mais pour l'instant je vous conseille de plutôt travailler avec la version 4.1 de ma lib et donc la version la plus répandue du protocole UWS: 1.0. Comme vous pourrez le voir, peu de code est nécessaire pour mettre en place un service UWS. Tout d'abord, il y a le job que vous voulez effectuer. Dans le WAR exemple (1), il s'agit de la classe TimerWork (un simple job qui attend un temps donné en paramètre et s'arrête ; il ne fait rien d'autre). Pour écrire un job, il faut étendre la classe abstraite JobThread et implémenter la fonction jobWork() ; cette fonction doit effectuer l'action du job. Dans votre cas, cette action serait une manipulation de fichier. Une fois le job écrit, il faut écrire une Servlet qui créera le service UWS et le configurera pour créer et exécuter vos jobs. Vous avez deux manières de faire: a) étendre UWSServlet b) écrire votre propre HttpServlet qui créera et configurera le service UWS ainsi que transfèrera toutes les requêtes vers ce service. Je vous recommande la première méthode: UWSServlet. Vous avez un exemple de comment procéder dans le fichier d'exemple (1) nommé "MyUWSServlet". Vous avez la possibilité de vérifier les paramètres d'entrée, mais cela est facultatif. Le plus important est de créer une job list dans initUWS() (donc, seule la ligne 25 est obligatoire) et de créer une instance de votre job dans createJobThread(UWSJob). Le UWSJob donné en paramètre vous donne la description du job (i.e. liste des paramètres d'entrée) à exécuter. La dernière chose à faire est de déclarer votre servlet dans WEB-INF/web.xml: UWSServletExample MyUWSServlet UWSServletExample /example/* Dans le servlet-mapping, vous pouvez écrire le path que vous voulez mais il doit obligatoirement se terminer par "/*" de manière à ce que toute la hiérarchie REST de UWS soit correctement gérée par la librairie. Vous pouvez bien évidemment écrire tout simplement: /* En bref, on peut résumer tout cela en 3 étapes: A- Ecrire votre job (cf TimerWork dans le WAR (1)) B- Etendre la servlet UWSServlet (cf MyUWSServlet dans le WAR (1)) C- Déclarer la servlet et son mapping dans WEB-INF/web.xml Au sujet de votre question sur la phase COMPLETED ou ERROR, hormis le PHASE=RUN initial et éventuellement le PHASE=ABORT, le changement d'état doit être géré à l'intérieur du service UWS ; donc pas de POST pour passer en COMPLETED ou ERROR. Pour ces derniers, c'est l'exécution de votre job (e.g. TimerWork) qui déterminera l'état de fin du job: - si une exception est jetée lors de l'exécution, le job passe en ERROR (cf ligne 48 de TimerWork) - sinon, lorsque le JobThread.jobWork() est terminé, le job passe en COMPLETED. Afin de permettre le PHASE=ABORT, vous devez prendre soin de vérifier l'état du Thread aussi souvent que possible dans jobWork() (cf isInterrupted() dans TimerWork, lignes 24 et 30). En cas d'interruption, il suffit de jeter une InterruptedException (cf ligne 31) pour que le job s'arrête et passe en ABORTED. J'espère avoir répondu à votre question et surtout avoir comblé un minimum le manque de Getting Started. Mais si vous avez d'autres questions ou rencontrez le moindre problème, n'hésitez pas à me re-demander ;-) Cordialement, Grégory ********************************************************************************************************************************************************* Madjid Bouchaïr 6 juin (Il y a 7 jours) À Gregory Bonjour, J'ai une questions (peut-être naïves) supplémentaires au sujet de la librairie. Il a été décidé d'utiliser une API java utilisant la librairie en parallèle à l'API python que je développais. Pour le moment j'utilisais le côté java uniquement pour créer un job avec un décompte (basé sur TimerWork et quelques modifications). Maintenant je dois pouvoir l'utiliser pour réaliser les procédures de VOSpace nécessitant un job. 1. Le XML est-il conservé ? Une requête avec un fichier XML est envoyé sur le modèle suivant (requête offrant un uri pour télécharger la cible) : vos://example.com!vospace/mydata1 pullFromVoSpace Le job doit donc contenir les informations de ce fichier XML ainsi que sa représentation dans dans "jobInfo" comme dans le cas suivant : m4ipu36gairz0dnl PENDING 2015-05-26T11:06:45.713 43200 2015-06-01T23:06:45.713 vos://example.com!vospace/mydata1 pullFromVoSpace J'ai noté la présence d'une classe UploadFile dans /uws/service/request/ qui semble conserver le fichier uploader avec la requête HTTP. Est-il possible d'y accéder ? Si oui, par une méthode déjà écrite ? ********************************************************************************************************************************************************* Grégory Mantelet 6 juin (Il y a 7 jours) À moi Bonjour Madjid, Tout paramètre donné lors de la création d'un job est conservé et accessible au moins en lecture avec l'URI: {root-uws}/parameters/{nom-du-parametre} Cela inclut également les fichiers uploadés. Donc si le fichier s'appellait "monFichier" à la création du job, il sera accessible avec l'URL: {root-uws}/parameters/monFichier Cela répond-il à votre question ? -- Vous pouvez "facilement" générer l'URL avec le morceau de code suivant: UWSUrl paramURL = new UWSUrl(job.getUrl()); paramURL.setAttributes(new String[]{UWSJob.PARAM_PARAMETERS, "monFichier"}); System.out.println(paramURL.toString()); OU (plus compact): System.out.println(job.getUrl().getParameter(job.getJobList().getName(), job.getJobId(), UWSJob.PARAM_PARAMETERS, "monFichier").toString()); Je n'ai testé aucun de ces codes, mais très peu de modifications devrait être nécessaires pour les corriger si nécessaire. Sinon, dites moi si vous rencontrez un quelconque problème. -- Au sujet du jobInfo, je suppose que vous avez dû étendre un peu la librairie pour en avoir un dans votre sortie XML car la librairie n'a pas encore cette possibilité. Si non, je peux essayer de faire ça cette semaine....ça ne devrait pas être bien compliqué à rajouter de manière basique. Donc, si vous en avez besoin, dites le moi ;) ********************************************************************************************************************************************************* Madjid Bouchaïr 6 juin (Il y a 7 jours) À Grégory Merci, Je vais regarder ça. Madjid Bouchaïr 6 juin (Il y a 7 jours) À Grégory Je viens de voir la seconde partie du mail, désolé. La partie jobInfo est tiré du protocol et je cherche justement à la générer, d'où ma question au sujet de la conservation du XML. Elle correspond juste au contenu du XML envoyé avec la requête HTTP "nestée" dans la réponse uws. ********************************************************************************************************************************************************* Grégory Mantelet 6 juin (Il y a 7 jours) À moi Ok. Je n'étais pas sûr d'avoir bien compris la/les question(s), mais maintenant je vois. Donc, si vous envoyez une requête HTTP avec un content-type différent de "multipart/form-data" et "application/x-www-form-urlencoded" (ce qui est fait dans les exemples de VOSpace 2.0), la librairie uploadera ce contenu dans un fichier et y donnera accès en lecture via un paramètre nommé "JDL" dans le job ainsi créé. Comme dit dans mon précédent email, il sera possible d'y accéder avec l'URL: {root-uws}/{joblist}/{jobId}/parameters/JDL J'ai testé avec un UWS de test en local et cela fonctionne comme prévu. Maintenant, je viens de très très rapidement scanner le document VOSpace et d'après ce que je vois, il y aurait deux manières de créer un "job" ou une opération dans VOSpace: * 3.6.1 - XML Document Transfers (celle que vous essayez en ce moment) * 3.6.2 - URL Parameter Transfers (celle implémentée par défaut dans la librairie ; avec des paramètres HTTP) Du coup, vous pourriez d'ores et déjà utilisée la méthode 3.6.2. Mais il semblerait que cette méthode soit limitée ; d'où l'intérêt de la méthode 3.6.1. Toutefois, si j'ai bien compris, pour implémenter et utiliser cette dernière, il faudrait que la librairie crée un jobInfo dans la représentation du job. Comme dit ci-dessus, la partie récupération du contenu de la requête HTTP (c'est à dire le XML vos:transfer) est déjà prise en compte par la librairie. Il "ne manque plus qu'à" le stocker en tant que jobInfo. Le plus gros problème que l'on a maintenant est que ma librairie n'a pas encore de jobInfo. Donc, je peux essayer de rajouter cela. Ce ne sera pas aussi trivial que je le pensais, mais ça doit être faisable. La manière dont je vois ça pour l'instant est que pour y accéder depuis votre JobThread, vous aurez à utiliser la méthode suivante: UWSJob.getJobInfo(): org.w3c.dom.Document Sachant cela, vous pouvez déjà commencer à écrire votre implémentation de JobThread car vous savez que le parsing du XML sera déjà fait et que vous n'aurez qu'à utiliser les méthodes de l'interface org.w3c.dom.Document pour accéder au contenu XML. ==> Est-ce que cette solution vous convient ? Si oui, j'essaie de faire ça dès que possible cette semaine ; vous n'aurez alors qu'à faire un "git pull origin" pour récupérer la version modifiée (ou directement télécharger l'archive zippée sur GitHub). ********************************************************************************************************************************************************* Madjid Bouchaïr 6 juin (Il y a 7 jours) À Gregory C'est exactement ça, j'ai eu du mal a exprimé ma pensée désolé. Oui la méthode par url est très limitée. Madjid Bouchaïr 09:23 (Il y a 1 jour) À Gregory Bonjour, j'espère ne pas vous déranger mais j'ai deux questions au sujet de la librairie. Tout d'abord, je n'arrive pas à récupérer les paramètres sur une requête XML (inspiré par celle présente dans getParameters de la page de démo uws cds). Actuellement j'utilise les arguments de l'url : curl -X POST 'http://localhost:8080/VospaceUws/example/PullFromVoSpace?time=5&target=Foo' Et ça fonctionne sans problème. J'ai essayé d'envoyer le fichier xml suivant : 100 Foo curl -X POST -d @pull.xml 'http://localhost:8080/VospaceUws/example/PullFromVoSpace' Mais seul les valeurs par défaut apparaissent dans le job : 1496925588638A PENDING 0 "1.0" encoding="UTF-8"?><vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.1"> <vos:target>vos://example.com!vospace/myresult1</vos:target> <vos:direction>pullFromVoSpace</vos:direction> <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget" /></vos:transfer> 10 None J'ai conservé le code de TimersWork afin de faire un décompte avant l'execution de l'action. Est-ce que ça vient du xml en lui-même ? Autre question : La librairie ne renvoie pas de réponse 303 à la requête POST. Dois-je le gérer manuellement ou une méthode de la librairie le permet déjà ?