Créer votre premier service ZOO¶
Table des matières
Introduction¶
Dans cette partie, nous allons créer et publier un service ZOO simple
appelé Hello
qui retournera simplement un message hello contenant la
valeur d’entrée fournie. Il sera utile pour présenter plus en détails les
concepts généraux de fonctionnement du ZOO-Kernel et du
traitement des demandes.
Service et vue d’ensemble du processus de publication¶
Avant de commencer à développer un service ZOO, vous devriez vous rappeler que dans le ZOO-projet, un service est un couple composé de:
- un fichier de métadonnées : un fichier de configuration de service ZOO (ZCFG) contenant des informations de métadonnées sur un service (fournissant des informations sur les entrées et sorties par défaut / supportées pour un service)
- un fournisseur de services: il dépend du langage de programmation utilisé, mais pour Python c’est un module et pour JavaScript un fichier de script.
Pour publier votre service, ce qui signifie rendre votre Kernel ZOO
conscient de sa présence, vous devez copier un fichier ZCFG dans le
répertoire où zoo_loader.cgi
est situé (dans ce workshop,
/usr/lib/cgi-bin
) ou dans un sous-répertoire.
Warning
seul le fichier ZCFG est requis pour que le service soit considéré comme disponible. Donc, si vous n’avez pas le fournisseur de services, ce qui est le cas ici, une requête Execute échouerait comme nous le verrons plus tard.
Avant la publication, vous devriez stocker votre travail en cours, ainsi, nous allons commencer par créer un répertoire pour stocker les fichiers de votre fournisseur de services :
mkdir -p /home/user/ws_sp/
Une fois que le ZCFG et le module Python sont tous deux prêts, vous pouvez publier simplement en copiant les fichiers correspondants dans le même répertoire que le ZOO-Kernel ou un sous-répertoire.
Créons notre premier fichier ZCFG¶
Nous allons commencer par créer le fichier ZCFG pour le service Hello. Créez le fichier /home/user/ws_sp/Hello.zcfg et ajoutez-y le contenu suivant:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | [Hello]
Title = Return a hello message.
Abstract = Create a welcome string.
processVersion = 2
storeSupported = true
statusSupported = true
serviceProvider = test_service
serviceType = Python
<DataInputs>
[name]
Title = Input string
Abstract = The string to insert in the hello message.
minOccurs = 1
maxOccurs = 1
<LiteralData>
dataType = string
<Default />
</LiteralData>
</DataInputs>
<DataOutputs>
[Result]
Title = The resulting string
Abstract = The hello message containing the input string
<LiteralData>
dataType = string
<Default />
</LiteralData>
</DataOutputs>
|
Note
le nom du fichier ZCFG et le nom entre crochets (ici [Hello]
) doivent être les mêmes et correspondre au nom de la fonction que nous avons définie dans notre fournisseur de services.
Comme vous pouvez le voir dans le fichier de configuration du service ZOO présenté ci-dessus, il est divisé en trois sections distinctes:
- Information de métadonnée principale (de la ligne 2 à 8)
- Liste des Informations de métadonnée en entrée (de la ligne 9 à 19)
- Liste des Informations de métadonnée en sortie (de la ligne 20 à 28)
Vous pouvez obtenir plus d’informations sur le ZCFG depuis la documentation de référence.
Si vous copiez le fichier Hello.zcfg
dans le même répertoire que votre ZOO-Kernel alors vous serez en mesure d’interroger DescribeProcess
en utilisant l’Identifier de Hello
. Le service Hello devrait également être listé dans le document de “Capabilities”.
Tester les requêtes¶
Dans cette section, vous testerez chaque requête WPS: GetCapabilities, DescribeProcess et Execute. Notez que seuls les GetCapabilities et DescribeProcess devraient fonctionner à cette étape.
Tester la requête GetCapabilities¶
Si vous lancez la requête GetCapabilities
:
http://localhost/cgi-bin/zoo_loader.cgi?request=GetCapabilities&service=WPS
Maintenant, vous devriez trouver votre service dans un noeud Process
dans ProcessOfferings
:
<wps:Process wps:processVersion="2">
<ows:Identifier>Hello</ows:Identifier>
<ows:Title>Return a hello message.</ows:Title>
<ows:Abstract>Create a welcome string.</ows:Abstract>
</wps:Process>
Tester la requête DescribeProcess¶
Vous pouvez accéder au ProcessDescription
du service Hello
en
utilisant la requête DescribeProcess
ci-dessous :
http://localhost/cgi-bin/zoo_loader.cgi?request=DescribeProcess&service=WPS&version=1.0.0&Identifier=Hello
Vous devriez obtenir la réponse suivante :
<wps:ProcessDescriptions xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsDescribeProcess_response.xsd" service="WPS" version="1.0.0" xml:lang="en-US">
<ProcessDescription wps:processVersion="2" storeSupported="true" statusSupported="true">
<ows:Identifier>Hello</ows:Identifier>
<ows:Title>Return a hello message.</ows:Title>
<ows:Abstract>Create a welcome string.</ows:Abstract>
<DataInputs>
<Input minOccurs="1" maxOccurs="1">
<ows:Identifier>name</ows:Identifier>
<ows:Title>Input string</ows:Title>
<ows:Abstract>The string to insert in the hello message.</ows:Abstract>
<LiteralData>
<ows:DataType ows:reference="http://www.w3.org/TR/xmlschema-2/#string">string</ows:DataType>
<ows:AnyValue/>
</LiteralData>
</Input>
</DataInputs>
<ProcessOutputs>
<Output>
<ows:Identifier>Result</ows:Identifier>
<ows:Title>The resulting string</ows:Title>
<ows:Abstract>The hello message containing the input string</ows:Abstract>
<LiteralOutput>
<ows:DataType ows:reference="http://www.w3.org/TR/xmlschema-2/#string">string</ows:DataType>
</LiteralOutput>
</Output>
</ProcessOutputs>
</ProcessDescription>
</wps:ProcessDescriptions>
Tester la requête Execute¶
Bien entendu, vous ne pouvez pas encore exécuter votre service car le fichier
Python n’a pas été publié. Si vous essayez la requête Execute
suivante:
http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto
Vous devriez obtenir un ExceptionReport
comme présenté ci-dessous, ce qui est un comportement normal:
<ows:ExceptionReport xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd" xml:lang="en-US" version="1.1.0">
<ows:Exception exceptionCode="NoApplicableCode">
<ows:ExceptionText>Python module test_service cannot be loaded.</ows:ExceptionText>
</ows:Exception>
</ows:ExceptionReport>
Implémentez le Service Python¶
Principes généraux¶
La chose la plus importante que vous devez savoir quand vous
implémentez un nouveau ZOO-Services en utilisant le langage Python est
que la fonction correspondant à votre service retourne une valeur
entière qui représente l’état d’exécution (SERVICE_FAILED
[1] ou
SERVICE_SUCCEEDED
[2]) et prend trois arguments (dictionnaires
Python):
conf
: la configuration de l’environnement principal (correspondant au contenu de main.cfg)inputs
: les entrées demandées / par défaut (utilisées pour accéder aux valeurs d’entrée)outputs
: les sorties demandées / par défaut (utilisées pour stocker le résultat de traitement)
Note
quand votre service retourne SERVICE_FAILED` vous pouvez définir conf[“lenv”][“message”] pour ajouter un message personnalisé dans l’ExceptionReport retourné par le ZOO-Kernel dans ce cas.
Dans ce qui suit, vous trouverez la structure conf
exemple basée sur le
fichier main.cfg
que vous avez vu précédemment.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | {
"main": {
language: "en-US",
lang: "fr-FR,ja-JP",
version: "1.0.0",
encoding: "utf-8",
serverAddress: "http://localhost/cgi-bin/zoo_loader.cgi",
dataPath: "/var/www/zoows-demo/map/data",
tmpPath: "/var/www/temp",
tmpUrl: "../temp",
cacheDir: "/var/www/cache/"
},
"identification": {
title: "Atelier ZOO-Project - FOSS4G-FR 2014",
keywords: "WPS,GIS,buffer",
abstract: "Création d'une application web de recherche de plus courts chemins basée sur la norme WPS",
accessConstraints: "none",
fees: "None"
},
"provider": {
positionName: "Developer",
providerName: "ZOO-Project",
addressAdministrativeArea: "Lattes",
addressCountry: "fr",
phoneVoice: "False",
addressPostalCode: "34970",
role: "Dev",
providerSite: "http://www.zoo-project.org",
phoneFacsimile: "False",
addressElectronicMailAddress: "gerald.fenoy@geolabs.fr",
addressCity: "Denver",
individualName: "Gérald FENOY"
}
|
Dans ce qui suit, vous obtenez une valeur de sortie exemple passée à un service Python ou JavaScript:
1 2 3 4 5 6 7 | {
'Result': {
'mimeType': 'application/json',
'inRequest': 'true',
'encoding': 'UTF-8'
}
}
|
Note
la valeur inRequest
est définie en interne par le ZOO-Kernel
et peut être utilisée pour déterminer depuis le service si la clé a
été fournie dans la requête.
Le ZOO-project fournit une API ZOO qui était à l’origine uniquement
disponible pour les services en JavaScript, mais grâce au travail de
la communauté ZOO-project, maintenant vous avez aussi accès à une
ZOO-API utilisant le langage Python. Grâce à l’API ZOO Python, vous
n’avez plus à retenir la valeur de SERVICE_SUCCEDED
et SERVICE_FAILED
,
vous avez la capacité de traduire n’importe quelle chaîne depuis votre
service Python en appelant la fonction _
(ex: zoo._('Ma chaine a
traduire')
) ou de mettre à jour le statut actuel d’un service en cours
d’exécution, en utilisant la fonction update_status
de la même manière
que vous l’utilisez depuis des services C ou JavaScript.
Le Service Hello¶
Vous pouvez copier / coller ce qui suit dans le fichier
/home/user/ws_sp/test_service.py
.
import zoo
def Hello(conf,inputs,outputs):
outputs["Result"]["value"]=\
"Hello "+inputs["name"]["value"]+" from the ZOO-Project Python world !"
return zoo.SERVICE_SUCCEEDED
Une fois que vous aurez fini l’édition du fichier, vous devriez le
copier dans le répertoire /usr/lib/cgi-bin
:
sudo cp /home/user/ws_sp/* /usr/lib/cgi-bin
Interagir avec votre service en utilisant des requêtes Execute¶
Maintenant, vous pouvez utiliser une requête Execute en utilisant l’url de base suivante:
http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto
Vous pouvez interroger le serveur WPS pour retourner une réponse WPS XML contenant le résultat de votre calcul, en demandant un ResponseDocument (le cas par défaut) ou vous pouvez accéder aux données directement en demandant un RawDataOutput.
- Requête exemple utilisant le paramètre RawDataOutput:
http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&RawDataOutput=Result
- Requête exemple utilisant le paramètre par défaut ResponseDocument:
http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&ResponseDocument=Result
Lorsque vous utilisez ResponseDocument
, il y a un attribut spécifique
que vous pouvez utiliser pour demander au ZOO-Kernel de stocker le
résultat : asReference
. Vous pouvez l’utiliser come ceci :
http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&ResponseDocument=Result@asReference=true
Lorsque le traitement prend du temps, le client doit demander
l’exécution d’un service en mettant à la fois les paramètres
storeExecuteResponse
et status
à true pour forcer une exécution
asynchrone. Cela fera retourner au ZOO-Kernel, sans attendre
l’achèvement de l’exécution du service, mais après le début d’un autre
processus ZOO-Kernel responsable de l’exécution du service, un
ResponseDocument contenant un attribut statusLocation qui peut être
utilisé pour accéder au statut d’un service en cours ou le résultat
lorsque le processus a pris fin [3].
http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&ResponseDocument=Result&storeExecuteResponse=true&status=true
Vous pouvez invoquer l’exécution du service longProcess de la même manière (exécution asynchrone) afin de constater ce qu’il se passe lors de l’exécution de service réellement long à s’exécuter. Vous constaterez l’évolution du poucentage de complétude de l’exécution d’un service ainsi que le message associé.
Conclusion¶
Bien que ce premier service soit vraiment simple, il a été utilisé
afin d’illustrer comment le ZOO-Kernel remplit les paramètres
conf
, inputs
et outputs
avant de charger et d’exécuter
la fonction de votre service, comment écrire un fichier ZCFG, comment
publier un fournisseur de services en plaçant le ZCFG et les fichiers
Python dans le même répertoire que le ZOO-Kernel, et ensuite comment
interragir avec votre service en utilisant à la fois les requêtes
GetCapabilities
, DescribeProcess
et Execute
. Nous verrons
dans la section suivante
comment écrire des requêtes similaires en utilisant la syntaxe XML.
Footnotes
[1] | SERVICE_FAILED=4 |
[2] | SERVICE_SUCCEEDED=3 |
[3] | Pour obtenir l’url de statut en cours dans statusLocation ,
vous aurez besoin d’installer le service utils/status. Si vous n’avez
pas ce service disponible, le ZOO-Kernel donnera simplement l’URL d’un
fichier XML plat stockée sur le serveur qui contiendra, à la fin de
l’exécution, le résultat de l’exécution du service. |