Vous êtes sur la page 1sur 189

Architectures Logicielles

Distribuées

2ème Année GI

Mohammed Karim GUENNOUN

1
Plan
 Concepts généraux des architectures logicielles
– Les niveaux d’abstraction d’une application
– Les modèles architecturaux classiques
– La communication
– Les modèles de développement
 Projection vers des middlewares
– MOM:
 Sockets Java
– RMI:
 Java RMI

2
Les trois niveaux
d’abstraction

3
Les niveaux d’abstraction

 En règle générale, une application est


constituée de 3 niveaux d’abstraction:
– La couche présentation
(presentation layer) Client
– La couche application

Système d’information
(application logic layer) Présentation
– La couche gestion des ressources
Applicative
(ressource management layer)
Ressources
4
La couche présentation (1/2)

 Tout système doit communiquer avec des entités


externes:
– Humains
– Autres machines …
 Besoin de présenter convenablement l’information
à ces entités:
– Objectif: permettre de soumettre des opérations et d’avoir
les réponses
 Les éléments qui permettent ce type de traitement
appartiennent à la couche présentation
5
La couche présentation (2/2)

 Les éléments de cette couche ne doivent pas


être confondus avec le client.
 Le client est l’utilisateur du système
 Exemples de module de présentation:
– Interface graphique (GUI)
– Pages/Formulaires HTML
– Application mobile

6
La couche application

 Le système doit délivrer de l’information


 Généralement, il effectue des tâches de calcul
sur des données
 Il implémente les opérations requises par le
client à travers la couche présentation
 Les modules, programmes et composants qui
réalisent cette implémentation constituent la
couche applicative.

7
La couche application

 Les éléments sont appelés: services


 Exemple: service de retrait sur compte bancaire:
– Prend la requête de retrait
– Vérifie que le compte est assez approvisionné
– Vérifie que le plafond de retrait n’est pas atteint
– Donne l’autorisation de retrait pour la somme demandée
– Met à jour le nouveau solde
 Autre appellation pour ce niveau: processus
business, logique business, règles business, ou
simplement: serveur.

8
La couche gestion de ressources

 Les systèmes d’information ont besoin de


données sur lesquels travailler
 Les données sont stockées sur
– Bases de données
– Fichiers
– ERPs…
 La couche ressources correspond à ce type
d’entités

9
Couche gestion de ressources

 Autre appellation: couche données


 Cela correspond au mécanismes de
stockage persistant des données
 Dans des architectures plus complexes, la
couche gestion de ressources peut aussi
être un autre système d’information

10
Des couches conceptuelles
vers les tiers
 Les trois couches présentation, application, et ressources sont des
couches conceptuelles pour séparer les fonctionnalités d’un système
 Dans les systèmes réels, ces couches peuvent être distribuées et
combinées de différentes manières
 On parle alors de tiers
 Selon l’organisation considérée pour ces tiers, on obtient les
modèles architecturaux:
– 1-tier
– 2-tier
– 3-tier
– N-tier

11
L’architecture 1-tier

12
Il était une fois…
l’architecture 1-tier

 Historiquement, au début
– Gros serveurs et calculateurs isolés Client
– Une interface réduite à un invite de
commande Présentation
– Problématique principale: utiliser
efficacement la CPU
 Systèmes monolithiques Application
 Les trois couches sont dans le même
tier Ressources
 Le système vu comme une boîte noire Architecture
 Pas d’interaction avec d’autres 1-tier
13
systèmes ni d’API
Avantages

 Possibilité de fusionner à souhait les différentes


couches pour optimiser l’application
 Pas besoin de maintenir et de publier une
interface
 Investissement nul dans des transformations
complexes de données pour la compatibilité
 Coût nul concernant le développement des
clients et le déploiement de l’application.
 Sécurisation et diagnostiquabilité plus simples

14
Inconvénients

 Un code monolithique et complexe


 Efficace mais très couteux et difficile à
maintenir
 Obsolète par rapport au matériel
 L’industrie du logiciel à pris le chemin
opposé.

15
L’architecture 2-
tier

16
L’architecture 2-tier
 Emergence due à l’apparition du PC
 Coexistence de machines moins puissantes (PC et stations de
travail) avec de grosses machines (calculateurs et serveurs)
 Pour les designers:
– Besoin de garder ensemble les couches gourmandes en ressources
– La couche présentation est mise avec le client
 Avantages principaux:
– Liés intrinsèquement à la distribution: Accès distants/Accès
concurrents/Composabilité/Tolérance aux fautes/Load
Balancing/Multiplication des IHM…
– La couche présentation est déplacée dans le PC libérant de la puissance
de calcul pour les deux autres couches

17
L’architecture 2-tier
Client
 L’architecture 2-tier devient Présentation

Système d’information
très populaire. On parle
alors d’architecture Client-
Serveur Application

Serveur
 Le tier client correspond à la
couche présentation Ressources

 Le tier serveur englobe les


deux couches application et
gestion des ressources
18
Client léger Vs Client lourd

 Le client peut implémenter quelques fonctionnalités du serveur.


 Selon la complexité du client on parle de
– Clients légers qui offrent seulement des fonctionnalités minimales
– Clients lourds avec la prise en compte de certains traitements
 Les clients légers
– Sont faciles à installer, déployer, maintenir
– Ont besoin de peu de ressources de calcul
– Peuvent être déployés sur un large spectre de machines
 Les clients lourds
– Ont besoin de plus de ressources de calcul
– Ne peuvent être déployés sur des machines légères

19
Développements associés à
l’architecture Client-Serveur

 Les systèmes client-serveur ont permis plusieurs


avancées dans les domaines du logiciel et du matériel
avec une boucle vertueuse:
– Avec l’augmentation des ressources dans les PCs et les stations
de travail, la couche client est devenue de plus en plus
sophistiquée.
– La sophistication des clients a poussé vers une amélioration des
performances dans les machines et dans les réseaux
 L’approche C-S est associée avec des développements
cruciaux dans les systèmes distribués
– La notion de RPC (Remote Procedure Call). Interaction à base
d’appel de procédure.
– La notion d’interface de connexion
20
Avantages sur le 1-tier

 La distribution avec tous ses avantages…


 Les couches application et ressources sont
ensembles
– L’exécution des opérations reste performante
 Indépendance du client et du serveur
– Portabilité sur plusieurs plateformes
– Possibilité de définir des couches présentation
différentes pour différents clients à moindre coût

21
Inconvénients

 Apparition de problématiques nouvelles


– Les problématiques de communication
– Les accès concurrents
– Passage à l’échelle (scalability)
– Sécurité
– La recherche et publication
– Les transactions

22
Architecture 3-tier

23
L’architecture 3-tier
 Une séparation claire entre les
différentes couches abstraites:
Client
– La couche présentation réside
chez le client Présentation

Système d’information
– La couche application réside dans
le tier du milieu
 L’infrastructure qui supporte le Middleware
développement de la logique Application
business est appelée middleware
– La couche gestion de ressources
réside dans un troisième tier Ressources
24
Comparaison avec l’architecture 2-tier

 Dans l’architecture 2-tier la couche application et gestion des ressources sont


co-localisées
– Avantage: le coût de la communication est nul
– Inconvénient: il faut une machine puissante pour exécuter les deux
 Pour l’architecture 3-tier, séparation des deux couches
– Avantage:
 Possibilité de les distribuer sur différentes machines
 Augmentation de la performance en terme d’exécution
 Les deux sont moins liées
 Reutilisabilté
 Maintenabilité
– Inconvénient:
 Complexité de l’architecture
 Coût de communication additionnel entre les deux couches
25
Développements liés à l’architecture 3-tier

 L’apparition d’architectures 3-tiers a engendré des avancées:


– Les gestionnaires de ressources ont dû s’adapter pour offrir des interfaces
permettant la communication avec la couche application qui s’exécute dans le
middleware
– Apparition de standards de communication pour les gestionnaires de
ressources pour un accès uniforme de la couche application
 Java DataBase Connectivity: JDBC
 ORMs
 L’architecture 2-tier a forcé l’apparition d’API pour la couche
application alors que l’architecture 3-tier a provoqué
l’apparition d’API pour la couche gestion des ressources

