Open WPS Platform

Créer votre premier service ZOO

Introduction

Dans cette partie, vous allez 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 de présenter plus en détails le concept général sur la manière pour le ZOO-Kernel de fonctionner et traiter les 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).

Warning

seul le fichier ZCFG est requis pour le service pour être considéré comme disponible. Donc, si vous n’avez pas le fournisseur de services, évidemment, votre requête Execute échouera comme nous le verrons plus tard.

Avant la publication, vous devriez stocker votre travail en cours, ainsi, vous aurez donc commencer par créer un répertoire pour stocker les fichiers de votre fournisseur de services:

mkdir -p /home/user/zoo-ws2013/ws_sp/cgi-env

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.

Créez votre premier fichier ZCFG

Vous allez commencer par créer le fichier ZCFG pour le service Hello. Modifier le fichier /home/user/zoo-ws2013/ws_sp/cgi-env/Hello.zcfg et ajouter 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 vous allez définir dans votre 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:

  1. Information de métadonnée principale (de la ligne 2 à 8)

  2. Liste des Informations de métadonnée en entrée (de la ligne 9 à 19)

  3. 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 Kernel ZOO 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 à ProcessDescription du service Hello en utilisant la requête DescribeProcess suivante:

http://localhost/cgi-bin/zoo_loader.cgi?request=DescribeProcess&service=WPS&version=1.0.0&Identifier=Hello

Vous devriez avoir 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

Évidemment, vous ne pouvez pas exécuter votre service car le fichier Python n’a pas encore é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 similaire à celui fournit par la suite, 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 Kernel ZOO dans ce cas.

Vous obtenez dans ce qui suit une valeur conf exemple basée sur le fichier main.cfg que vous avez vu avant.

 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/temp/"
  },
  "identification": {
    title: "The ZOO-Project WPS Server FOSS4G 2013 Nottingham Workshop",
    keywords: "WPS,GIS,buffer",
    abstract: "Demo version of Zoo-Project for OSGeoLiveDVD 2013. See http://www.zoo-project.org",
    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-projet fournit une ZOO-API qui était à l’origine uniquement disponible pour les services de JavaScript, mais grâce au travail de la communauté ZOO-projet, maintenant vous avez aussi accès à une ZOO-API utilisant le langage Python. Grâce à la ZOO-API 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 et coller ce qui suit dans le fichier /home/user/zoo-ws2013/ws_sp/cgi-env/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/zoo-ws2013/ws_sp/cgi-env/* /usr/lib/cgi-bin

Interragir avec votre service en utilisant des requêtes Execute

Maintenant, vous pouvez interroger 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, demandant ResponseDocument ou vous pouvez accéder aux données directement depuis RawDataOutput.

  • Requête example 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 example 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 Kernel ZOO de stocker le résultat: asReference. Vous pouvez utiliser l’exemple suivant:

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 [# f3] _.

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

Conclusion

Même si ce premier service était vraiment simple, il était utile pour illustrer comment le ZOO-Kernel remplit les paramètres conf, inputs et outputs avant pour charger et exécuter votre service de fonction, 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, ensuite comment interragir avec votre service en utilisant à la fois les requêtes DescribeProcess et Execute. Nous verrons dans la section suivante comment écrire des requêtes similaires en utilisant la syntaxe XML.

Notes de pied de page

[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.