I. Le panneau des préférences▲
Le premier composant de cette réalisation est un panneau des préférences assez simple. Il liste les serveurs UDDI vers lesquels le client peut effectuer des requêtes. Depuis les méthodes base « Sur ouverture » et « Sur fermeture », cette liste est soit chargée automatiquement si la base est lancée pour la première fois ou enregistrée dans les ressources de la base afin de réutiliser la liste d'une session à l'autre. Le client UDDI enverra une requête à chacun des serveurs présents dans cette liste.
Jusque là rien de spécial…
II. L'assistant de recherche UDDI▲
L'assistant de recherche implémente une partie des commandes proposées dans les API d'interrogation. Il permet à l'utilisateur d'effectuer une recherche par mots-clés sur les noms des services Web enregistrés dans les registres UDDI des serveurs listés dans le panneau des préférences.
L'assistant peut se décomposer en trois sections :
- le mot-clé et les paramètres avancés de la recherche ;
- la liste et la documentation des services web candidats retournés par la recherche sur les serveurs UDDI ;
- les détails sur le service Web sélectionné dans la liste des services Web trouvés.
La section avancée n'a pas encore été réalisée. Elle donne simplement une idée du genre d'interface utilisateur qui pourrait être proposée afin de tirer parti des paramètres offerts par les API d'interrogation UDDI.
La fonctionnalité active est la recherche par mot-clé et nous allons étudier sa réalisation à l'aide des possibilités de 4D en tant que client de service Web.
III. Le code▲
Lorsque l'utilisateur après avoir saisi un mot-clé dans le champ correspondant sélectionne le bouton 'Recherche', des requêtes SOAP sont envoyées sur le réseau TCP/IP afin de rechercher le mot-clé. Le nombre de requêtes SOAP dépend du nombre de serveurs UDDI paramétrés dans la liste, à raison de deux requêtes SOAP par serveur UDDI.
IV. L'API find_tModel▲
Un ordre de recherche basé sur le mot-clé est envoyé en utilisant les APIs find_xx. Il reçoit comme réponse une liste d'uuid. Ces derniers sont des id de structure tModels dont le nom correspond ou contient le mot-clé recherché. L'assistant enregistre alors cette liste d'uuid dans un tableau.
Regardons de plus près la méthode UDDI_search. Elle construit la requête SOAP, l'envoie au serveur UDDI, reçoit et analyse la réponse XML.
Le serveur SOAP UDDI fonctionnant en style document, la requête doit être construite manuellement et la réponse reçue analysée de même.
La première étape prépare la requête :
2.
3.
4.
5.
6.
myxml:=
"<find_tModel xmlns
\"
urn:uddi-org:API
\"
generic=
\"
1.0
\"
>"
myxml:=
myxml+
"<name>"
myxml:=
myxml+
$1
myxml:=
myxml+
"</name>"
myxml:=
myxml+
"</find_tModel>"
TEXTE VERS BLOB
(
myxml;
myblob;
Texte sans longueur)
$1 contient le mot-clé sous forme de texte et s'insère dans un modèle précodé. Le texte est ensuite converti en BLOB de manière à pouvoir être passé comme argument à FIXER PARAMETRE SERVICE WEB tandis que APPELER WEB SERVICE l'incluera dans la structure xml qui sera envoyée en tant que requête SOAP au serveur UDDI :
2.
FIXER PARAMETRE WEB SERVICE(
"BlobAsXMLIn"
;
myblob)
APPELER WEB SERVICE(<>
UDDI_vServerList{$2
};
"as"
;
"as"
;
"as"
;
Web Service manuel
)
La partie suivante de la méthode n'est là que pour afficher et mettre à jour le thermomètre de progression.
2.
3.
<>
UDDI_vThermometer:=
35
<>
UDDI_vStatus:=
"En cours de réception et d'analyse"
APPELER PROCESS(
UDDI_VPN)
Nous allons ensuite recevoir une réponse du serveur en style document. Elle contiendra une structure XML brute correspondant au premier élément de l'élément <body> de la réponse SOAP si aucune faute SOAP n'a été remontée :
2.
3.
Si
(
OK=
1
)
LIRE RESULTAT WEB SERVICE(
$theblob
;
"BlobAsXMLOut"
;*)
Fin de si
La fin de la méthode se charge tout particulièrement du Blob XML afin d'y retrouver l'information intéressante (les uuid) et de les enregistrer dans un tableau :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
$i
:=
UDDI_FollowUp
$myroot
:=
Analyser variable XML(
$theblob
)
$myelement
:=
Lire premier element XML(
$myroot
)
$myelement
:=
Lire premier element XML(
$myelement
)
Si
(
OK=
1
)
INSERER LIGNES(<>
arrayuuid;
Taille tableau
(<>
arrayuuid)+
1
;
1
)
INSERER LIGNES(<>
arrayname;
Taille tableau
(<>
arrayname)+
1
;
1
)
$i
:=
UDDI_FollowUp
Repeter
LIRE ATTRIBUT XML PAR NOM (
$myelement
;
"tModelKey"
;<>
arrayuuid{$i
})
$mychild
:=
Lire premier element XML (
$myelement
;
$name
;<>
arrayname{$i
})
$myelement
:=
Lire element XML suivant (
$myelement
)
Si
(
OK=
1
)
INSERER LIGNES (<>
arrayuuid;
Taille tableau
(<>
arrayuuid)+
1
;
1
)
INSERER LIGNES (<>
arrayname;
Taille tableau
(<>
arrayname)+
1
;
1
)
$i
:=
$i
+
1
Fin de si
Jusque
(
OK=
0
)
Fin de si
À l'aide des commandes de navigation XML intégrées à 4D, la méthode crée un arbre DOM par l'appel à la commande Analyser variable XML.
Une réponse XML retournée par un serveur UDDI peut être du type :
<tModelList
generic
=
'1.0'
xmlns
=
'urn:uddi-org:API'
operator
=
'XMethods'
>
<tModelInfos>
<tModelInfo
tModelKey
=
'uuid:B89C49D5-CAB7-697E-BC18-AC129D170E99'
>
<name>
zipCodeService</name>
</tModelInfo>
<tModelInfo
tModelKey
=
'uuid:CCD10262-9509-4B67-D619-C68D18265432'
>
<name>
zip 2 Geo</name>
</tModelInfo>
</tModelList>
Les deux premiers appels à Lire premier element XML sur $myroot
et $myelement
permettent de sauter les deux premiers éléments. Il serait préférable de vérifier les noms des éléments, mais cette approche nous permet d'atteindre plus vite le cœur des données. Il suffit alors d'une boucle Repeter pour extraire les uuid et les noms de tous les éléments tModels retournés. Une fois les données extraites, elles sont insérées dans les tableaux <>
arrayuuid et <>
arrayname.
Lors de l'analyse de la réponse du serveur, avant qu'une autre requête SOAP ne soit envoyée au prochain serveur de la liste, il est nécessaire de connaître les détails du tModel en se référant aux uuid que nous venons de « mettre en cache » dans des tableaux.
V. L'API get_tModelDetails▲
Une autre méthode envoie donc une deuxième requête SOAP au serveur UDDI en utilisant les deuxièmes API d'interrogation : get_xx. Elle demande des détails au serveur concernant les tModels référencées par les uuid listés dans les deux tableaux construits dans le paragraphe précédent. S'agissant une nouvelle fois d'une requête SOAP de style document, nous devons la préparer par programmation :
2.
3.
4.
5.
6.
myxml:=
"<get_tModelDetail xmlns=
\"
urn:uddi-org:API
\"
generic=
\"
1.0
\"
>"
Boucle
(
$u
;
UDDI_FollowUp;
Taille tableau
(<>
arrayname))
myxml:=
myxml+
"<tModelKey>"
+<>
arrayuuid{$u
}+
"</tModelKey>"
Fin de boucle
myxml:=
myxml+
"</get_tModelDetail>"
TEXTE VERS BLOB
(
myxml;
myblob;
Texte sans longueur)
Les références uuid sont incluses dans un template XML codé en dur. Puis la structure XML est convertie en BLOB avant d'être passée comme paramètre à la commande FIXER PARAMETRE WEB SERVICE afin d'être incorporée dans la requête émise par APPELER WEB SERVICE.
2.
FIXER PARAMETRE WEB SERVICE(
"BlobAsXMLIn"
;
myblob)
APPELER WEB SERVICE(<>
UDDI_vServerList{$1
};
"as"
;
"as"
;
"as"
;
Web Service manuel
)
La suite ne sert qu'à afficher et mettre à jour le thermomètre de progression.
2.
3.
<>
UDDI_vThermometer:=
55
<>
UDDI_vStatus:=
"Analyse des informations recues"
APPELER PROCESS(
UDDI_VPN)
Puis, si aucune faute SOAP n'a été remontée, nous récupérons la réponse du serveur :
2.
3.
Si
(
OK=
1
)
LIRE RESULTAT WEB SERVICE(
$theblob
;
"BlobAsXMLOut"
;*)
Fin de si
La structure XML reçue est à analyser. Nous sommes seulement intéressés par neuf des propriétés de chaque tModel, que nous rangerons dans un tableau 2D :
TABLEAU TEXTE
(<>
arrayresult;
0
;
9
)
Ci-dessous un exemple de réponse d'un serveur UDDI :
<tModelDetail
generic
=
"1.0"
operator
=
"XMethods"
xmlns
=
"urn:uddi-org:api"
>
<tModel
operator
=
"XMethods"
tModelKey
=
"uuid:B89C49D5-CAB7-697E-BC18-
<AC129D170E99"
>
<name>
zipCodeService</name>
<description>
SHORT DESCRIPTION: Find distance between two zip codes,
Find all zip codes in the given distance</description>
<description>
DETAILED DESCRIPTION: findZipCordinates - returns latitude
and longitude for a given zip code findZipCodeDistance - find the
distance between two zip codes getCodeSet - finds a set of zipcode
within given distance from the specified zip code findZipDetails -
experimental! If you like it - have a look at
www.controtex.com/drinkware.htm</description>
<description>
USAGE NOTES:</description>
<description>
HOMEPAGE URL: http://www.controtex.com</description>
<overviewDoc>
<description>
wsdl link</description>
<overviewURL>
http://www.discoverdance.co.uk/zipQuery/zipCodeService.asm
x?wsdl#zipCodeServiceSoap</overviewURL>
</overviewDoc>
<categoryBag>
<keyedReference
keyName
=
"uddi-org:types"
keyValue
=
"wsdlSpec"
tModelKey
=
"uuid:C1ACF26D-9672-4404-9D70-39B756E62AB4"
/>
</categoryBag>
</tModel>
...
</tModelDetail>
La ligne suivante permet de construire l'arbre DOM en mémoire :
$myroot
:=
Analyser variable XML(
$theblob
)
La ligne d'après ne participe pas à l'analyse, mais sert à l'affichage du thermomètre afin d'offrir une progression linéaire.
$div
:=
Compter elements XML(
$myroot
;
"tModel"
)
La phase d'analyse consiste en une boucle de récupération de chaque élément tModel. Pour chacun d'entre eux, les données sont traitées afin d'être extraites et rangées dans le tableau 2D. Certaines informations figurent dans la structure XML en tant que valeur d'élément tandis que d'autres sont présentes en tant qu'attributs.
D'abord, nous extrayons les trois attributs de l'élément tModel : le nom autorisé, l'opérateur et le tModelKey :
2.
3.
4.
5.
6.
7.
8.
9.
`AuthorizedName
LIRE ATTRIBUT XML PAR NOM(
$myelement
;
"authorizedName"
;
$titi
)
<>
arrayresult{$i
}{1
}:=
$titi
`Operator
LIRE ATTRIBUT XML PAR NOM(
$myelement
;
"operator"
;
$titi
)
<>
arrayresult{$i
}{2
}:=-
$titi
`tModelKey
LIRE ATTRIBUT XML PAR NOM(
$myelement
;
"tModelKey"
;
$titi
)
<>
arrayresult{$i
}{3
}:=
$titi
Comme en XML l'ordre des éléments n'est pas déterminé, une structure Au cas où est utilisée au sein d'une structure de boucle « Repeter…jusque » afin de récupérer tous les éléments enfants de tModel et de les filtrer suivant leur nom pour les ranger à leur place dans le tableau 2D :
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.
$mychild
:=
Lire premier element XML(
$myelement
;
$name
;
$titi
)
Repeter
Au cas ou
: (
$name
=
"name"
)
<>
arrayresult{$i
}{4
}:=
$titi
$mychild
:=
Lire element XML suivant(
$mychild
;
$name
;
$titi
)
: (
$name
=
"description"
)
<>
arrayresult{$i
}{7
}:=<>
arrayresult{$i
}{7
}+
Caractere
(
13
)+
$titi
$mychild
:=
Lire element XML suivant(
$mychild
;
$name
;
$titi
)
: (
$name
=
"overviewDoc"
)
$mysecondchild
:=
Lire premier element XML(
$mychild
;
$name
;
$titi
)
Repeter
Au cas ou
: (
$name
=
"description"
)
<>
arrayresult{$i
}{7
}:=<>
arrayresult{$i
}{7
}+
$titi
+
Caractere
(
13
)
: (
$name
=
"overviewURL"
)
<>
arrayresult{$i
}{6
}:=
$titi
Fin de cas
$mysecondchild
:=
Lire element XML suivant (
$mysecondchild
;
$name
;
$titi
)
Jusque
(
OK=
0
)
$mychild
:=
Lire element XML suivant(
$mychild
;
$name
;
$titi
)
: (
$name
=
"identifierBag"
)
Lire premier element XML(
$mychild
;
$name
;
$titi
)
<>
arrayresult{$i
}{8
}:=
$titi
$mychild
:=
Lire element XML suivant(
$mychild
;
$name
;
$titi
)
: (
$name
=
"categoryBag"
)
Lire premier element XML(
$mychild
;
$name
;
$titi
)
<>
arrayresult{$i
}{9
}:=
$titi
$mychild
:=
Lire element XML suivant(
$mychild
;
$name
;
$titi
)
Fin de cas
Jusque
(
OK=
0
)
Les quelques lignes suivantes ont pour effet de se déplacer jusqu'au prochain élément tModel, puis de recommencer la boucle de traitement ou de sortir si aucun autre tModel n'est disponible :
2.
3.
4.
5.
$myelement
:=
Lire element XML suivant(
$myelement
)
Si
(
OK=
1
)
INSERER LIGNES(<>
arrayresult;
Taille tableau
(<>
arrayresult)+
1
;
1
)
$i
:=
$i
+
1
Fin de si
Ces deux opérations find_tModel et get_tModelDetails sont réitérées sur l'ensemble des serveurs UDDI listés dans le panneau des préférences.
Lorsque le tableau 2D &
lt;>
arrayresult est rempli, le résultat de la recherche est prêt pour l'affichage dans la fenêtre de l'assistant UDDI.
VI. Utilisation de la démo▲
Ouvrez la base de données, s'il s'agit du premier lancement, une alerte vous demandera d'ouvrir le panneau des préférences.
Ouvrez le panneau des préférences depuis la barre de menu : UDDI/Préférences
Vous pouvez alors laisser la liste telle quelle ou ajouter/supprimer des serveurs UDDI
Ouvrez l'assistant de recherche UDDI. Vous pouvez toujours cliquer sur le bouton ‘Avancé…' pour consulter les possibilités offertes par les API UDDI. Cependant, n'essayez pas de les utiliser : il ne se passera pas grand-chose et vous risquez d'être déçus !
Recliquez sur le bouton 'Avancé…' afin de masquer la section des options supplémentaires et revenir au mode de recherche normal.
Entrez un mot-clé quelconque pour effectuer une recherche sur le nom d'un service Web. Ex. : « zip » (pour code postal).
Cliquez sur le bouton 'Rechercher' pour déclencher une interrogation. Il se peut qu'une attente de quelques secondes soit nécessaire en fonction de la vitesse de la connexion Internet.
Une liste des services Web trouvés devrait ensuite apparaître dans la zone de défilement de gauche.
Vous pouvez sélectionner n'importe lequel des services listés (comme dans l'assistant de service Web) et consulter la documentation associée dans la zone de texte de droite.
Vous pouvez également accéder à la section 'Plus…' pour visualiser les détails du service sélectionné.
Cliquez sur le lien WSL pour afficher le WSDL dans votre navigateur par défaut ou tapez ctrl-c au clavier pour copier le lien dans le presse-papiers. Vous pouvez alors coller ce lien dans l'assistant Web service de 4D afin d'inspecter le WSDL et d'utiliser le service correspondant.
Il se peut que vous rencontriez des problèmes avec le lien WSDL retourné. Cela vous démontrera pleinement l'intérêt de maintenir les serveurs UDDI. Beaucoup des services Web listés autant sur les serveurs UDDI de Microsoft que d'IBM sont maintenant obsolètes et rendent ainsi ces serveurs inutilisables. xMethods.net étant considéré comme le pivot des services Web, je recommande d'utiliser seulement xMethods.net comme serveur UDDI.
VII. Base exemple▲
Téléchargez la base exemple :
pour Windows
pour MacOs