26
Développements liés à l’utilisation des
middlewares (1/2)

 L’apparition des architectures 3-tier a induit


l’apparition de middleware permettant:
– Une intégration aisée de la logique métier
– Des fonctionnalités pour la gestion des
ressources:
 Recherche/Publication
 Communication
 Accès concurrents/gestion des instances
 Persistence
 Garanties transactionnelles
27
 …
Développements liés à l’utilisation
des middlewares (2/2)

 Les concepteurs se concentrent sur la logique


métier et profitent du support offert par le
middleware pour le développement des
interactions complexes
 La perte de performance liée à l’augmentation du
coût de communication est généralement
compensée par la possibilité de distribuer le tier
du milieu sur plusieurs nœuds machine
augmentant la scalabilité et la disponibilité

28
Inconvénients

 Les inconvénients de l’architecture 3-tier sont


aussi liés aux problèmes d’intégration
– Pour l’architecture 2-tier, le problème venait de la
difficulté de faire interagir un client avec différents
types de serveurs
– Pour l’architecture 3-tier, le problème vient de la
nécessité d’intégrer des applications inter-
organisations et inter-réseaux
– L’absence de standard de communication entre les
différentes architectures est un handicap majeur

29
L’architecture N-
tier

30
L’architecture N-tier

 Les architectures N-tier ne constituent pas


réellement une évolution architectural par
rapport à l’architecture 3-tier
 C’est une extension de ce modèle en
considérant l’Internet comme un canal
d’intéraction
 La majorité des systèmes construits
actuellement

31
Une architecture N-tier Client
Explorateur
Web

 La couche Présentation est scindée


en deux tiers Serveur
– Un tier Client comprenant un Web
Tier Web
explorateur Web et des pages

Système d’information
Moteur
HTML, HTML
– Un tier Web comprenant le
serveur Web et le code qui
prépare les pages HTML Middleware
Couche
 Les tiers Application et Gestion de Application
données gardent la même
sémantique
Couche
Ressources
32
La distribution
 En passant de l’architecture 1-tier vers la 2-tier, 3-tier, et
N-tier, on assiste a une constante addition de tiers.
 Avec chaque tier,
– l’architecture gagne en
 Flexibilité
 Fonctionnalité
 Distribution
– Perd en performance avec l’augmentation du coût des
communications entre les différents tiers
– Introduit plus de complexité pour la gestion et la maintenance
 Il faut que le gain en flexibilité et en scalabilité compense la
33
perte de performance due à la communication
Communication
dans les systèmes
d’information

34
La communication dans les systèmes
d’information

 Nous avons discuté comment les couches


abstraites et les tiers peuvent être combinés et
distribués
 Séparer le systèmes en plusieurs tiers implique
l’implémentation d’une certaine communication
entre ces éléments
 La caractéristique dominante des différents
mode d’interaction correspond aux choix
synchrone ou asynchrone
– Appels bloquants ou non bloquants

35
Interactions
Synchrones

36
Interaction synchrone

 Dans une interaction synchrone un processus qui appelle


un autre doit attendre la réponse avant de continuer ses
traitements.
Le processus Le processus
appelant invoqué
Période de

Requête
blocage

Réponse

37
Avantages (1/2)

 Attendre la réponse avant de continuer


présente plusieurs avantages:
– Simplifier la conception
– L’état du processus appelant n’est pas altéré entre son
appel et la réponse
– Corrélation simple entre le code qui fait l’appel et le code
qui traite la réponse (les deux bouts de code sont en
séquence)
– Les composants sont fortement liés pour chaque
interaction. Plus de facilité pour le test, le débogage, et
38 l’analyse de performance
Avantages (2/2)

 Au passage de l’architecture 1-tier vers 2-tier, la


majorité des systèmes utilisent du synchrone
pour la communication entre clients et serveur

 Au passage vers l’architecture 3-tier, la majorité


des serveurs de données offrent une
communication synchrone avec la couche
application

39
Inconvénients

 Certains avantages peuvent être aussi vus comme des


inconvénients spécialement quand l’interaction n’est pas
de type requête-réponse (e.g. one way)
 Perte de temps et de ressources calcul si le traitement
côté serveur est long
 Le problème de performance augmente avec
l’augmentation du nombre de tiers
 En terme de tolérance aux fautes, le processus appelant
et le processus invoqué doivent être connectés et
opérationnels lors de l’invocation. Ils doivent le rester tout
au long de l’exécution de la requête
40  Les procédures de maintenance doivent être faites offline
Interactions
asynchrones

41
Les interactions asynchrones

 Quand il est nécessaire de travailler de manière


interactive, le choix synchrone s’impose
 Dans plusieurs cas, cela n’est pas nécessaire
– Impression
 J’envois une demande d’impression
 La demande est insérée dans la liste des taches
 L’imprimante traite la tache quand elle est disponible
 La machine est notifiée de la fin du traitement

42
Les interactions asynchrones
 Au lieu de faire une requête et attendre la réponse
– Envoyer la requête
– Vérifier plus tard si une réponse a été retournée
Le processus Le processus
appelant invoqué
Le processus

put fetch
reste actif

Tampons

fetch put

43
Avantages

 Suivre une approche non bloquante permet:


– Au programme appelant de continuer à réaliser d’autres tâches
pendant le traitement de sa requête
– D’éliminer le traitement de la coordination entre les deux
processus
 Réduction des problèmes dus
– Au nombre de connections
– À la dépendance entre composants
– À la tolérance aux fautes
 Modèle adéquat dans certaines situations (style
publisher-subscriber)
– Un serveur dissémine l’information vers plusieurs clients
44 – Différents clients s’intéressent à différents types d’information
Evolution des concepts de
développement logiciel

45
Applications Procédurales Centralisées

 E.g. C, Pascal, Ada


 L’univers est constitué principalement de
procédures et de fonctions
 Le programme s’exécute sur une machine
unique
 Interactions principalement via une interface
IHM locale

46
L’orienté objet

 E.g. Java, C++, Eiffel


 Vision plus proche du monde réel
 L’univers est constitué principalement d’objets
– Attributs
– Méthodes
 L’orienté objet est plus une vision relative à l’organisation de
l’implantation
– La distribution et le déploiement ne sont pas pris en compte
 Concepts nouveaux:
– Attributs (caractéristiques d’un objets)
– Méthodes (actions possibles sur un objet)

47
L’orienté composant
 E.g. RMI, Corba, ejb
 Au-delà de l’orienté objet
 On s’intéresse maintenant à la structure en terme de
– Décomposition du code exécutable stand-alone (composants)
– Déploiement au niveau des environnements d’exécution
 Objectifs principaux, au sein d’une entité:
– Réutilisation
– Composition
– Facilitation de développement
 Nouveaux Concepts:
– Interface
– Connexions
– Middleware

48
L’orienté service
 E.g. Services Web
 Au-delà de l’orienté-composant
 Le web et les applications inter-entités
 Objectifs principaux
– Développer le e-business
– Publier-rechercher des services sur le web
– Composition dynamique de services
 Nouveaux concepts
– Registres de publications
– Standards de
 Description
 Communication
 Publication

49
Paradigmes de communication

 MOM
– Orienté messages
 RPC
– Orienté procédures
 RMI
– Orienté méthodes

50
Ce qu’il faut retenir

51
Retour sur les thèmes abordés

 Trois couches conceptuelles sont identifiées


– Présentation
– Application
– Gestion de ressources
 Quatre modèles architecturaux
– 1-tier, 2-tier, 3-tier, N-tier
 Deux modèles de communication:
– Client-Serveur
– Publisher-Subscriber
52
La distribution, c’est Darwin!

 La distribution des couches conceptuelles a évolué en


réponse à des évolutions au niveau matériel et réseau
– Avec les gros serveur et calculateurs: l’architecture 1-tier
– Avec les réseaux locaux et l’apparition des PCs et des stations
de travail: l’architecture client-serveur
– Avec la prolifération de l’information et l’augmentation de la
bande passante: l’architecture 3-tier
– Avec l’avènement d’Internet, une bande passante en
augmentation constante, et l’essor du e-business:
l’architecture N-tier

53
L’évolution de la programmation

 De programmes monolithique isolés…


 Vers une structuration des applications en services distribués à
