UE NSY107 Technologies logicielles pour la gestion de la distribution CNAM Aquitaine Eric Cariou Université de Pau et des Pays de l'adour UFR Sciences Pau Département Informatique Eric.Cariou@univ-pau.fr 1
Evolution technologies De manière +/- orthogonales, plusieurs vues d'évolution au fil du temps Paradigme de programmation Procédural Objet Composant Paradigme de communication à distance Sockets TCP ou UDP Appel de méthode à distance Autres services de communication (message, mémoire partagée...) Intégration dans des plateformes/intergiciels de services annexes (transaction, sécurité, temps, réplication...) Puis une évolution vers plateformes de composants 2
Evolution technologies Outre la communication à distance, l'évolution prend aussi en compte Le besoin de faire communiquer ensemble des éléments hétérogènes Matériel, système exploitation, langage de programmation,... Le besoin de faire communiquer toujours plus d'éléments ensemble Serveurs de fichiers, base de données, serveurs d'applications, logiciels patrimoniaux... Le besoin d'intégrer l'existant (anciennes technos) dans le développement d'un système informatique Il existe encore de très nombreux logiciels écrit en COBOL et... toujours utilisé et au coeur des systèmes des entreprises! 3
Sockets UDP et TCP 4
Sockets Couche de communication la plus basse pour faire communiquer des éléments distribués Attaque directement les couches UDP ou TCP Conséquence : pas besoin de se préoccuper des problématiques réseau pour trouver le destinataire C'est géré par la couche en dessous (réseau : IP) Communication virtuelle directe point à point entre 2 entités Envoie de données «brutes» : séries d'octets Pas de structuration de la communication du point de vue des données envoyées C'est aux éléments communiquants de connaître et déterminer la structure des données brutes qu'ils s'échangent Pauvre de ce point de vue là 5
Placement couches réseau TCP ou UDP Communication entre systèmes aux extrémités Pas de visibilité des systèmes intermédiaires Application TCP/UDP IP Liaison Physique Communication d extrémité à extrémité IP Liaison Physique Application TCP/UDP IP Liaison Physique 6
Adressage Adressage pour communication entre applications Adresse «réseau» application = couple de 2 informations Adresse IP : identifiant de la machine sur laquelle tourne l'appli Numéro de port : identifiant local réseau de l'application Couche réseau : adresse IP Ex : 192.129.12.34 Couche transport : numéro de port TCP ou UDP Ce numéro est en entier d'une valeur quelconque Ports < 1024 : réservés pour les applications ou protocoles systèmes Exemple : 80 = HTTP, 21 = FTP,... Sur un port : réception ou envoi de données Adresse notée : @IP:port ou nommachine:port 192.129.12.34:80 : accès au serveur Web tournant sur la machine d'adresse IP 192.129.12.34 7
Socket : prise Sockets Associée, liée à un port C'est donc un point d'accès aux couches réseaux Services d'émission et de réception de données sur la socket via le port En mode connecté (TCP) Connexion = tuyau entre 2 applications distantes Une socket est un des deux bouts du tuyau Chaque application a une socket locale pour gérer la communication à distance Une socket peut-être liée Sur un port précis à la demande du programme Sur un port quelconque libre déterminé par le système 8
Sockets Une socket est Un point d'accès aux couches réseau TCP/UDP Liée localement à un port Adressage de l'application sur le réseau : son couple @IP:port Elle permet la communication avec un port distant sur une 9 machine distante : c'est-à-dire avec une application distante
Client / serveur avec sockets Il y a toujours différenciation entre une partie client et une partie serveur Deux rôles distincts au niveau de la communication via TCP/UDP Mais possibilité que les éléments communiquant jouent un autre rôle ou les 2 en même temps Différenciation pour plusieurs raisons Identification : on doit connaître précisément la localisation d'un des 2 éléments communiquants Le coté serveur communique via une socket liée à un port précis: port d'écoute Dissymétrie de la communication/connexion Le client initie la connexion ou la communication 10
Client / serveur avec sockets Sockets appliquent un mode client / serveur classique Dans toute interaction client / serveur on retrouvera ces caractéristiques Nécessité pour le client de connaître le serveur Problèmatique d'adressage, nommage... Le serveur est lancé avant les clients et attend des requêtes de leur part Une communication client / serveur est toujours initiée par la partie client 11
Sockets UDP : principe Mode datagramme Envois de paquets de données (datagrammes) Pas de connexion entre parties client et serveur Pas de fiabilité ou de gestion de la communication Un paquet peut ne pas arrivé (perdu par le réseau) Un paquet P2 envoyé après un paquet P1 peut arriver avant ce paquet P1 (selon la gestion des routes dans le réseau) Principe de communication La partie serveur crée une socket et la lie à un port UDP particulier La partie client crée une socket pour accéder à la couche UDP et la lie sur un port quelconque 12
Sockets UDP : principe Principe de communication (suite) Le serveur se met en attente de réception de paquet sur sa socket Le client envoie un paquet via sa socket en précisant l'adresse du destinataire Couple @IP/port Destinataire = partie serveur @IP de la machine sur laquelle tourne la partie serveur et numéro de port sur lequel est liée la socket de la partie serveur Il est reçu par le serveur (sauf pb réseau) Si le client envoie un paquet avant que le serveur ne soit prêt à recevoir : le paquet est perdu Emission non bloquante Réception bloquante 13
Sockets TCP : principe Fonctionnement en mode connecté Phase de connexion explicite entre client et serveur avant comm. Données envoyées dans un «tuyau» et non pas par paquet Flux (virtuels) de données Fiable : la couche TCP assure que Les données envoyées sont toutes reçues par la machine destinataire Les données sont reçues dans l'ordre où elles ont été envoyées 14
Sockets TCP : principe Principe de communication Le serveur lie une socket d'écoute sur un certain port bien précis et appelle un service d'attente de connexion de la part d'un client Le client appelle un service pour ouvrir une connexion avec le serveur Il récupère une socket (associée à un port quelconque par le système) Du coté du serveur, le service d'attente de connexion retourne une socket de service (associée à un port quelconque) C'est la socket qui permet de dialoguer avec ce client Comme avec sockets UDP : le client et le serveur communiquent en envoyant et recevant des données via leur socket 15
Sockets TCP : résumé communication 16
Ex: fonctions de mise en oeuvre en C Création / initialisation socket() : création d'une socket (TCP ou UDP) bind() : liaison d'une socket sur un port particulier Fonctions spécifiques TCP : gestion des connexions connect() : connexion à la partie serveur pour le client accept() (et listen()) : attente de connexion de clients coté serveur Transferts de données recvfrom() : réception de données de la part d'un élément sendto() : émission de données vers un élément En TCP : on est connecté donc communique forcément avec un élément et un seul, pas besoin d'identifier l'émetteur/récepteur Peut utiliser les fonctions systèmes standards read() et write() Fermeture close() : ferme une socket et libére le port utilisé En TCP : rompt la connexion établie 17
Ex. de programme TCP (simplifié) Serveur Lancé sur machine ladybird et attend des connexions sur port 4000 Code coté client // création socket TCP coté client ; pas besoin de la lier sur un port précis, on laisse // le système en prendre un au hasard sock = socket(af_inet, SOCK_STREAM, 0); // création d'une adresse de socket qui contient l'adresse IP de la machine ladybird // et le port 4000 : dans une variable de nom addr_serveur // (code non présenté car un peu complexe vu les structures considérées) // connexion à la partie serveur en utilisant l'adresse créée connect(sock, &addr_serveur, sizeof(addr_serveur)); // on est maintenant connecté à la partie serveur, on lui envoie une chaîne char *message = "bonjour serveur!"; nb = write(sock, message, strlen(message)+1); // strlen(message) + 1 : nombre d'octets à envoyer (longueur chaîne + le '\0' à la fin) 18
Ex. de programme TCP (simplifié) Code coté serveur : // création socket TCP d'écoute sock_ecoute = socket(af_inet, SOCK_STREAM, 0); // liaison de la socket d'écoute sur le port 4000 // addr_serveur : pointe sur le port 4000 (code créant la variable non présenté) bind(sock_ecoute, &addr_serveur, sizeof(addr_serveur)); // attente de connexion d'un client sock_service = accept(socket_ecoute,&addr_client, &lg_addr); // addr_client : contient l'addresse (IP + port) du client qui vient de se connecter // communique avec le client via la socket de service retournée char buffer[100]; int nb; nb = read(sock_service, buffer, 100); // on suppose qu'on sait qu'on reçoit une chaîne char *chaine = malloc(sizeof(char) * nb); memcpy(chaine, buffer, nb); printf(" reçu du client : %s \n", chaine); 19
Avantages Conclusion et limites sockets Communication simple avec un élément distant Inconvénient Communication simple... Pas de structuration des données envoyées : blocs d'octets Que faire en cas d'échec de la connexion (TCP) ou que l'autre élément ne répond pas? Doit gérer tous ces problèmes à la main, explicitement Rompt le paradigme de programmation entre «élément» logiciel L'appel de procédure (ou méthode) sur un élément Doit se ramener à de l'envoi brut de données 20
Vers de l'appel de procédure distant Supposons qu'on dispose d'une librairie gérant des rectangles Structures définies struct point { int x, y; }; struct rectangle { struct point p1, p2; }; typedef int booleen; Opérations associées int calcul_surface(struct rectangle rect); rectangle creer_rectangle(int x1, y1, x2, y2); booleen inclus(struct rectangle r, struct point p); 21
Vers de l'appel de procédure distant Exemple de programme int main() {... int resultat; struct rectangle rect; } rect.p1.x = 12; rect.p2.x = 20; rect.p1.y = 10; rect.p2.y = 15; surface = calcul_surface(rect); printf("surface du rectangle : %d \n", surface);... Ici calcul_surface est une fonction qui est appelée localement Son code est intégré dans l'exécutable compilé ou chargé dynamiquement au lancement (librairie dynamique) 22
Vers de l'appel de procédure distant L'exécution de la fonction main() comporte donc un appel vers la fonction surface_rectangle() de la librairie mais au sein du même exécutable main() calcul_surface() Exécutable chargé en mémoire 23
Vers de l'appel de procédure distant On suppose maintenant que la librairie de gestion de rectangle se trouve sur une autre machine Doit passer par des sockets pour la communication distante Une partie serveur offre les 3 services de la librairie qui sont appelés par une partie client Principe de communication Coté client, on veut appeler une opération Envoi les paramètres de l'opération Mais aussi l'identifiant de l'opération En effet, le serveur peut en exécuter 3, on doit préciser laquelle Le serveur exécute l'opération Le serveur renvoie le résultat au client 24
Vers de l'appel de procédure distant Identification de la fonction à appeler via une énumération enum fonction_t { SURFACE = 1, CREER, INCLUS }; Code coté client // connexion au serveur sock = connect(...); enum fonction_t fonction = SURFACE; struct rectangle rect; rect.p1.x=12; rect.p2.x=20; rect.p1.y=10; rect.p2.y=15; int resultat, nb; // envoi code opération + paramètres write(sock, &fonction, sizeof(fonction)); write(sock, &rect, sizeof(rect)); // réception résultat read(sock, &resultat, &bnb); printf("surface du rectangle : %d \n", surface); 25
Vers de l'appel de procédure distant Code coté serveur // attente de connexion d'un client sock = accept(...); // réception de l'identification de la fonction appelée enum fonction_t fonction; read(sock, &fonction, sizeof(fonction)); // si c'est la fonction de calcul surface if (fonction==surface) { // réception du rectangle int resultat, nb; struct rectangle rect; read(sock, &rect, &nb); // appel de la fonction localement resultat = calcul_surface(rect); }... // renvoi du résultat au client write(sock, &resultat, sizeof(int)); 26
Vers de l'appel de procédure distant Deux exécutables communiquent via des sockets main() code serveur calcul_surface Exécutable coté client Exécutable coté serveur 27
Notes sur partie serveur TCP Code présenté : très simplifié Gére la connexion d'un seul client et une requête du client Pour gestion de la communication avec plusieurs clients Nécessité de plusieurs processus/threads Car blocage en attente de données sur une socket de service par client Car blocage en attente de connexions de nouveaux clients Et doit pouvoir exécuter une réception/connexion dans n'importe quel ordre Principe général Processus principal attend en boucle des connexions A chaque client connecté, on crèe un processus qui gère la communication avec le client connecté Peut exécuter plusieurs requêtes du client au besoin Pseudo code réalisant cela while(true) { socketclient = acceptconnection() newprocessus(socketclient) } 28
Vers de l'appel de procédure distant Résultat de la communication, point de vue du client Aboutit à l'appel de la fonction surface_rectangle() sur un élément distant (partie serveur) Réalise un appel de procédure à distance Problèmes Tout est géré à la main (envoi des données, décodage de la requête coté serveur,...) Que faire si la connexion au serveur échoue? La relancer? A gérer explicitement aussi L'appel de procédure est la construction de base d'interaction entre éléments logiciels On l'a réalisée ici mais en mettant en oeuvre toute une mécanique, c'est relativement caché dans le code Amélioration possible Cacher la mécanique, coté client 29
Vers de l'appel de procédure distant Coté client Création d'une fonction de même signature que celle qu'on veut appeler sur le serveur int calcul_surface(struct rectangle rect) { // envoi code opération + paramètres enum fonction_t fonction = SURFACE; write(sock, &fonction, sizeof(fonction)); write(sock, &rect, sizeof(rect)); } // réception résultat int nb, resultat; read(sock, &resultat, &bnb); return resultat; int main() { // connexion au serveur (sock variable globale) sock = connect(...); } struct rectangle rect; rect.p1.x=12; rect.p2.x=20; rect.p1.y=10;rect.p2.y=15; int resultat = calcul_surface(rect); printf("surface du rectangle : %d \n", surface); 30
Vers de l'appel de procédure distant Nouvelle architecture main() calcul_surface code serveur calcul_surface Exécutable coté client Exécutable coté serveur 31
Vers de l'appel de procédure distant Deux types de code bien découplés Code métier/fonctionnel main() coté client et calcul_surface() coté serveur Code dédié à la gestion de la communication distante Contenu de calcul_surface() coté client et «code serveur» coté serveur Principe appliqué La partie client appelle localement une opération à la signature similaire à l'opération qu'on veut appeler à distance Via une mécanique de communication TCP, la fonction est appelée sur la partie serveur distante L'appel de la procédure distante est (presque) aussi simple qu'un appel de procédure locale et transparence de l'aspect distant On voit facilement qu'on peut généraliser ce principe pour toute opération A partir de la signature de l'opération, on sait ce qu'on doit envoyer et recevoir 32 Peut même aller jusqu'à une automatisation, génération du code
Vers de l'appel de procédure distant L'architecture définie à la forme finale suivante 1. demande d'appel de la fonction Client appel logique de la fonction 6. résultat de la fonction 4. résultat de la fonction Serveur 3. appel de la fonction Talon Client Talon Serveur 2. & 5. Communication via TCP ou UDP La fonction distante est appelée de manière logique/virtuelle comme une fonction locale Des «talons» servent à gérer en pratique la 33 communication distante et l'appel de la fonction concrète
Appel de procédure à distance 34
Idée Appel de procédure à distance Pouvoir appeler «presque» aussi facilement une fonction/opération/méthode sur un élément distant que localement Plusieurs noms génériques RPC RMI Remote Procedure Call (appel de procédure distante) Remote Method Invocation (invocation de méthode distante) Dans un contexte de programmation objet 35
Appel de procédure à distance La technologie d'appel à distance est généralement intégrée dans un ensemble plus global Un middleware (intergiciel) Offre le service d'appel de procédure à distance et un ensemble de services annexes utiles en plus Services «de base» d'un middleware de type RPC/RMI Le service de RPC/RMI en tant que tel Un service d'annuaire Pour identifier les éléments distants voire aussi leurs opérations Un outillage/service de codage des données pour gérer les problèmes d'hétérogénéité des données Un outillage de génération de code Pour générer automatiquement le code des «talons» Pour générer automatiquement les fonctions de codage des données 36
Middleware Middleware (intergiciel en français) : couche logiciel S'intercale entre le système d'exploitation/réseau et les éléments de l'application distribuée Offre un ou plusieurs services de communication entre les éléments formant l'application ou le système distribué Services de plus haut niveau que les communications via sockets TCP/UDP, augmentation du niveau d'abstraction Offre également souvent en plus des services de nommage, transaction, événements, sécurité... Client 1 Client 2 Serveur Middleware Middleware Middleware Couches réseau Système Exploit. Couches réseau Système Exploit.... Couches réseau Système Exploit. Matériel Matériel Matériel Réseau physique 37
Hétérogénéité format de données Système distribué = formé d'éléments hétérogènes Matériel (processeur) Langage de programmation Système d'exploitation Exemple simple de problème d'hétérogénéité Codage des entiers : big-endian et little-endian Deux codages matériels (dans processeurs) qui ne mettent pas les octets dans le même ordre Ex de programme simple communiquant via sockets TCP Client envoie un entier au serveur qui l'affiche, et le serveur renvoie l'entier au client Client : processeur x86, serveur : processeur SPARC 38
Hétérogénéité format de données Code coté client // envoi de l'entier 1105 au serveur int nb1 = 1105; write(sock, &nb1, sizeof(int)); printf("envoye la valeur de %d\n", nb1); // lecture de l'entier renvoyé int nb2; read(sock, &nb2, sizeof(int)); printf("recu en retour la valeur de %d\n", nb2); Code coté serveur // on lit un entier et on le renvoie au client int nb; read(socket_service, &nb, sizeof(nb)); printf("recu valeur de %d\n",nb); write(socket_service, &nb, sizeof(nb)); 39
Hétérogénéité format de données Traces d'exécution Coté client Envoye la valeur de 1105 Recu en retour la valeur de 1105 Coté serveur Recu valeur de 1359216640 Explications Le client reçoit en retour sa valeur d'origine : ça n'est donc pas un problème de transmission ou de corruption de la donnée Codage binaire du nombre envoyé (sur 4 octets, taille d'un int) 1105 = (00000000 00000000 00000100 01010001) 2 En inversant les octets on obtient (01010001 00000100 00000000 00000000) 2 = 2 18 + 2 24 + 2 28 + 2 30 = 262144 + 16777216 + 268435456 + 1073741824 = 1359216640 Le serveur a bien reçu la bonne suite d'octets/bits mais ne l'a pas 40 interprété de la bonne façon car il lit les octets d'un int dans l'autre sens
Hétérogénéité format de données Intéropérabilité entre éléments écrits dans différents langages Comment par exemple échanger des informations sur une personne entre un programme C et un programme Java? Avec coté C struct personne { int age; char *nom; } Avec coté Java public class Personne { protected int age; protected String nom; } Nécessité d'utiliser des codages pivots indépendants des codages matériel et des langages de programmation 41
Architecture middleware RPC/RMI Architecture générale, plusieurs couches Classes du développeur Partie Client Communication logique Partie Serveur/ Servant Accès au middleware Talon Squelette Interne au middleware Elt Communication Elt Communication Système d' exploitation Couche Réseau Couche Réseau Machine A Communication via le réseau Machine B 42
Architecture middleware RPC/RMI Éléments de l'architecture générale 2 catégories (comme pour notre exemple précédent) Éléments communiquants réalisés par le développeur Éléments permettant la communication Description des différents éléments Éléments dont le code est généré automatiquement via des outils du middleware Talon (stub) : élément/proxy du coté client qui offre localement les mêmes opérations (la même interface) que le servant Correspond à ce que fait la fonction calcul_surface() Squelette (skeleton) : élément du coté serveur qui reçoit les requêtes d'appels d'opérations des clients et les lance sur le servant Correspond à ce que l'on a appelé «code serveur» 43
Middleware RPC/RMI Description des différents éléments (suite) Partie client Partie qui appelle l'opération distante Partie serveur Partie qui offre l'opération distante via une interface Appelée aussi «servant» pour certains middleware A implémenter par le développeur : contient le code des opérations de l'interface Correspond à l'implémentation de la fonction calcul_surface() Des 2 cotés : éléments de communication entre parties client/serveur Internes au middleware Attaquent les couches TCP ou UDP via des sockets pour gérer la communication entre les talons et squelettes 44 Dans notre exemple simple : mélangé avec «code serveur» et fonction calcul_surface() coté client
Architecture middleware RPC/RMI Fonctionnement général d'un appel d'opération à distance 1. La partie client récupère via le service de nommage une référence d'objet sur le servant distant En réalité, une référence sur le talon local 2. La partie client appelle une opération sur cette référence d'objet Appel synchrone : la partie client attend que l'appel de l'opération soit terminé pour continuer son exécution 3. Le talon, qui reçoit cet appel, «compacte» (marshall) toutes les données relatives à l'appel (identificateur opération + paramètres) 4. L'élément de communication envoie les données à l'élément de communication coté serveur 5. L'élément de communication coté serveur envoie les données au squelette 6. Le squelette décompacte les données (unmarshall) pour déterminer l'opération à appeler sur le servant 7. L'opération est appelée sur le servant par le squelette 45
Architecture middleware RPC/RMI Fonctionnement général d'un appel d'opération à distance (fin) 8. Le squelette récupère la valeur de retour de l'opération, la compacte et l'envoie au talon via les éléments de communication Même si pas de valeur de retour, on renvoie quelque chose au talon pour l'informer de la fin de l'appel d'opération 9. Le talon décompacte la valeur et la retourne la valeur à la partie client 10.L'appel de l'opération distante est terminé, la partie client continue son exécution Le marshalling/unmarshalling Correspond dans notre exemple à la création et au décodage des messages décrivant l'opération à appeler et ses paramètres ainsi que les valeurs de retour 46
Mid. RPC/RMI : gestion communication Gestion des problèmes de communication entre partie client et servant Problèmes potentiels... Le servant est planté ou inaccessible La requête d'appel d'opération n'a pas été reçue coté servant La réponse à la requête n'a pas été reçue par la partie client L'exécution de l'opération s'est mal passée En cas de problèmes, coté client, on n'a pas reçu la réponse à la requête Doit renvoyer la requête au serveur a priori Mais coté serveur, si l'opération modifie un état doit éviter de rappeller l'opération a priori Plusieurs cas possibles pour gérer cela 47
Mid. RPC/RMI : gestion communication 4 sémantiques possibles pour l'appel d'opérations «Peut-être» On ne sait pas si l'opération a été appelée «Au moins une fois» L'opération a été appelée au moins une fois mais peut-être plusieurs fois également Problème si opération modifie un état (opération non idempotente) «Au plus une fois» L'opération est appelée une seule fois ou on reçoit un message informant qu'un problème a eu lieu et que l'opération n'a pas été appelée «Une fois» Cas idéal mais difficile à atteindre 48
Mid. RPC/RMI : gestion communication Trois caractéristiques pour gérer les requêtes d'appels d'opérations Retransmission de la requête Le client peut redemander au serveur d'appeler l'opération en cas de non réponse reçue de sa part Filtrage des duplicats de requêtes Si le serveur détecte qu'il s'agit d'une redemande d'appel d'opération, il n'exécute pas une nouvelle fois l'opération Retransmission des résultats Le serveur garde un historique des valeurs de retour des opérations et peut renvoyer le résultat retourné pour une opération en cas de nouvelle demande de cette même opération 49
Mid. RPC/RMI : gestion communication Trois combinaisons principales de caractéristiques et sémantiques associées Pas de retransmission de la requête Sémantique «peut-être» Retransmission des requêtes mais pas de filtrage des duplicats de requêtes Sémantique «au moins une fois» Retransmission des requêtes, filtrage des duplicats de requêtes et utilisation de l'historique des réponses Sémantique «au plus une fois» 50
Exemples de middleware RPC/RMI Quelques middlewares RPC/RMI parmi les plus connus Sun RPC Premier middleware RPC à être réellement utilisé Pour le langage C et systèmes Unix CORBA Common Object Request Broker Architecture Norme de middleware par l'omg Intéropérabilité entre langages Java RMI Nativement intégré aux distributions Java DCOM Distributed Component Object Model (DCOM) Solution Microsoft pour Windows Web Services Plus récent, communication au dessus de HTTP Les plateformes composants (EJB,.Net...) communiquent en interne via un middleware RPC/RMI 51
Sun RPC Sun RPC Première implémentation de RPC utilisée massivement Date des années 80 Dédié au langage C et systèmes Unix Comporte déjà tout les éléments de base d'un middleware RPC/RMI Contient / utilise Langage de description de programme Programme = structures de données + signature opérations Technologie de codage de données XDR : external Data Representation Outillage pour génération de code (rpcgen) Annuaire d'enregistrement des programmes (portmap) 52
Sun RPC : XDR XDR : external Data Representation Librairie permettant de coder toute donnée dans un format pivot afin d'éviter les problèmes d'hétérogénéité Définit des fonctions de codage des types de base (int, double, char,...) et des fonctions de codage de tableaux, pointeurs... A partir de ces fonctions, on peut construire une fonction de codage pour n'importe quelle structure définie en C La librairie est implémentée pour chaque Unix et processeur différent (conversion «codage local» «codage pivot») Principe d'utilisation Avant d'envoyer des données à un élément distant, on les code dans le format pivot via les fonctions associées On transmet la version codée En réception, on décode pour passer de la version codée à la représentation locale 53
RPC : définition d'un programme Exemple avec les rectangles Partie du fichier de définition d'un programme RPC Ecrit dans un langage dédié (mais proche du C) struct point { int x; int y; }; struct rectangle { struct point p1; struct point p2; }; (...) program GEOM_PROG { version GEOM_VERSION_1 { int CALCUL_SURFACE(rectangle) = 1; rectangle CREER_RECTANGLE(coordonnees) = 2; booleen INCLUS(param_inclus) = 3; } = 1; } = 0x20000001; 54
RPC : définition d'un programme Chaque programme comporte Description des structures utilisées Définition de la signature des opérations Définition d'un nom et numéro de programme Pour l'identifier Définition d'un nom et d'un numéro de version Plusieurs versions possibles pour un même programme Outil rpcgen s'applique sur fichier de def. du prog. Génère code gestion des données Fichiers «.h» et fonctions XDR associées aux données Génére talon et squelette Reste à implémenter la partie servant avec le code des opérations sur les rectangles 55
RPC : communication client / serveur Exemple des rectangles, code coté client CLIENT client; rectangle rect; int *surface; client = clnt_create("scinfe222", GEOM_PROG, GEOM_VERSION_1, "udp"); if (client == NULL) { perror(" erreur creation client\n"); exit(1); } rect.p1.x=12; rect.p2.x=20; rect.p1.y=10; rect.p2.y=15; surface = calcul_surface_1(&rect, client); printf(" rectangle de surface %d\n", *surface); Fonction clnt_create Crée une connexion avec la partie seurveur, en précisant La machine où il est lancé (scinfe222) Le numéro du programme et sa version (GEOM_PROG, GEOM_VERSION) La couche de communication utilisée, ici UDP 56
RPC : communication client / serveur Coté serveur Il y a un main() dans le talon serveur qui enregistre automatiquement le programme au niveau du portmap Portmap : annuaire référençant tous les programmes RPC s'exécutant sur la machine Avec l'outil système rpcinfo, on peut connaitre la liste des programmes RPC accessibles sur une machine $ /usr/sbin/rpcinfo -n scinfe222 program no_version protocole no_port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100024 1 udp 32768 status 100024 1 tcp 32770 status 391002 2 tcp 32771 sgi_fam 536870913 1 udp 32916 536870913 1 tcp 38950 Notre programme est bien lancé en version 1 (536870913) 10 = (20000001) 16 Il est accesible via UDP (port 32916) ou TCP (port 38950) 57
Sun RPC : conclusion Implémentation efficace d'un middleware RPC / RMI Gestion de l'hétérogénéité des données Ca n'apparait pas dans le code présenté, mais en interne dans les talons, toutes les données sont codées/décodées via XDR Génération automatique de code Implémentation restant à faire est simple Annuaire de programmes Connexion directement à des programmes Pas de besoin de manipuler numéro de port, on est une couche au dessus Limitations Langage C et Unix Passe difficilement à l'échelle sur des réseaux grande distance Sémantique d'appel des méthodes «au plus une fois» Relance les appels (selon des timeouts configurables) mais sans vérifier si l'opération n'a pas déjà été appelée 58
Java RMI Middleware RMI natif de Java Permet d'appeler une méthode sur un objet distant Différence RPC / RMI RMI dans le contexte objet On parle aussi d'objets distribués Caractériques objets distribués L'idée est de généraliser les concepts objets mais dans un contexte distribué En Java, on manipule des références (pointeurs...) sur des objets Avec RMI, on étend cela à des références distantes (Essaie de) ne pas différencier une référence locale d'une distante Prend aussi en compte les aspects d'héritage, de spécialisation, de polymorphisme de manière transparente par rapport à l'aspect distribué Java RMI intégre des mécanismes de téléchargement de code pour récupérer des classes à distance 59
Outils / services Java RMI Description des méthodes appelables à distance Interface Java (quasiment) standard Annuaire : rmiregistry Génération de code : rmic Génération des talons, squelettes Gestion de l'hétérogénité Géré par la machine virtuelle Java (JVM) Java est nativement un langage multi-plateforme Sémantique d'appel «au plus une fois» Avantages Simple d'utilisation et bonne généralisation de l'approche objet au contexte distribué Inconvénients Limité à Java 60
CORBA Common Object Request Broker Architecture Norme définie par l'omg Première version en 1991 Intérêt principal Gestion de l'hétérogénéité poussée plus loin Indépendance des langages de programmation Indépendance des systèmes de programmation Peut par exemple faire communiquer un serveur écrit en C++ sur du Linux avec un client écrit en Java sur du Windows Interface Definition Language (IDL) Langage de définition de structures de données et de fonctions associées (similaire à celui de RPC) Définit un grand nombre de services Services de nommages (pages blanches et jaunes), d'événement, de transaction, de temps... 61
Avantages CORBA Grande interopérabilité, définition de nombreux services C'est une norme Plusieurs éditeurs ont développé des implémentations de la norme (existent des versions libre également) Choix de l'outil Inconvénients C'est une norme... et dans un outil donné : Respect pas toujours complet de la norme Non implémentation de tous les services Pas toujours multi-langage ou gère souvent peu de langages L'aspect «objet» est surtout là pour la programmation de l'application en elle-même Pas dans la définition des types de données et fonctions associées Pas de notion de classe avec héritage dans IDL par exemple Pas vraiment de l'objet distribué donc 62
Web Services Web Services Appel de services (opérations/fonctions) avec support de communication bas niveau qui est HTTP Outils / services : architecture RPC standard Gestion de la communication avec protocole SOAP Gestion hétérogénéité avec codage des données en XML Codage des signatures des services en WSDL Annuaire de services : UDDI Avantages Permet de faire interopérer des éléments très hétérogènes HTTP permet une communication à large distance (Internet) Bien adapté pour les services «gros grain» (quasiment des applications complètes) et à couplage faible (approche SOA : orientée services) Inconvénients Peu performant A limiter à de l'interaction avec services gros grain 63
Du procédural vers le composant et les services 64
Paradigmes de programmation Différents paradigmes de programmation Procédural (C, Pascal,... Fonctionnel (LISP, Scheme,...) Objets (Java, C#, Eiffel, Smalltalk...) Procédural Objet Programme est constitué d'une série de fonctions qui manipulent des données Encapsulation : on se focalise sur les données auxquelles on associe des méthodes de manipulation Programme = ensemble d'objets (structures de données) interagissant entre eux via des appels de méthodes Intérêts approche objet niveau conceptuel Encapsulation, réutilisation, héritage... 65
Point de vue interaction Approche objet L'approche objet caractérise bien mieux les interactions entre éléments Chaque objet possède une interface publique (explicite ou implicite) Ensemble des méthodes publiques qu'on peut appeler sur lui Ensemble des services qu'il offre aux autres objets On peut ainsi plus facilement interconnecter les objets entre eux selon les services qu'ils offrent et qui sont requis par d'autres objets 66
Exemple Approche objet public interface InterA { void met1(); String met2(); } public interface InterB { int met3(); } public class A implements InterA { protected B monb; int met1() {... int nb = monb.met3(); }... public class B implements InterB {... } 67
Exemple Approche objet Classes A et B précisent clairement les opérations qu'on peut appeler sur elles via une interface explicite Permet de savoir les services qu'elles offrent Problème / limite On voit dans le code de met1() de la classe A que la classe A appelle les services offerts par un objet de classe B A requiert les services de l'interface InterB implémentée par B Mais contrairement aux services offerts, les services requis ne sont pas clairement explicités Les objets ne sont jamais indépendants, sont toujours interconnectés à d'autres objets mais sans connaissance explicite de cela (sauf à analyser en détail le code...) Image de la grappe : quand on essaye de «retirer» un objet, de l'isoler, on récupère une grappe d'objets interconnectés 68
Solution? Approche composant Préciser aussi les services requis Quelque chose du style public class A implements InterA require InterB Approche composant Conceptuellement, peut être vu comme une extension de l'approche objet avec explicitation des services requis Composant précise clairement La/les interfaces de services qu'il offre La/les interfaces de services qu'il requiert pour fonctionner On peut ainsi créer une application (ou un composant plus gros) en interconnectant facilement entre eux des composants Une interface requise d'un composant A est connectée à une interface offerte compatible d'un composant B 69
Approche composant Exemple d'application (syntaxe personnelle) 70
Approche composants Intérêts de l'approche composant Séparation claire entre la spécification et l'implémentation Spécification : sémantique précise des services offerts et requis Notion de contrat d'usage Permet de manipuler, tester, valider au niveau spécification/modèle Permet des variantes d'implémentation Vision globale de l'architecture de l'application Construite par interconnexion d'éléments clairement définis Application = assemblage de composants via interfaces Un composant peut aussi être construit de manière hiérarchique Composant composite = assemblage de composant pour former un composant de plus haut niveau Composant = unité de déploiement 71
Approche composant Deux grands types de plateformes composants Approches «conceptuelles» Ce qui vient d'être présenté Langages de description d'architectures (ADL), relativement grand nombre de plateformes On peut également citer l'évolution d'uml La principale nouveauté d'uml 2.0 sont les diagrammes de composants Approches «technologiques» L'aspect pris en compte est moins la composition des composants (interfaces offertes / requises, spécification...) qu'une plateforme de déploiement avec services associés Et uniquement coté serveur en général Entre les deux Corba Component Model (CCM) : norme de l'omg Extension de CORBA pour passer dans une vraie vision composant Peu utilisé en pratique, peu d'implémentations... OpenCCM : université de Lille1 Fractal développé par FT 72
Plateformes industrielles de composant Deux principales plateformes industrielles Entreprise Java Beans (EJB) de Sun COM+ de Microsoft (Dans une moindre mesure : inclut parfois Web Services) Description générale Permet de développer coté serveur des composants métiers Leur offre un support d'exécution Conteneur / structure d'accueil Facilite l'utilisation et le développement des composants Cycle de vie du composant (création, activation...) Interactions à distance (via du RMI/RPC) Services de sécurité, transaction, annuaires... 73
Entreprise Java Beans Modèle technologique de composants Uniquement coté serveur Limité niveau conceptuel : interfaces fournies mais pas requises Trois types d'ebj Entity : orienté entités / données persistantes Session : orienté interaction avec le client Réalise des actions pour le client Avec ou sans état (statefull ou stateless) Créé pour une interaction avec le client, disparaît quand le client ne l'utilise plus Message Driven Bean : communication par message et non appel de services Un EJB possède 2 interfaces Remote : les services offerts par l'ejb aux clients RemoteHome : pour gestion de l'ejb (création, recherche, destruction...) 74
Conteneur Enterprise Java Beans Elément dans lequel s'exécute les EJB Offre des services techniques aux EJB Gestion cycle de vie Transaction pour gestion des données (JTA : Java Transaction API) Annuaire (JNDI : Java Naming and Directory Interface) Un EJB s'enregistre au niveau du JNDI pour qu'on récupère sa référence à distance Sécurité L'existence de ces services techniques permet de n'avoir que du service et logique métier dans les EJB Bon découplage des 2 aspects et facilité d'implémentation des parties métiers grace aux services techniques Communication du client vers le support d'exécution des EJB Via du Java RMI Ou via une servlet/jsp et HTTP 75
Vers une approche services Avantages approche composants Architecture claire de l'application via un ensemble de composants aux interfaces bien définies et interconnectés Limites selon les contextes Couplage fort Un composant nécessite d'être connecté, +/- en permanence, à d'autres composants Implique un déploiement complet de tous les composants Composants sont de relativement «faible grain» Et on peut avoir besoin de vouloir Faire interopérer des éléments gros grain (quasiment voire des applications) Avoir du couplage faible (pas de liaison / connexion forte entre les éléments) Système ouvert et accessible à très large distance (Internet) On ira vers une approche orientée services 76
Approche services SOA SOA : Software Oriented Architecture SOC : Software Oriented Computing Principe On définit des services «gros grain» et à couplage faible Ex : service de facturation, service de gestion de la paie dans un système d'information On s'intéresse plus particulièrement pour la réalisation d'une tache à l'enchaînement des services nécessaires Via leur ordonnancement, des workflows Ex: commande d'un client 1. Appel du service de commande par un client 2. Appel du service de gestion des stocks 3. Appel du service de facturation 4. Appel du service de livraison Ces appels peuvent se faire sur différents éléments / logiciels du système d'information de l'entreprise 77
SOA se focalise sur SOA L'ordonnancement et l'orchestration des services On peut voir donc cela comme une sorte de retour à une vision... procédurale! S'intéresse d'abord aux opérations et leur enchainement qu'à l'encapsalution et la gestion des données (vision objets / composants) Mais à très haut niveau En pratique, on mélangera les 2 approches Les services seront implémentés par des objets ou composants Mise en oeuvre d'une approche SOA La technologie la plus utilisée est les Web Services Mais l'approche SOA ne se limite pas aux Web Services Discipline en pleine expansion, pas mal de travail encore sur Composition / assemblage / orchestration des services Annuaires de services UDDI des web services pas forcément très utilisable à très large échelle (Net) 78
Faisons une pause... 79
Évolution des technologies Évolution permanente des technologies logicielles On vient d'en voir un certain nombre et ça n'est pas fini... Exemple : systèmes distribués Faire communiquer et interagir des éléments distants Évolution dans ce domaine C et sockets TCP/UDP C et RPC C++ et CORBA Java et RMI Java et EJB C# et Web Services A suivre... 80
Évolution des technologies Problème Ca évolue tout le temps alors qu'on a souvent des choses similaires Idée afin de limiter le nombre de technologies Normaliser un standard qui sera utilisé par tous Pour les systèmes distribués Normaliser un intergiciel (middleware) C'était le but de CORBA CORBA : Common Object Request Broker Architecture Norme de l'omg : Object Management Group Consortium d'industriels (et d'académiques) pour développement de standards 81
Évolution des technologies Principes de CORBA Indépendant des langages de programmation Indépendant des systèmes d'exploitation Pour interopérabilité de toutes applications, indépendamment des technologies utilisées Mais CORBA ne s'est pas réellement imposé en pratique D'autres middleware sont apparus : Java RMI Plusieurs implémentations de CORBA Ne réalisant pas tous entièrement la norme Les composants logiciels sont arrivés OMG a développé un modèle de composants basé sur CORBA : CCM (Corba Component Model) Mais Sun EJB, MS.Net, Web Services sont là... 82
Évolution des technologies De plus, «guerre» de la standardisation et/ou de l'universalité Sun : J2EE Plate-forme d'exécution universelle avec langage commun (Java) Intergiciel intégré (RMI), support de composants (EJB) OMG : CORBA Intergiciel universel Multi langages et systèmes Microsoft :.Net Multi langages et systèmes Intergiciel intégré (.Net remoting), supports de composants (COM+) Microsoft, IBM et d'autres (Sun,...) : Web Services Interopératibilité universelle entre composants de toute nature Intergiciel = HTTP + XML Middleware ou middle war? 83
Évolution des technologies Evolutions apportent un gain réel Communications distantes Socket : envoi d'informations brutes RPC/RMI/CORBA : appel d'opérations sur un élément distant presque comme s'il était local Composants : meilleure description et structuration des interactions (appels d'opérations) Paradigmes de programmation C : procédural Java, C++, C# : objet Encapsulation, réutilisation, héritage, spécialisation... EJB, CCM : composants Meilleure encapsulation et réutilisation, déploiement, cycle de vie... 84
Évolution des technologies Conclusion sur l'évolution des technologies Nouveaux paradigmes, nouvelles techniques Il ne s'agit pas que de concurrence entre éditeurs qui proposent des outils similaires Régulièrement, de «vraies» innovations et nouveaux concepts Pour développement toujours plus rapide, plus efficace Rend difficile la standardisation (désuétude rapide d'une technologie) Et aussi car combats pour imposer sa technologie Principes de cette évolution Évolution sans fin La meilleure technologie est... celle à venir 85
Évolution des technologies Quelles conséquences en pratique de cette évolution permanente? Si veut profiter des nouvelles technologies et de leurs avantages : Nécessite d'adapter une application à ces technologies Question : quel est le coût de cette adaptation? Généralement très élevé Doit réécrire presque entièrement l'application Car mélange et du code métier et du code technique Aucune capitalisation de la logique et des régles métiers 86
Exemple Évolution des technologies Application de calculs scientifiques distribués sur un réseau de machines Passage de C/RPC à Java/EJB Impossibilité de reprendre le code existant Pourtant Paradigme procédural à objet/composant Les algorithmes de distribution des calculs et de répartition des charges sur les machines sont indépendants de la technologie de mise en oeuvre Logique métier indépendante de la technologie 87
Principes ingénierie des modèles Partant de tous ces constats Nécessité de découpler clairement la logique métier et de la mise en oeuvre technologique C'est un des principes fondamentaux de l'ingénierie des modèles Séparation des préoccupations (separation of concerns) Besoin de modéliser/spécifier A un niveau abstrait la partie métier La plate-forme de mise en oeuvre De projeter ce niveau abstrait sur une plateforme 88
Model Driven Architecture Approche Model-Driven Architecture (MDA) de l'omg Origine de l'ingénierie des modèles Date de fin 2000 Le MDA est né à partir des constatations que nous venons de voir Évolution continue des technologies But du MDA Abstraire les parties métiers de leur mise en oeuvre Basé sur des technologies et standards de l'omg UML, MOF, OCL, CWM, QVT... 89
Model Driven Architecture Le MDA définit 2 principaux niveaux de modèles PIM : Platform Independent Model Modèle spécifiant une application indépendamment de la technologie de mise en oeuvre Uniquement spécification de la partie métier d'une application PSM : Platform Specific Model Modèle spécifiant une application après projection sur une plate-forme technologique donnée Autres types de modèles CIM : Computation Independent Model Spécification du système, point de vue extérieur de l'utilisateur PDM : Plateform Deployment Model Modèle d'une plate-forme de déploiement 90
Model Driven Architecture Relation entre les niveaux de modèles Projection vers une architecture/ technologie génération de code PIM PSM Code Rétro-ingénierie Rétro-ingénierie Raffinement Raffinement 91
Capitalisation Principes du MDE Approche objets/composants MDE Capitalisation, réutilisation d'éléments logiciels/code Capitalisation, réutilisation de logique métier et de leur modélisation Abstraction Des technologies de mise en oeuvre Permet d'adapter une logique métier à un contexte Permet d'évoluer bien plus facilement vers de nouvelles technologies 92
Modélisation Principes du MDE La modélisation n'est pas une discipline récente en génie logiciel Les processus de développement logiciel non plus RUP, Merise... C'est l'usage de ces modèles qui change Le but du MDE est De passer d'une vision plutôt contemplative des modèles A but de documentation, spécification, communication A une vision réellement productive Pour générer le code final du logiciel pour une technologie de mise en oeuvre donnée 93
Principes du MDE Séparation des préoccupations 2 principales préoccupations Métier : le coeur de l'application, sa logique Plate-forme de mise en oeuvre Mais plusieurs autres préoccupations possibles... Sécurité Interface utilisateur Qualité de service Chaque préoccupation est modélisée par un... modèle Intégration des préoccupations Par transformation/fusion/tissage de modèles Conception orientée aspect 94
Principes du MDE Pour passer à une vision productive, il faut Que les modèles soient bien définis Notion de méta-modèle Pour que l'on puisse les manipuler et les interpréter via des outils Avec traitement de méta-modèles différents simultanément Pour transformation/passage entre 2 espaces technologiques différents Référentiels de modèles et de méta-modèles Outils et langages de transformation, de projection, de génération de code Langages dédiés à des domaines (DSL : Domain Specific Language) 95
Conclusion sur le MDE Le MDE est une nouvelle approche pour concevoir des applications En s'abstrayant des technologies de mise en oeuvre Pour pouvoir s'y adapter plus facilement sans en être dépendant En plaçant les modèles et surtout les méta-modèles au centre du processus de développement dans un but productif Les modèles sont depuis longtemps utilisés mais ne couvrait pas l'ensemble du cycle de vie du logiciel Les méta-modèles existent aussi depuis longtemps (grammaires, DTD XML,...) Nouvelle vision autour de notions déjà connues Automatisation du processus de développement Application de séries de transformations, fusions de modèles Les grands éditeurs de logiciel suivent ce mouvement IBM, Microsoft... 96
Conclusion sur le MDE Problématiques, verrous technologiques, besoin en terme d'outils dans le cadre du MDE Définition précise de modèles et de méta-modèles Langage et outils de transformations, fusion de modèles, tissage de modèles/aspects Traçabilité dans le processus de développement, reverseengineering Gestion de référentiels de modèles et méta-modèles Y compris à large échelle (nombre et taille des (méta)modèles) Exécutabilité de modèles Connaissance et usage du modèle à l'exécution, modèle intégré dans le code Validation/test de modèles et de transformations Interopérabilité entre outils Nécessité de faire coopérer / interagir des outils différents Standards de représentation des modèles 97
Le MDE en pratique Les problèmes restent les mêmes Le but du MDE est de s'abstraire des technologies pour développer une application Mais les outils MDE sont des outils technologiques et sont donc... en concurrence Deux grands concurrents IBM et plateforme Eclipse Framework EMF : Eclipse Modeling Framework Sert de base à un grand nombre d'outils et plugins IDM, grosse activité de recherche mais aussi développement d'outils industriels ATL, Kermeta, TopCased, OpenEmbedd, SmartQVT, Blu Age,... Microsoft avec Visual Studio et DSL Tools Suite Basé sur des technologies Microsoft :.Net Eclipse / EMF a pour l'instant une bonne avance Autres outils : éditeurs UML standards 98
Le MDE en pratique Etat actuel des technologies Réel manque de maturité mais en pleine explosion Plusieurs évolutions parallèles à venir Développement des outils pour créer des DSL Langages relativement petits pour problèmes spécifiques internes à une entreprise Outils de modélisation «générique» Modélisation en UML et ses adpatations / variantes selon domaines Ex : SysML pour la modèlisation système Spécialisation d'outils pour des problèmes précis Génération de code, par ex. outil Blu Age de Netfective Diagramme UML «bas niveau» : en génére une application 3-tiers complète J2EE directement exécutable et fonctionnelle99