travers le Web
 Développement d’outils et de standards
– Conception
– Développement
– Déploiement
 De plus en plus de génération automatique de code
– Stubs / Skeletons, classes de support
 Décharger un maximum le développeur pour se consacrer à la
logique business

54
Un middleware MOM:
La communication
par Sockets en Java
Fonctionnement
 Deux composants élémentaires
– Serveur
– Client
 Deux phases
– Établissement de la connexion
– Interaction à base d’échange de messages
 Mode synchrone connecté
 L’envoi de message est réalisé par une écriture sur un flux
 La réception de message est réalisée par une lecture sur un flux

56
Architecture

Sockets
Machine 1 d’échange Machine 2

Client Serveur

… … … …

Socket
d’échange Socket
d’écoute
Envoi de messages entre Machine1:Port1 et Machine2:Port2

Port 1
Port 2
Le package

 Le package utilisé pour l’implantation de la


communication par sockets: java.net
 Comprend les classes
– java.net.InetAddress: permet de manipuler les adresses
IP
– java.net.SocketServer: permet de programmer l’interface
côté serveur (sockets d’écoute)
– java.net.Socket: permet de programmer la communication
côté client et serveur (sockets d’échange)
La classe InetAddress (1/2)

 3 méthodes statiques pour créer des objets adresse IP


– public static InetAddress getLocalHost() throws UnknownHostException
 renvoie l'adresse du site local d'appel.
– public static InetAddress getByName(String host) throws
UnknownHostException
 construit un nouvel objet InetAddress à partir d'un nom textuel de site.
 Le nom du site est donné sous forme symbolique (www.ehtp.ac.ma) ou
sous forme numérique (147.127.18.03).
– public static InetAddress[] getAllByName(String host) throws
UnknownHostException
 permet d'obtenir les différentes adresses IP d'un site.
La classe InetAddress (2/2)

 Trois méthodes pour obtenir les informations


sur l’objet adresse IP
– public String getHostName()
 obtient le nom complet correspondant à l'adresse IP
– public String getHostAddress()
 obtient l'adresse IP sous forme %d.%d.%d.%d
– public byte[] getAddress()
 obtient l'adresse IP sous forme d'un tableau d'octets
La classe ServerSocket (1/2)

 Les constructeurs
– public ServerSocket()
 Créée un objet socket d’écoute non liée
– public ServerSocket(int p) throws IOException
 Crée un objet socket à l’écoute du port p. Une valeur 0 implique une
allocation automatique d’un port libre.
 Les getters
– public InetAddress getInetAddress()
 Permet de récupérer l’objet adresse IP
– public int getLocalPort()
 Permet de récupérer le port d’écoute
La classe ServerSocket (2/2)

 Les méthodes
– public Socket accept() throws IOException
 Acceptation de la connection d’un client
 Opération bloquante
 Par défaut, le temps d’attente est infini
– public void setSoTimeout(int timeout) throws SocketException
 L’argument est en milliseconds
 Définit un délai de garde. 0 implique un temps de garde infini
 À l’expiration, l’exception java.io.InterruptedIOException est levée
– public void close()
 Ferme la socket d’écoute
La classe Socket (1/3)
 Utilisée pour la programmation des sockets connectées côté client et serveur.
 Création
– Côté Serveur: résultat de l’appel de la méthode accept
– Côté Client: par l’appel des constructeurs
 public Socket(String host, int port) throws UnknownHostException, IOException
– Ouvre une socket sur une machine et un port côté serveur. Le choix côté client n’est pas
spécifié.
 public Socket(InetAddress address, int port) throws IOException
– Utilise l’objet InetAddress au lieu d’une chaine de caractères
 public Socket(String host, int port, InetAddress localAddr, int localPort) throws
UnknownHostException, IOException
– Spécifie une adresse et un port côté Client
 public Socket(InetAddress addr, int port, InetAddress localAddr, int localPort) throws
IOException
La classe Socket (2/3)

 Les getters
– public InetAddress getInetAddress()
 L’adresse IP distante
– public InetAddress getLocalAddress()
 L’adresse IP locale
– public int getPort()
 Le port distant
– public int getLocalPort()
 Le port local
La classe Socket (3/3)

 Méthodes
– public OutputStream getOutputStream() throws IOException
 Ouvre un flux d’écriture sur la socket
 Permet de construire un objet PrintWriter
– public InputStream getInputStream() throws IOException
 Ouvre un flux de lecture sur la socket
 Permet de construire un objet BufferedReader
 L’opération de lecture est bloquante
– public void close()
 Ferme la socket et libère les ressources
Ecriture du code: côté serveur
 Créer une socket d’écoute
– ServerSocket SS= new ServerSocket(NumeroPort);
 Récupérer la socket d’échange
– Socket S=SS.accept();
 Ouvrir un flux de lecture sur la socket
– BufferedReader BR = new BufferedReader(new
InputStreamReader(S.getInputStream()));
 Ouvrir un flux d’écriture sur la socket
– PrintWriter PW = new PrintWriter(S.getOutputStream());
 Réaliser les traitements
 Communication à travers les flux de lecture et d’écriture
– BR.readLine()
– PW.println(message);
Ecriture du code: côté Client

 Créer la socket d’échange


–Socket S=new Socket(AdresseServeur,port);
 Ouvrir un flux de lecture sur la socket
– BufferedReader BR = new BufferedReader(new
InputStreamReader(S.getInputStream()));
 Ouvrir un flux d’écriture sur la socket
– PrintWriter PW = new PrintWriter( S.getOutputStream());
 Réaliser les traitements
 Communication à travers les flux de lecture et d’écriture
– BR.readLine()
– PW.println(message);
Remote Method Invocation
RMI
Remote Method Invocation

 RMI technologie pour la mise en œuvre d’objets


distribués
 Le but de RMI est de permettre l'appel, l'exécution et
le renvoi du résultat d'une méthode exécutée dans
une machine virtuelle différente de celle de l'objet
l'appelant
 S’appuie sur le stub pour implémenter la
communication distante
 Package: java.rmi
Les deux parties
 Une application RMI est constituée généralement de deux
programmes:
– Partie Serveur:
 Crée des objets distants
 Crée des références sur ces objets pour les rendre accessibles
 Attends les requêtes des clients: appels distants sur les méthodes de ces
objets
– Partie Client:
 Obtient une ou plusieurs références sur des objets distants localisés sur
un ou plusieurs serveurs
 Effectue des appels distants sur les méthodes des objets

70
Interfaces, objets et méthodes
distantes

 Comme n’importe quelle application Java, une application distribuée


RMI est constituée d’interfaces et de classes
– Les interfaces déclarent des méthodes
– Les classes implémentent ces méthodes et d’autres méthodes
additionnelles
 Les objets possédant des méthodes pouvant être appelées à travers
plusieurs JVMs sont appelés objets distants.
– Ils implémentent une interface distante (remote interface) possédant les
caractéristiques suivantes:
 Hérite de java.rmi.Remote
 Chaque méthode de l’interface peut lever l’exception:
java.rmi.RemoteException

71
Fonctionnement de l’invocation
distante dans RMI
 RMI traite un objet distant de manière différente par rapport à
un objet local
– RMI utilise un stub (côté client) pour chaque objet distant:
 Le stub joue le rôle d’un représentant local (ou proxy) pour l’objet distant
 Le client invoque la méthode sur le stub local
 Le stub transporte l’appel de méthode vers l’objet distant
 Le stub d’un objet distant implémente la même interface
distante que l’objet distant
– Permet d’intercepter tous les appels sur ces méthodes
– Seules les méthodes déclarées dans l’interface peuvent être invoquées
à distance

72
Etapes de création des
applications RMI

 Le développement d’une application RMI


correspond à 4 étapes
– Design et implémentation des composants de
l’application distribuées
– Compilation des sources
– Connexion des classes sur le réseau
– Démarrage de l’application

73
Design et implémentation
 Définir l’architecture de l’application
– Quels objets sont locaux et lesquels sont distants
– Définir les interfaces distantes pour les objets distants
 Spécifier les méthodes invocables à distance par les clients (types des paramètres et
type de retour)
 Implémentation des objets distants:
– Les objets distants
 Doivent implémenter une ou plusieurs interfaces distantes
 Peuvent implémenter d’autres interfaces et méthodes qui ne peuvent être appelées que
localement
 Implémentation des clients:
– Les clients qui utilisent les objets distants peuvent être implémentés à n’importe
quel moment après la définition des interfaces

74
Compilation des sources

 Génération des codes exécutables:


– Compiler les codes sources (serveurs , clients,
classes d’implémentation…)
– => javac
 Génération du stub
– Compiler l’interface
– => rmic

75
Rendre les objets accessibles

 Enregistrement sur le registre rmi

– Spécification d’une localisation

– Attribution d’un nom

– Méthode bind (rebind) de la classe


java.rmi.Naming

76
Lancement de l’application

 Exécution:

– Du registre d’objets RMI

– Du Serveur

– Du client

77
Récapitulons…
 Côté serveur:
– Définition de l’interface d’accès distant
– Implémentation de la classe de ou des objets distants
– Implémentation du serveur qui crée l’objet distant et l’enregistre
sur le registre de nommage RMI (RMI registry)
 Côté client: implémentation comprenant
– L’obtention d’une référence sur l’objet distant à travers le registre
de nommage RMI
– La réalisation des appels de méthodes distantes en utilisant
cette référence
DEMO
Un exemple simple:
L’objet Hello

 L’application est constituée des classes


– Hello: implémente l’objet
– HelloInt: l’interface de l’objet distant
– Serveur: la partie serveur de l’application
– Client: la partie client de l’application
L’interface

 Doit hériter de l’interface java.rmi.Remote


 Publie les méthodes accessibles par appels
distants
 Dans un fichier HelloInt.java:
package hello;
import java.rmi.*;
public interface HelloInt extends Remote
{
public void SayIt() throws RemoteException;
}
L’implémentation

 Implémente le code de l’objet distant


 Implémente toutes les méthodes déclarées
dans l’interface
 Hérite de la classe UnicastRemoteObject
 Toutes les méthodes y compris le constructeur
lèvent l’exception RemoteException
La classe Hello.java

package hello;
import java.rmi.*;
import java.rmi.server.*;
public class Hello extends UnicastRemoteObject implements HelloInt {
public Hello() throws RemoteException {
super();
}
public void SayIt()throws RemoteException {
System.out.println("bonjour");
}
}
Le serveur

 Crée l’objet distant


 L’enregistre sur le serveur de nommage RMI
 Dans un fichier Serveur.java
import java.rmi.*;
import java.rmi.registry.*;
import hello.*;
public class Serveur{
public static void main(String[] args) throws Exception {
// création de l’objet
Hello h = new Hello();
Le serveur

 L’enregistrement d’un objet se fait à travers la méthode


bind
 Prend en paramètre:
– L’objet
– Sa localisation: port et nom attribué
 Introduire le reste du code du serveur:
System.out.println("Je vais enregistrer mon objet");
Naming.bind("rmi://localhost:1099/hello",h);
System.out.println("C est fait!");
}}
Le client

 La première étape est d’obtenir une référence


sur l’objet distant:
– Utiliser la méthode statique lookup de la classe
naming
– Retourne le stub en faisant une recherche sur le
nom de l’objet référencé dans le registre de
nommage
– Retourne l’exception NotBoundException si la
recherche échoue
Le code du client
import hello.*;
import java.rmi.*;
public class Client{
public static void main(String[] args)
{
try {
Remote remote_h = Naming.lookup("rmi://localhost:1099/hello");
if (remote_h instanceof HelloInt)
{
((HelloInt) remote_h).SayIt();
}
}
catch (Exception e) {
}
}}
Structuration de l’application
 Côté Serveur:
– Code de l’interface, de la classe d’implémentation
– Code du serveur
 Compilation + génération du stub
– javac *.java
– rmic hello.Hello
 Côté Client
– Code de l’interface, du stub
– Code du client
 Compilation du code du client
Exécution (arrêt)

 Dans le répertoire MON_PREMIER_RMI


– Lancement du registre de nommage
 java sun.rmi.registry.RegistryImpl 1099
– Lancement du serveur
 java Serveur
 Lancement du client
– java Client
La communication

 Implantation de la communication entre les


composants:
– Client  Servant
 e.g. Transférer un identifiant du client vers le Servant
– Servant  Client
 e.g. renvoyer le nbre des invocations
– Serveur  Servant
 e.g. communiquer un identifiant du Serveur
– Serveur  Client
 e.g. renvoyer l’identifiant du serveur vers le client

90
Des architectures plus complexes

Client C1
Serveur S
Client C2

Serveur S1
Client C
Serveur S2

Client C Serveur S1 Serveur S2

91
Le middleware ORB et La norme
CORBA

92
Points Abordés

 Le middleware
 Concepts généraux de CORBA
 L’application Hello
 Le langage IDL
 Mapping IDL et Java
 Création et connexion des objets au BUS
 Localisation des objets en CORBA
 Étapes de développement

93
Le middleware

Motivation et objectifs

94
Le middleware

 Lié à l’architecture 3-tier


 Le terme middleware est une combinaison
de middle (du milieu) et software (logiciel)
 En français, plusieurs terminologies
– intergiciel
– logiciel d’intermédiation
– par abus de langage: Bus logiciel

95
Motivations

 Comment rendre l'écriture d'applications


distribuées "aussi simple" que celle des
applications centralisées ?

 Quel cadre fournir pour permettre


l'intégration aussi bien de nouveaux services
que d'applications existantes ?

96
Objectifs

 Développer une architecture unifiée orientée-


composants pour l'intégration d'applications
réparties.
 Afin d'offrir un environnement logiciel pour
supporter :
– La réutilisabilité et la portabilité des composants
logiciels.
– L'hétérogénéité et l'interopérabilité entre les différents
 langages
 environnements informatiques (machines,OS).

97
Difficultés
 Hétérogénéité multi-formes
– des matériels
– des systèmes
– des langages
 Accès aux ressources (comment les trouver?)
 Les problèmes «classiques»:
– transaction,
– concurrence, ...
 Beaucoup d'approches "Orientées Objets" incompatibles (BDs,
langages ...)

98
Fonctions du middleware
 Le middleware a quatre fonctions principales
– Fournir une interface ou API (Application Programming
Interface) de haut niveau aux applications
– Masquer l’hétérogénéité des systèmes matériels et logiciels
sous-jacents
– Rendre la répartition aussi invisible (“transparente”) que
possible
– Fournir des services répartis d’usage courant
 Exemples de middleware Objet
– CORBA
– J2EE/EJB
– .NET

99
L'Object Management Group (OMG)

 Norme CORBA ( Common Object Request


Broker Architecture ) créée par l’OMG en 1992
 Consortium fondé en 1989 (Sun, H.P., ...), basé
aux Etats-Unis : plus de 700 membres:
– Constructeurs (Sun, HP, IBM ...)
– Environnements systèmes (Microsoft, Novell ...)
– Outils et langages (Iona, Object Design, Borland ...)
– Produits et BD (Lotus, Oracle, Informix, O2 ...)
– Industriels (Boeing, Alcatel, Thomson ...)

10
Concepts généraux de CORBA

10
Le standard CORBA : fonctionnalités
(1)

 Transparence à la localisation (locale ou distante) et


à l'invocation :
– Contrôle d’invocation à la compilation (statique).
– Contrôle d’invocation à l'exécution (dynamique).

 Liaison avec "tous" les langages de programmation :


– Un langage de description d'interfaces (IDL) fortement
typé.
– Des "projections" de l'IDL vers les langages
d'implantation /programmation (C/C++/java ...).

10
Le standard CORBA : fonctionnalités
(2)

 Activation automatique et transparente des


objets :
– les objets sont en mémoire uniquement s'ils sont
utilisés.
 Environnements hétérogènes (langages,
OS,machines ...).
 Protocole générique d'interopérabilité entre
ORBs différents :
– IIOP est une instanciation de GIOP sur Internet
(TCP/IP).

10
Fonctionnement

 Parallèle avec le fonctionnement du téléphone


– L’ORB ≡ le réseau téléphonique
 Les "Objects Services" sont ≡
– Appareil téléphonique
– Annuaires
– modems, fax
 Applications : utilisation du réseau ≡
– Appeler quelqu’un
– Accès Internet

10
Invocation d’une méthode à distance
 1: Invocation d’une méthode §§§§§§ 2: Emballage des arguments
 3: transport de l’invocation §§§§§§ 4: déballage des arguments
 5: Invocation de l’objet réel §§§§§§ 6: Retour de l’invocation locale
 7: Emballage du résultat §§§§§§ 8: Transport du résultat
 9: Déballage du résultat §§§§§§ 10: Retour de l’invocation distante

(1) (2) (4) (5)


Implantation
Client
Objet
(10) (9) (7) (6)

(3)
Skeleton
Stub client Stub serveur
(8)
Souche client
10 Réseau
Souche
serveur
Nomenclature CORBA:
Le minimum à connaître

 Stub & Skeleton: souches client et serveur


 BOA (Basic Object Adapter).
– Identifie le servant
– Passe la requête au skeleton associé
 ORB (Object Request Broker)
– Transporte les requêtes vers le BOA
 Serveur: processus qui
– Initialise l’ORB et le BOA
– Crée le servant par instanciation de l’implémentation de l’objet
 Client: processus qui utilise le servant
 IOR (Interoperable Object Reference)
10 – Identifie un objet unique sur le bus
Architecture CORBA

SERVEUR
CLIENT

Servant
Serveur
Client IDL Basic
IDL Skeleton Object
Stubs Adapter

Object Request Broker


10
IOR: références des objets CORBA

 Un IOR identifie un objet unique sur le bus par un code


basé sur 3 informations principales:
– Nom de la machine hôte (Hostname): La machine sur laquelle
s’exécute le serveur. Il est choisi par le BOA. Il coïncide avec le
nom associé à l’adresse IP
– Le numéro de port (port number): un numéro attribué par le BOA,
à chaque exécution du serveur. Il coïncide avec le numéro de port
TCP
– La clé de l’objet (Object Key): pour chaque objet créé par le
serveur, le BOA lui attribue une clé unique
 À chaque relance du serveur, les références des IOR
10 publiées peuvent devenir invalides
Fonctionnalités des composants

Serveur
Client

Static
Static Static
Dynamic Static
Invocation Static
Static Dynamic
Invocation ORB Skeleton Basic
Interface Invocation Invocation
Interface Skeleton
Skeleton Skeleton
Interface Interface Interface Object Implementati
Repository Interface Interface Interface
Interface interface
Adapter on
Repository

ORB
10
Fonctionnalités des composants
Côté client (1/2)

 SII: Code Java (ou C++) du stub. Généré par le compilateur IDL
 IR: Interface Repository: Objet CORBA dont l’interface permet
d’obtenir des informations sur les IDL des objets du bus

Client

Static
Static Static
Dynamic Static
Invocation Static
Static Dynamic
Invocation ORB Skeleton Basic
Interface Invocation Invocation
Interface Skeleton
Skeleton Skeleton
Interface Interface Interface Object Implementati
Repository Interface Interface Interface
Interface interface
Adapter on
Repository
11
Fonctionnalités des composants
Côté client (2/2)

 DII: permet aux clients d’invoquer des opérations dont ils


construisent la requête dynamiquement en obtenant des
informations depuis le référentiel d’interface (IR).
– Aussi générée par le compilateur IDL
– Interface générique mais plus complexe à utiliser qu’une SII.

Client

Static
Static Static
Dynamic Static
Invocation Static
Static Dynamic
Invocation ORB Skeleton Basic
Interface Invocation Invocation
Interface Skeleton
Skeleton Skeleton
Interface Interface Interface Object Implementati
Repository Interface Interface Interface
Interface interface
on
11 Adapter
Repository
Fonctionnalités des composants Côté
Serveur (1/2)

 BOA (Basic Object Adapter):


– API partiellement spécifiée par l’OMG
– Elle permet l’exécution des requêtes transmises par
l’ORB
 SSI: Code Java (ou C++…) du skeleton
– Généré par le compilateur IDL
Client

Dynamic
Static
Static Static
Static
Static Dynamic
Interface Static
Invocation ORB Basic
Invocation Invocation
Invocation Skeleton
Skeleton
Skeleton Skeleton Implementa
Repositor Interface
Interface Interface Object
Interface Interface Interface
Interface interface tion
11 y Interface Adapter
Repository
Fonctionnalités des composants
Côté Serveur (2/2)

 DSI:
– permet au serveur de traiter des requêtes d’opérations sans disposer à
l’avance des squelettes de déballage
– Sert à réaliser des interpréteurs CORBA et des passerelles entre ORBs
 Implementation Repository:
– Non spécifié par l’OMG
– Contient les informations stockées par le BOA concernant les objets
servants

Client

Dynamic
Static
Static Static
Static
Static Dynamic
Interface Static
Invocation ORB Basic
Invocation Invocation
Invocation Skeleton
Skeleton
Skeleton Skeleton Implementa
Repositor
11 y
Interface
Interface
Interface
Interface Interface Interface
Interface
Interface interface
Object
Adapter
tion
Repository
Fonctionnalités des composants
(côté client et serveur)

 Interface ORB: Une API qui fournit les primitives de base pour:
– initialiser et paramétrer l’environnement CORBA,
– associer objets et IOR
 object_to_string: fournit la représentation en string d’un objet
CORBA
– On l’utilise généralement du côté serveur pour publier une "stringified"
IOR
 string_to_object: associe un objet CORBA à un string
– Utilisée généralement côté client pour associer le stub de l’objet servant

11
Génération de code
IDL
e.g. client et serveur en Java
----------
----------
Description ----------
---------
des interfaces
(1)
Application Implémentation Code
Compilateur
cliente IDL->Java
des interfaces Serveur
Java Java Java
(4) ---------- (2) ---------- ---------- (3)
---------- SII SSI ---------- ----------
---------- (stub) (skeleton) ---------- ----------
--------- --------- ---------

Compilateur Compilateur
Java Java

11 CLIENT SERVEUR
Génération de code
e.g. client Java et serveur en C++
IDL
----------
Description ---------- (1)
des interfaces ----------
---------

Application Compilateur Compilateur Implémentation Code


IDL->Java IDL->C++ des interfaces
cliente Serveur
Java C++ C++
(4) ---------- (2) ---------- ---------- (3)
---------- SII SSI ---------- ----------
---------- (stub) (skeleton) ---------- ----------
--------- --------- ---------

Compilateur Compilateur
Java C++

11 CLIENT SERVEUR
Première application CORBA

L’application Hello

11
L’interface IDL

 Dans un fichier Hello.idl:


interface Hello
{
void hello( );
} ;

– Simple, non?

11
11
Hello.java

HelloHolder.java

HelloHelper.java mapping vers Java Hello.idl


Compilateur idl pour
Compilation de l’IDL

_HelloImplBase.java

HelloPOA.java

StubForHello.java

_HelloStub.java
Implémentation du servant en Java

 Fichier Hello_impl.java/ HelloImpl.java


package hello;
import org.omg.CORBA.*;
public class Hello_impl extends _HelloImplBase
{ public void hello ( )
{
System.out.println( "Hello World!" );
}}

package hello;
import org.omg.CORBA.*;
public class HelloImpl extends HelloPOA
{ public void hello ( )
{
System.out.println( "Hello World!" );
12 }}
Implémentation du serveur Hello
Création de l’ORB et du BOA

 Le même langage doit être utilisé pour implanter le


servant et le serveur !
 Dans un fichier Serveur.java:
package hello;
import org.omg.CORBA.*;
import java.io.*;
public class Serveur
{
public static void main (String args[ ])
{
try
{
// Créer ORB et BOA
org.omg.PortableServer.POA poa =
org.omg.PortableServer.POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
12 poa.the_POAManager().activate();
Implémentation du serveur
-Suite-

 Suite du même fichier : Seveur.java


// Créer l’implémentation de l’objet
HelloImpl p = new HelloImpl ( ) ;
// Calculer l’IOR stringifieg
org.omg.CORBA.Object o = poa.servant_to_reference(p);
System.out.println( orb.object_to_string( o ) );
orb.run();
}
catch (SystemException ex)
{
System.err.println(ex.getMessage( ) );
ex.printStackTrace ( );
System.exit (1);
} } }
12
Code Java du Client

 Dans un fichier Client.java:


package hello;
import org.omg.CORBA.*;
import java.io.*;
public class Client
{ try
{
// créer l’ORB
ORB orb = ORB.init(args, new java.util.Properties ( ) );
// récupérer l’IOR du servant
String ref= args[0];
// créer une référence sur l’objet CORBA associé à l’IOR
org.omg.CORBA.Object obj = orb.string_to_object(ref);
if (obj==null)
12 throw new Runtime Exception ( );
Code Java Client
-Suite-

// Lier le Stub Client à l'objet CORBA


Hello hello = HelloHelper.narrow(obj);
if(hello == null)
throw new RuntimeException( );
// maintenant, nous pouvons utiliser l’objet java Hello comme
// s'il était local

hello.hello ( );
}
catch(COMM_FAILURE ex)
{
System.err.println(ex.getMessage ( ) );
System.exit(1);
12 } } }
Le langage de description

Interface Definition
Language (IDL)

12
Caractéristiques du langage IDL
 IDL = Interface Definition Language
 Objectif: Définir les interfaces indépendamment des
applications
 IDL est un langage déclaratif: ressemble beaucoup à
la partie déclarative de C++
 IDL est indépendant de tout langage de
programmation
 L’OMG définit des correspondances entre l’IDL et de
nombreux langages de programmation
– C++, SmallTalk, Ada, Java
– Cobol, C…

12
Les concepts principaux

 L’interface
– Comme une classe C++ ou Java mais définit uniquement l’interface d’un objet sans
informations sur sa présentation en mémoire et sans informations sur l’implémentation de
ses méthodes
 Les opérations
– Comme une méthode
 Pas de surcharge d’opérations
 Le nom des paramètres sont à spécifier
– Le mode de passage doit être préciser
 in || out || inout
 Les attributs
– Comme un attribut d’une classe C++ ou Java
– Il peut être modifiable ou non (dans le dernier cas : readonly)

12
Structuration en IDL
Module
Déclarations: alias de type
types complexes
exceptions
Interface
Déclarations: alias de types
types complexes, exceptions
Déclarations: opérations,
attributs

Module
Déclarations: alias de type
types complexes
exceptions

Interface
Déclarations: alias de types
types complexes, exceptions

Déclarations: opérations,
attributs

12
Imbrication dans IDL
 Il n’est pas possible d’imbriquer les interfaces.
L’exemple suivant est incorrect
interface A {
interface B {
void operationB( );
};
void operationA( );
};

12
Imbrication en IDL

 Mais il est possible d’imbriquer les modules


module A {
interface C {
void operationC ( );
} ;
module B {
typedef short entier;
interface D {
void operationD ( );
} ;
} ;
} ;

13
Les valeurs IDL

Types CORBA

Objets Non-Objets

Références
d’objets
Simples Complexes

struct sequence union array

13short long unsigned


short
unsigned
long
float double char string octet enum any
La déclaration de types complexes en
IDL

 Les constantes
module valeursIDL {
const double PI = 3.14;
const short s= 1;
const long deux = 1+1;
};

13
La déclaration de types complexes
en IDL

 Les tableaux:
module valeursIDL {
typedef string tableau[20];
interface Nom {
attribute string nom;
void setNom(in tableau t, in long indice);
};
typedef Nom matrice[10] [10];
};

13
La déclaration de types complexes en
IDL

 Les énumérations
module valeursIDL
{
enum Marque {Renault, Peugeot, Citroen, Dacia};
enum Couleur { rouge, bleu, jaune, vert, noir, blanc };

};

13
La déclaration de types complexes
en IDL

 Les structures
module valeursIDL
{
struct voiture
{
Marque marque;
Couleur couleur;
string matricule;
};
};

13
Les exceptions CORBA
 Deux types d’exceptions
– Exceptions utilisateur
– Exceptions système: la norme en spécifie 25
 BAD_PARAM: mauvais paramètre d’une opération du bus
 COMM_FAILURE: échec dans la communication
 INV_OBJREF: Référence d’objet non valide
 NO_RESSOURCES: ressources insuffisantes pour le traitement de
l’opération
 NO_PERMISSION: droit insuffisants pour l’invocation de l’opération
 MARSHAL: erreur dans l’emballage/déballage d’un paramètre ou d’un
résultat
 INTERNAL: erreur interne du bus
 BAD_OPERATION: opération inconnue ou non valide
 OBJ_NOT_EXIST: objet détruit

13
Exemple d’une description IDL

module Graphique
{
typedef unsigned short entier;
const entier uneconstante=1;
enum Couleur {rouge, bleu, jaune, vert, noir, blanc };

struct Dimensions {
entier largeur;
entier longueur;
} ;
typedef string ligne;
typedef sequence<ligne> Texte;

13
Exemple d’une description IDL
interface fenetre{
readonly attribute Dimensions dimension,
attribute Couleur fond;
void ecrire (in Texte texte);
Texte lire ( );
void ligneContenant(inout Texte unMotif);
};
interface boutton{
attribute Couleur fond;
attribute Texte text;
};
};
13  L’utilisation de typedef est obligatoire pour les tableaux et les
séquences en paramètre d’une opération
Mapping

Correspondance IDL
avec Java

13
Image d’un module IDL en Java

 Un module IDL est associé à un module de Java


ayant le même nom
 Toutes les déclarations de types IDL sont
associées aux déclarations correspondantes de
classe ou d’interface dans le module produit
 Toutes les déclaration IDL non encapsulées dans
aucun module sont associées à un package
Java par défaut.
14
Image d’une interface

 Une interface IDL est associée à:


– Une interface publique Java avec le même nom
– Une classe supplémentaire de Java avec le suffixe
"Helper" ajouté au nom de l’interface
 Fournit une méthode statique "narrow" qui permet à
org.omg.CORBA d’être transformé vers une référence d’objet
d’un type plus spécifique
 L’exception BAD_PARAM est levée si la transformation échoue
– Une classe de support "Holder". Son nom est le nom de
la classe Java suivi de ce suffixe

14
Exemple

 Fichier IDL :

module Graphique {
interface boutton {
attribute Couleur fond;
attribute Texte text;
};
};

14
Exemple

 Interface Java générée: boutton (boutton.java)

package Graphique;
public interface boutton extends org.omg.CORBA.Object
{
// deux méthodes pour chaque attribut(une seule pour les readonly)
public Couleur fond( );
public void fond(Couleur value);
public String[ ] texte ( );
public void texte(String [ ] value);
}

14
Images des types simples et des
constantes

IDL Java C++


short short CORBA::Short
long int CORBA::Long
unsigned long int CORBA::Ulong
long long long CORBA::LongLong
unsigned long long CORBA::ULongLong
float float CORBA::Float
double double CORBA::Double
boolean boolean CORBA::Boolean
octet byte CORBA::Octet
char char CORBA::Char
string String CORBA::String

IDL Java C++

TRUE true CORBA::TRUE


14 FALSE false CORBA::FALSE
Images des types complexes:
règles générales (1/2)

 Les alias de types déclarés par "typedef type


alias" n’ont pas de correspondance en java
– Utiliser type directement
– Une classe aliasHelper est générée par le
compilateur IDL
 Les énumérations en Java sont traduites par
des classes qui portent le même nom
 Une structure IDL est associée en Java à une
classe
14
Images des types complexes:
règles générales (2/2)

 Les tableaux IDL ont pour image les tableaux Java à


dimension fixe
– L’exception CORBA::MARSHAL est levée en cas de
débordement lors de l’utilisation de tableau Java en
paramètres d’une invocation
 Une classe de support est générée et porte le nom: nom-
tableauHolder
 Les séquences bornées ou non sont associées en
Java à des tableaux
 Une classe support est générée et porte le nom: nom-
sequenceHolder

14
Exemple: structures (1/2)

 Fichier IDL

module valeursIDL
{ struct voiture
{
Marque marque;
Couleur couleur;
string matricule;
};
};

14
Exemple: structures (2/2)

 Trois classes sont générées : voiture,


voitureHolder, voitureHelper
package valeurIDL;
final public class voiture
{
public voiture( ) { } // un constructeur vide
public voiture (Marque marque, Couleur couleur,
String matricule) { }
// déclaration des attributs : champs de la structure
public Marque marque;
public Couleur couleur;
String matricule;
}
14
Exemple: les tableaux (1/2)

module valeursIDL {
typedef string tableau[20];
interface Nom {
attribute string Nom;
void setNom(in tableau t, in long indice);
};
typedef Nom matrice[10] [10];
};

14
Exemple: les tableaux (2/2)

• L’interface Nom.java obtenue


package valeurIDL;
public interface Nom extends org.omg.CORBA.Object
{
public String Nom[ ];
public void Nom(String nom);
// les déclarations: idl typedef string tableau[20]
// et void setNom(in tableau t, in long … sont associés à:
public void setNom(String[ ] t, int indice);
}

15
Les interfaces: opérations et attributs

 Les opérations d’une interface sont traduites par des méthodes


de la classe associée
 Les attributs readonly d’une interface sont associés à une
méthode, sans paramètres permettant d’y accéder en lecture
– La valeur de l’attribut est obtenue comme résultat de l’appel de la méthode
 Les autres attributs sont associés en plus à des méthodes
d’affectation
– La méthode a un paramètre de même type que l’attribut
 L’invocation d’une opération op(…) se fait en Java via l’appel de
méthode objetJava.op(…)

15
Le passage des paramètres en Java

 in correspond au passage par valeur


– Nom et type du paramètre IDL : Nom et type correspondant en Java
 out et inout correpondent au passage par référence
– Le mapping Java a prévu des classes conteneur appelés Holder
– À chaque type T est associée une classe THolder qui est utilisée
pour le passage en paramètre par référence
– Les classes Holder des types simples sont définies par défaut
– Pour les autres classes définies par le programmeur, c’est le
compilateur IDL qui se charge de la génération de code pour les
classes Holder

15
Exemple (1/2)

Module IDL:
module Exemple {
interface Modes{
long operation (in long inArg , out long outArg,
inout long inoutArg);
};
};

15
Exemple (2/2)

Le code Java générée


package Exemple;
public interface Modes{
int operation (int inArg, intHolder outArg,
intHolder inoutArg);
}

15
Exemple de l’image d’une interface
(1/2)

Fichier IDL:
typedef string ligne;
typedef sequence<ligne> Texte;

interface fenetre{
readonly attribute Dimensions dimension;
attribute Couleur fond;
void ecrire (in Texte text);
Texte lire ( );
void ligneContenant (inout Texte motif);
};

15
Exemple de l’image d’une interface
(2/2)

On obtient la classe fenetre.java :

public interface fenetre{


public Dimensions dimension( );
public Couleur fond( );
public void fond(Couleur value);
public void ecrire (String[ ] text);
public String[ ] lire( );
public void ligneContenant(StringHolder[ ] motif);
}

15
Les exceptions utilisateur

 Sont associés à des classes qui héritent


d’une classe de base des exceptions
– org.omg.CORBA.UserException
 Sont gérées naturellement comme les
exceptions Java

15
Exemple: les exceptions (1/2)

Fichier IDL:
module Hello {
exception ilDort {
string laRaison;
short depuis_quand;
};
};

15
Exemple: les exceptions (2/2)

Correspondance Java:
package Hello;
final public class ilDort extends org.omg.CORBA.UserException
{
public String laRaison;
public short depuis_quand;
public ilDort ( ) { };
public ilDort(String raison, short depuis)
{
laRaison =raison;
depuis_quand=depuis;
}
15 }
Création et connexion des objets
au bus

16
Implémentation par héritage (1/2)

interface A{
void operationA ( );
};
 La classe d’implémentation prend le suffixe Impl
– Elle hérite de la classe POA générée par le
compilateur IDL
– Elle implémente les opérations de l’interface

16
Implémentation par héritage (2/2)

 Code de la classe d’implémentation:

public class AImpl extends _APOA


{
void operationA ( )
{
code d’implémentation en Java
}
}

16
Création des objets CORBA

 Se fait directement par l’appel à new sur la


classe d’implémentation
 Plusieurs Servants peuvent être créés du
côté serveur et utilisés du côté client
A servant1 = new AImpl( );
// Code Java
A servant2 = new AImpl( );
// autre Code Java

16
Connexion directe des objets au bus
CORBA

 Connexion explicite d’un objet au BOA


// code Java
org.omg.CORBA.ORB orb = … // obtenir la ref de l’ORB
A servant =new A_impl( );
orb.connect(servant);
 Déconnexion d’un objet du BOA
// code Java
orb.disconnect(servant);
 Après cet appel, les requêtes à ce servant entraînent la levée
de l’exception OBJECT_NOT_EXIST

16
Connexion via une manufacture
d’objets

 Une manufacture est une interface qui permet


de créer des objets d’autre interface
– permet la création d’objets CORBA par simple appel
de méthodes au lieu de le coder en dure du côté
serveur
interface produit
{
// code idl de l’interface
void detruire( );
};
interface factory
{
produit CreerProduit( );
16 };
Implémentations correspondantes

 Implémentation de l’interface produit


public class produit_impl extends _produitImplBase
{
org.omg.CORBA.ORB orb_;
public produit_impl(org.omg.CORBA.ORB orb)
{ orb_ =orb; }
public void detruire( ) { orb_.disconnect(this); }
}

16
Implémentations correspondantes

 Implémentation de l’interface factory


public class factory_impl extends _factoryImplBase
{
org.omg.CORBA.ORB orb_;
public factory_impl (org.omg.CORBA.ORB orb) { orb_ = orb;}
public produit CreerProduit( ) {
produit objet =new produit_impl(orb_)
orb_.connect(objet);
return objet;
}
}

16
Localisation des Objets en corba

16
Fichiers partagés

Objet
CLIENT A

SERVEUR

2- récupérer une 1- enregistrer l’IOR


référence sur l’objet transformée en string
à partir de son IOR de l’objet A dans un
enregistrée sous fichier "ObjetA.ref"
ObjetA.ref
forme de string
16 dans le fichier
"ObjetA.ref"
Exemple
1- le code du serveur
org.omg.CORBA.ORB orb= ... //obtenir 1 référence sur l’ORB
ObjetA impl=new ObjetA_impl( );
String ref=orb.object_to_string(impl);
java.io.PrintWriter out = new java.io.PrintWriter( new
java.io.FileOutputStream("ObjetA.ref"));
out.println(ref);

2- le code du client
org.omg.CORBA.ORB orb=…//obtenir 1 référence sur l’ORB
java.io.BufferedReader in = new java.io.BufferedReader(new
java.io.FileReader("objetA.ref")
String ref=in.readLine( )
org.omg.CORBA.Objet obj=orb.string_to_object(ref);
17 ObjetA a=ObjetAHelper.narrow(obj);
Utilisation du Web

Objet
CLIENT A

SERVEUR
2- récupérer une référence
1- enregistrer l’IOR transformée en
sur l’objet à partir de son
string de l’objet A dans
IOR enregistrée sous forme
~guennoun/public_html/fichierA
de string dans
www.EHTP/~guennoun/
fichierA

ObjetA.ref

17 Serveur WEB
Exemple
1- le code du serveur
org.omg.CORBA.ORB orb= ... //obtenir 1 référence sur l’ORB
ObjetA impl=new ObjetA_impl( );
String ref=orb.objet_to_string(impl);
java.io.PrintWriter out = new java.io.PrintWriter(
new java.io.FileOutputStream(/home/…/"ObjetA.ref"));
out.println(ref);

2- le code du client
import java.net.*;
import java.io.*;
String location="http://www.ehtp.ma/~guennoun/ObjetA.ref"
org.omg.CORBA.ORB orb=…//obtenir 1 référence sur l’ORB
URL url=new URL(location);
URLConnection conn=url.openConnection( );
BufferedReader in = new BufferedReader(new
inputStreamReader(conn.getInputStream( ));
String ref=in.readLine( )
org.omg.CORBA.Objet obj=orb.string_to_object(ref);
17 ObjetA a=ObjetAHelper.narrow(obj);
Service de nommage

Objet
CLIENT A

SERVEUR

2- récupérer une 1- enregistrer objetA


référence sur l’objet sous le nom "A"
enregistré sous le Service de
nom "A" Nommage
17
Le service de nommage CORBA

Naming Service

17
Objectifs
 Maintient des associations de type nom/objet (name
binding)
 Une association est toujours définie relativement à un
contexte (naming context)
 Différents noms peuvent être associés au même objet,
sous le même ou sous différents contextes
 Associer (bind) un nom = créer une association de type
nom/objet dans un contexte donné
 Résoudre (resolve) un nom = déterminer l’objet associé
dans un contexte donné
 Un objet peut être un objet CORBA applicatif ou un
contexte de nommage qui est aussi un objet CORBA

17
Caractéristiques de la spécification
OMG

 Fédération de services
envisagée
 Porté de nommage
– Associer des contextes à des
noms sous d’autres contextes c2 o1
c1
conduit à un arbre de nommage
– Les cycles sont autorisés
 Opérations spécifiées c1.
o.V1 o.V2
1
– Association, dissociation,
recherche et énumération
17 – Le renommage n’est pas spécifié
Le module CosNaming (1/2)
 Spécifie les types pour construire les noms utilisés par
le service
– NameComponent comme une structure
– Name comme une séquence de NameComponent
 Spécifie l’interface NamingContext avec les
opérations suivantes
– Pour les objets applicatifs de type Object
 void bind/rebind (in Name n,in Object obj)
Association d’un nom et un objet obj
– Pour les objet contexte de type NamingContext
 void bind_context/rebind_context (in Name,in NamingContext nc)
17 Association d’un nom et d’un contexte
Le module CosNaming (2/2)
 Pour les deux types d’objets
– object resolve(in Name n)
Recherche d’objet par son nom
– void unbind(in Name n)
Libération d’un nom; i.e. le dissocier d’un objet
 Création d’un contexte
– NamingContext new_context( )
Crée un nouveau context sur le même serveur que le contexte
appelant
– NamingContext bind_new_context (in Name n)
Crée un nouveau contexte et l’associe au nom n
 Destruction d’un contexte
– void destroy( )
17
Les noms: définitions et exemples

typedef string Istring;


Struct NameComponent{ 0 1
Istring id;
Istring kind;};
typedef sequence <NameComponent> Name;
NameComponent[ ] LeNom=new NameComponent[ 2]; c2,cont o1,obj
LeNom[0]=new NameComponent( );
LeNom[0].id="c2" ; LeNom[0].kind="cont ";

LeNom[1]=new NameComponent( );
LeNom[1].id="o1" ; LeNom[0].kind="obj ";

17
Exemple d’utilisation côté serveur
//obtenir l’IOR du serveur de nom
java.io.BufferedReader in = new java.io.BufferedReader(new
java.io.FileReader("NamingService.ref")); Initial_context
String ior=in.readLine();
NamingContext context_initial= NamingContextHelper.narrow(orb.string_to_object(ior));
//création du context c2
NameComponent[ ] LeNom = new NameComponent[1];
LeNom[0]=new NameComponent( );
LeNom[0].id="c2" ; LeNom[0].kind="cont"; nc2
NamingContext nc2=context_initial.new_context( );
Context_initial.bind_context(LeNom,nc2);
//création d’un objet CORBA de type A
A objectA=new A_impl( ) ;
//création d’un binding o1/obj avec objetA
o1
NameComponent[ ] NomA=new NameComponent[1];
NomA[0]=new NameComponent( );
NomA[0].id="o1" ; NomA[0].kind="obj";
nc2.bind(NomA,objetA);
18
Exemple d’utilisation côté client

// obtenir l’IOR du serveur de nom et le lier au stub NamingContext


java.io.BufferedReader in = new java.io.BufferedReader(new
java.io.FileReader("NamingService.ref"));
String ior=in.readLine();
NamingContext context_initial=
NamingContextHelper.narrow(orb.string_to_object(ior));
//récupérer la référence de o1 et la lier à un stub de type A
NameComponent[ ] LeNom = new NameComponent[2];
LeNom[0]=new NameComponent( ); LeNom[0].id="nc2 " ;
LeNom[0].kind="cont ";
LeNom[1]=new NameComponent( ); LeNom[1].id="o1" ;
LeNom[1].kind="obj";
org.omg.CORBA.Object obj=context_initial.resolve(LeNom);
A stubObjetA= Ahelper.narrow(obj);
18
Exemple d’utilisation côté client
Code équivalent

// obtenir l’IOR du serveur de nom et le lier au stub NamingContext


java.io.BufferedReader in =
new java.io.BufferedReader(new java.io.FileReader("NamingService.ref"));
String ior=in.readLine();
NamingContext context_initial=
NamingContextHelper.narrow(orb.string_to_object(ior));
//récupérer une référence sur le naming context nc2
NameComponent[ ] NomNC2 = new NameComponent[1];
NomNC2[0]=new NameComponent( );
NomNC2[0].id="nc2 " ;
NomNC2[0].kind="cont ";
org.omg.CORBA.Object obj1=context_initial.resolve(NomNC2);
NamingContext nc2= NamingContextHelper.narrow(obj1);
//récupérer une référence sur l’objet A
NameComponent[ ] LeNom = new NameComponent[1];
LeNom[0]=new NameComponent( ); LeNom[0].id="o1 " ; LeNom[0].kind="obj ";
org.omg.CORBA.Object obj2=nc2.resolve(LeNom);
A stubObjetA= Ahelper.narrow(obj);
18
Règles d’équivalence

Ctx ->bind(<c1;c2;…;cn>,obj) ≡
Ctx ->resolve(<c1;c2;…;cn-1>)->bind(<cn>,obj)
 Ctx ->bind_context(<c1;c2;…;cn>,nc) ≡
Ctx ->resolve(<c1;c2;…;cn-1>)->bind_context(<cn>,nc)
 Ctx ->resolve(<c1;c2;…;cn> ≡
Ctx ->resolve(<c1;c2;…;cn-1>)->resolve(<cn>)
 Ctx ->unbind(<c1;c2;…;cn>) ≡
Ctx ->resolve(<c1;c2;…;cn-1>)->unbind(<cn>)
 Ctx ->bind_new_context(<c1;c2;…;cn>) ≡
18 Ctx ->resolve(<c1;c2;…;cn-1>)->bind_new_context(<cn>
Enumération des associations (1/2)

 Opération list de l’interface NamingContext


– void list (in unsigned long nb,
out BindingList bl,
out BindingIterator bi);
 bl : liste des nb premières associations
 bi : itérateur sur les associations restantes

18
Enumération des associations (2/2)

 Définitions de types
– enum BindingType (nobject,ncontext)
– struct Binding{
Name binding_name;
BindingType binding_type}
– typedef sequence<Binding> BindingList;
 interface BindingIterator
– interface BindingIterator{
boolean next_one(out Binding b);
boolean next_n(in unsigned long nb, out BindingList bl);
void destroy( );
};
18
Etapes de développement

18
Etapes d’implémentation

 Définition de l’IDL
– interface A {string hello( );}
 Compilation de l’IDL: génère 5 classes/interfaces
java:
– 2 utilisée par le broker
 A.java, StubForA.java
– 3 utilisée par le programmeur
 AHolder.java, AHelper.java, _AImplBase.java
 Implémentation de l’interface A:
import org.omg.CORBA.*;
public class A_impl extends _AImplBase {
18 public String hello ( ){ //code }
Création du client et du serveur

Côté serveur Côté client


 1- initialisation de l’ORB
 1- initialisation de l’ORB – ORB orb=ORB.init(---)
– ORB orb=ORB.init(---)
 2- initialisation du BOA  2- obtenir la référence de
– BOA boa= l’objet
– orb.BOA_init(---) – String ref= args[0];
 3- Création d’un objet CORBA  3- Créer une référence sur
– A_impl o = new A_impl( ); l’objet CORBA associé
 4- Publication de sa référence – org.omg.CORBA.Object o =
– String ref= object_to_string(o); orb.string_to_object(ref);
– System.out.println(ref);
 4- Lier le stub client à cet objet
 5- Connecter l’objet au bus
– orb.connect(o);
– A a =Ahelper.narrow(o);
 6- démarrage du service  Utilisation
188 – Boa.impl_is_ready(---) – System.out.println(a.hello());
Des questions ?

189

Vous aimerez peut-être aussi