Java Remote Method Invocation
Download
Report
Transcript Java Remote Method Invocation
Invocation de Méthode à des
Objets distants
Exemple : CORBA
Common Object Request Broker Architecture
Mise en pratique avec Orbacus en JAVA
1.1-histoire
Consensus pour l’interopérabilité
Le problème : Intégration des applications
Pas de consensus sur les langages de programmation
Pas de consensus sur les plate-formes de développement
Pas de consensus sur les systèmes d’exploitation
Pas de consensus sur les protocoles réseau
Pas de consensus sur les formats des données
manipulées par les applications
Recherche d’un Consensus pour l’interopérabilité
1.2 CORBA?
CORBA
Common Object Request Broker Architecture : CORBA
Plate-forme client/serveur orientée objets
Un standard pour l’interopérabilité entre objets
– Support pour différents langages
– Support pour différentes plate-formes (interopérabilité)
– Communications au travers du réseau
– Des services (Distributed transactions, events, ... )
– Guides et modèles de programmation
3
I.3. OMG
Object Management Group
(OMG)
http://www.omg.org
consortium international créé en 1989
but non lucratif
regroupement de plus de 460 organismes
• constructeurs (SUN, HP, DEC, IBM, ...)
• environnements systèmes (Microsoft, OSF, Novell, ...)
• outils et langages (Iona, Object Design, Borland, ...)
• produits et BD (Lotus, Oracle, Informix, O2, ...)
• industriels (Boeing, Alcatel, Thomson, ...)
• institutions et universités (INRIA, NASA, LIFL, W3C)
OMG en résumé
OMA : pour l ’architecture logicielle
MDA (Model Driven Architecture)
CORBA : pour le « middleware » technique
UML pour la modélisation
UML = Unified Modeling language
MOF pour la méta-modélisation
MOF = Meta-Object Facility
6
Processus de développement
Le langage IDL: Un « esperanto »
pour les objets
contrat
Client
d ’objets
Stub
IDL
IDL
Bus CORBA
Objets Corba
Fournisseur
d ’objets
Squelette
IDL
Spécification interface IDL (1/2)
Un objet grid est un tableau contenant des valeurs.
Les valeurs sont accessibles grâce aux opérateurs get et set
qui peuvent être invoqués à distance.
objets grid
Appel de get et set sur
l'objet grid distant
Processus client
Processus serveur
9
Spécification interface IDL (2/2)
interface Grid {
readonly attribute short height;
readonly attribute short width;
void set (in short n, in short m, in long value);
long get(in short n, in short m);
void copyIn(inout Grid g);
};
10
Le langage IDL: Interface
Definition Language
langage de spécification d’interfaces, supportant l’héritage
multiple;
indépendant de tout langage de programmation ou
compilateur (langage pivot entre applications);
langage utilisé pour générer les stubs, les squelettes et pour définir
les interfaces du Référentiel d’interface;
la correspondance IDL-langage de programmation est fournie
pour les langages C, C++, Java, Smalltalk, Ada, Cobol.
Exemple
interface
attribut
opérations
exception
opérations
interface account {
readonly attribute float balance;
attribute string description;
void credit (in float f);
void debit (in float f);
};
interface currentAccount : account {
readonly attribute float overdraftLimit;
};
interface bank {
exception reject {string reason;};
account newAccount (in string name)
raises (reject);
currentAccount newCurrentAccount (in string name, in float limit)
raises (reject);
void deleteAccount (in account a); };
Eléments IDL
Une spécification IDL définit un ou plusieurs types, constantes,
exceptions, interfaces, modules,...
• pragma
• constantes
• types de base au format binaire normalisé
• nouveaux types
(typedef, enum, struct, union, array, sequence)
• exceptions
• types de méta-données (TypeCode, any)
Eléments IDL
Un module permet de limiter la validité des identificateurs
Interface : ensemble d’opérations et de types =>classe C++
Syntaxe :
Interface | [<héritage>] { <interface Body>};
• opération (synchrone ou asynchrone sans résultat)
• attribut (possibilité de lecture seule)
Surcharge Interdite
Réutilisation de spécifications existantes (#include)
Exemple
module
module unService {
définitions
de type
typedef unsigned long EntierPositif;
typedef sequence<Positif> desEntiersPositifs;
interface
interface Premier {
opérations
boolean est_premier ( in EntierPositif nombre);
desEntiersPositifs nombres_premiers (in EntierPositif nombre);
};
};
module monApplication {
interface MonService {
unService::EntierPositif prochainPremier(..);
3. IDL
Description
Exemple
// Regroupe les définitions communes à ce service.
module date {
//
Une année
est codée par
exception
ErreurInterne
{}; un entier 16 bits.
typedef
short
Annee;
exception
MauvaiseDate
{ DateMultiFormat date; };
// Ensemble non borné d'années.
typedef
sequence<Annee>
// Service
de traitementDesAnnees;
sur les dates.
interface Traitement {
enum
Mois {
// Enumération des mois.
boolean verifierDate (in Date d);
Janvier,
Fevrier,
Mars,
Avril,
Mai, Juin,Juillet,
JourDansLaSemaine calculerJourDansLaSemaine
(
Aout, in
Septembre,
Octobre, Novembre, Decembre
Date d) raises(ErreurInterne,MauvaiseDate);
}; long nbJoursEntreDeuxDates (in Date d1, in Date d2)
// Ensemble non borné de
mois.
raises(MauvaiseDate);
typedef
sequence<Mois>
DesMois;
void dateSuivante
(inout
Date d,
in Jour nombreJours)
// Enumérationraises(MauvaiseDate);
des jours de la semaine.
enum
JourDansLaSemaine
{
};
Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi,
//
Service};
de conversion de dates.
Dimanche
interface Convertisseur {
// Jour
Un jour
est un entier 16 bits non signé.
convertirDateVersJourDansAnnee
(in Date d)
typedef unsigned short Jour;
raises(MauvaiseDate);
Date convertirChaineVersDate (in string chaine)
struct Date { // Structure
pour la notion de date.
raises(MauvaiseDate);
Jour
le_jour;
string
convertirDateVersChaine (in Date d)
Mois le_mois;
raises(MauvaiseDate);
Annee l_annee;
}; // L’année courante pour l’opération suivante.
Annee
annee_courante;
// attribute
Ensemble non
borné
de dates.
Date convertirJourDansAnneeVersDate
(in Jour jour);
typedef
sequence<Date> DesDates;
L’année de de
référence
opérations
suivantes.
// //
Regroupement
divers des
formats
de dates.
readonly
attribute Annee base_annee ;
union
DateMultiFormat
convertirJourVersDate
(in àJour
jour);
// Date
Le discriminant
anonyme sert
choisir
le format.
Jour convertirDateVersJour
(in Date d)
switch(unsigned
short) {
raises(MauvaiseDate);
case 0: string chaine;
case 1: Jour nombreDeJours;
void obtenirDate(in
default:
Date date; DateMultiFormat d1,out Date d2)
raises(MauvaiseDate);
};
};
// Héritage de spécification.
interface ServiceDate : Traitement,Convertisseur {};
};
// Regroupe les définitions communes à ce service.
module date {
// Une année est codée par un entier 16 bits.
typedef short Annee;
// Ensemble non borné d'années.
typedef sequence<Annee> DesAnnees;
// Enumération des mois.
enum Mois {
Janvier, Fevrier, Mars, Avril, Mai, Juin,Juillet,
Aout, Septembre, Octobre, Novembre, Decembre
};
// Ensemble non borné de mois.
typedef sequence<Mois> DesMois;
// Enumération des jours de la semaine.
enum JourDansLaSemaine {
Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi,
Dimanche };
// Un jour est un entier 16 bits non signé.
typedef unsigned short Jour;
struct Date { // Structure pour la notion de date.
Jour le_jour;
Mois le_mois;
Annee l_annee;
};
// Ensemble non borné de dates.
typedef sequence<Date> DesDates;
// Regroupement de divers formats de dates.
union DateMultiFormat
// Le discriminant anonyme sert à choisir le format.
switch(unsigned short) {
case 0: string chaine;
case 1: Jour nombreDeJours;
default: Date date;
};
Attribut IDL
Définition d’attribut
interface account {
readonly attribute float balance;
attribute string description;
...
};
Equivaut à :
float get_balance();
string get_description();
void set_description(in string s);
3. IDL
Description
Operations (1/2)
Paramètres nommés
et associés à un mode
void op1 (in long input,
out long output,
inout long both);
Opérations bloquantes
par défaut
interface account;
Client
uneBanque
newAccount
retours
interface bank {
account newAccount (in string name);
calcul
void deleteAccount (in account old);
};
<uneOpération> ::= <modeInvocation> <typeRetour> <identificateur>
‘ (‘ <paramètres> ‘ ) ’ <clausesExceptions><clausesContextes>
Pourquoi différents modes de
passage de paramètres ?
in : Données fournies par le client
out : Données retournées par l ’objet
inout : Données clientes modifiées par l ’objet
Répartition
Passage par copie
20
3. IDL
Description
Opérations (2/2)
oneway void notify (in string message);
Opération non bloquante
Pas de paramètre de type out, inout ou d’exceptions
Valeur de retour : void
Client
uneBanque
notify(«ok »)
Pas d ’exceptions déclenchées.
méthode
finie
3. IDL
Description
Exceptions
exception reject {string reason;};
account newAccount (in string name)
raises (reject);
exception DateErronnee {
String raison; };
CORBA::Exception
CORBA::UserException
CORBA::SystemException
Des exceptions CORBA standardisées
UNKNOWN
BAD_PARAM
COM_FAILURE
INV_OBJREF
NO_PERMISSION
NO_IMPLEMENT
OBJECT_NOT_EXIST
……….
Gestion explicite de la part du client
22
3. IDL
Description
Définitions circulaires
module Circulaire {
interface B;
interface A {
void utiliséB(in B unB);
}
interface B {
void utiliséA(in A unA);
}
3. IDL
Description
Héritage multiple
interface A { ... }
interface B : A { ... }
interface C : A { ... }
interface D : B, C { ...}
A
B
C
D
3. IDL
Description
Types de base et autres types
Types de base
• short
• long
• unsigned short
• unsigned long
• float
• double
• char
• boolean
• octet
MétaTypes
•…...
•any
•TypeCode
Types construits
• struct
• union
• enum
Types génériques
• array
• sequence
• string
Types de données dynamiques et
auto-descriptifs
3. IDL
Description
Type Any
interface PileDeChaines {
readonly attribut string sommet;
void poser(in string valeur);
string retirer();
};
interface PileGénérique {
readonly attribut Any sommet;
readonly attribut TypeCode typeDesValeurs;
void poser(in Any valeur);
Any retirer();
};
26
1- Exemple introductif
Exemple Compilation interface IDL
vers Java
Grid.idl
jidl … Grid.idl
A écrire
Compilateur IDL/Java
Généré
Client
_GridStub.java
Répertoire grid
Répertoire grid
Répertoire grid
Répertoire grid
GridOperations.java
I
Grid.java
Client.java
GridHelper.java
Serveur
GridPOA.java
Grid_Impl.java
Serveur.java
GridHolder.java
27
1- Exemple introductif
Les classes Stubs et Squelettes
• implantation du stub
public class _GridStub ……. Grid
– envoie de requêtes
– invisible par le programmeur
– instanciée automatiquement par GridHelper (narrow)
– Utilise le DII pour assurer la portabilité du binaire
• implantation du squelette
public abstract class GridPOA ………. GridOperations
– reçoit et décode des requêtes
– doit être héritée par l’implantation
28
1- Exemple introductif
Implémentation du serveur (1)
1. Initialiser le bus CORBA
– obtenir l’objet ORB
2. Initialiser l’adaptateur d’objets
– obtenir le POA
3. Créer les implantations d’objets
4. Enregistrer les implantations par l’adaptateur
5. Diffuser leurs références
– afficher une chaîne codifiant l’IOR
6. Attendre des requêtes venant du bus
7. Destruction du Bus
29
1- Exemple introductif
Implémentation du client
1. Initialiser le bus (objet ORB)
2. Créer les souches des objets à utiliser
2.a. obtenir les références d’objet (IOR)
2.b. convertir vers les types nécessaires
– narrow contrôle le typage à travers le réseau
3. Réaliser les traitements
• Rem. : éviter l’opérateur bind (2.a + 2.b)
– spécifique à chaque produit donc non portable
30
Le cycle de vie des objets
• Problème
– actuellement, 1 grille = 1 serveur
– pas de création/destruction d’objets à distance
– seulement invocation d’opérations
• Solution
– notion de fabrique d’objets
– exprimée en OMG-IDL
• C’est un canevas de conception : Design pattern
– voir aussi le service LifeCycle
Autres usages de la fabrique :
- gestion de droits, load-balancing, polymophisme, …
31
L’implantation de la fabrique
creerGrille
Fabrique
Grille
Grille
Grille
Grille
32
L’implantation de la fabrique
Fabrique
Grille
Grille
Grille
Grille
detruireGrille
33
Interface IDL d ’une fabrique de
Grilles
module grilles {
. . .
interface Fabrique {
Grid newGrid(in short width,in short height);
}; };
34
Scénario d ’obtention de la
référence du service de nommage
ORB
Client ou Serveur
resolve_initial_references ("NameService");
CosNaming::
NamingContext
conversion
ajout,retrait,lecture,...
35
Enregistrer un objet
• Opération pour publier un Objet
– en général, opération réalisée par le serveur
• Scénario Type
1. Créer un objet
2. Construire un chemin d ’accès (Name)
3. Appeler l ’opération « bind » ou « rebind » avec le chemin et la
référence de l ’objet
void bind (in Name n, in Object obj)
raises (NotFound, CannotProceed, InvalidName, AlreadyBound);
37
Retrouver un objet
• Opération réalisée par un client ou un serveur
• Scénario type :
– construire un chemin d ’accès (Name)
– appeler l ’opération « resolve » avec le chemin
– convertir la référence obtenue dans le bon type
Object resolve (in Name n)
raises (NotFound, CannotProceed, InvalidName)
38
Une application d’administration
de la fabrique
• Création d’une nouvelle grille et mise à disposition par le
service Nommage
– 1. Initialiser le bus CORBA
–
–
–
–
2. Obtenir le service Nommage (NS)
3. Obtenir la fabrique depuis le NS
4. Créer un répertoire
5. Enregistrer le répertoire dans le NS
39
Annuaire : service de nommage
java.rmi.Naming
bind
rebind
unbind
lookup
Client
rmi
URL
java.rmi.naming
RMI Registry
RMI Remote Object
40
RMI URL
•
•
•
•
Même syntaxe que http mais préfixe rmi
rmi://mymachine.com/monObjet
Inconvénient : perte de la transparence
=> utilisation de JNDI (Java Naming
Directory Interface)
41
JNDI : Nommage et directory
• C:/monRépertoire/monFichier
Lien (bind)
Nom
Contexte
Attributs
Créé le 12 mars 2002
Taille : 12 M
42
Conventions de nommage
• LDAP (Light Directory Access Protocol) :
"cn=Todd Sundsted, o=ComFrame, c=US" nomme la
personne "cn=Todd Sundsted"
Note : c = country, o = organization
• DNS :
carabosse.essi.fr
• => Abstraction JNDI
43
Naming/Directory
• Un service de Naming permet de retrouver
des objets à partir d'un nom ("pages
blanches")
• Un service de Directory rajoute des
fonctionnalités permettant d'associer des
attributs aux points d'entrée, et de faire une
recherche sur ces attributs ("pages jaunes")
44
Usage
• Les services de nommage sont utilisés :
– Pour stocker des objets
– Pour offrir un point d'accès aux applications
réparties (RMI, Corba , EJB…)
Ils servent également de référentiel
d'entreprise pour accéder à des applications
(machine/port), des bases de données, et
même des informations de sécurité (gestion
des accès au sein d'une entreprise)
45
Service providers
46
L'interface Context
Contexte
• Le contexte permet une isolation des noms,
par exemple pour plusieurs applications =>
évite les collisions
• Structure hiérarchique comme un répertoire
48
Interface Context
• void bind(String stringName, Object object): Lie un
nom à un objet. Le nom ne doit pas déjà être lié à un
autre objet. Tous les contextes intermédiaires doivent
exister.
• void rebind(String stringName, Object object): Lie un
nom à un objet. Si le nom est déjà lié, la liaison
précédente est écrasée. Tous les contextes
intermédiaires doivent exister.
• Object lookup(String stringName): Renvoie l'objet
pointé par le nom
• void unbind(String stringName): Délie l'objet pointé
par le nom.
49
Mais aussi
• void rename(String stringOldName, String
stringNewName): Modifie le nom auquel l'objet est lié.
• NamingEnumeration listBindings(String
stringName): Envoie une énumération contenant les
noms liés au contexte passé en paramètre, ainsi que les
objets liés à ces noms et leur classe
• NamingEnumeration list(String stringName): Renvoie
une énumération contenant les noms liés au contexte,
ainsi que les noms de classes des objets liés à eux
50
Contextes
• Pas de contexte racine => InitialContext
• Possibilité de créer des sous-contextes
public Context createSubcontext(String name)
throws NamingException
51
Un exemple : d'abord les
packages
import
import
import
import
import
javax.naming.Context;
javax.naming.InitialContext;
javax.naming.Binding;
javax.naming.NamingEnumeration;
javax.naming.NamingException;
// Pour les paramètres d'initialisation
import java.util.Hashtable;
52
Création du contexte initial
L'information d'environnement spécifie le provider JNDI par le nom de la
factory.
Dans ce cas : répertoire sous forme URL file://...
Hashtable hashtableEnvironment = new
Hashtable();
hashtableEnvironment.put(
Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory"
);
hashtableEnvironment.put(
Context.PROVIDER_URL,
"file://tmp"
53
);
Lien avec la sécurité
private Context getInitialCtx()
{
// Set up our JNDI environment properties...
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, INITCTX);
env.put(Context.PROVIDER_URL, HOST);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, USER);
env.put(Context.SECURITY_CREDENTIALS, PASSWORD);
try
{ return new InitialDirContext(env); }
catch(NamingException e)
54
Enumération de tous les objets
NamingEnumeration namingEnumeration = context.listBindings("");
while (namingEnumeration.hasMore()) {
Binding binding = (Binding)namingEnumeration.next();
System.out.println(
binding.getName() + " " +
binding.getObject()
);
}
55
Recherche d'un objet particulier
Object object = context.lookup(unNom);
System.out.println(
unNom + " " +
object
);
56
Utilisation de l'objet
On reçoit un object, il faut par
conséquent faire un "cast" pour pouvoir
l'utiliser
(MyClass) object.myMethode(….)
57
Résumé
•
•
•
•
Comme dans RMI
InitialContext
bind, lookup
On peut lister un contexte, créer un souscontexte
• Utilisation d'une factory pour lier à une
implémentation et initialiser les paramètres
• La sécurité est définie au niveau de
58
Directory Service
Directory Service
• Naming + attributs
60
Les fonctions de base
void bind(
String stringName,
Object object,
Attributes attributes
)
• Même méthode que Context, mais avec un
paramètre de plus : les attributs.
• Idem rebind, lookup
• Idem createSubcontext
• Créé à partir de InitialDirContext
61
GetAttributes
• 2 formes possibles
Attributes
getAttributes(
String stringName
)
Attributes
getAttributes(
String stringName,
String [] rgstringAttributeNames
)
62
modifyAttributes
void
modifyAttributes(
String stringName,
int nOperation,
Attributes attributes
)
• Avec les opérations :
•
ADD_ATTRIBUTE, REPLACE_ATTRIBUTE, et
REMOVE_ATTRIBUTE
63
Search
• La forme la plus simple passe une liste
d'attributs
• Il est possible d'utiliser des filtres selon la
norme
RFC 2254
• Les contrôles permettent la mise en forme
des résultats (par exemple tri ascendant,
etc…)
64
Search : pour faire des requêtes
NamingEnumeration
search(
String stringName,
Attributes attributesToMatch
)
On peut utiliser des filtres de recherche selon la spécification RFC 2254:
(cn=Babs Jensen)
(!(cn=Tim Howes))
(&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))
(o=univ*of*mich*)
NamingEnumeration
search(Name stringName, String stringRFC2254Filter, SearchControls
searchcontrols)
65
Search : contrôle de la recherche
• On peut utiliser des contrôles permettant :
– De définir les attributs à renvoyer
– De définir la portée de la recherche (récursive
en arbre, locale…)
– Le nombre maximum de réponses
– Le temps maximum d'attente
– De renvoyer ou non l'objet Java associé
– De déréférencer ou non les liens
66
Un exemple
String filter = "(objectclass=Inetorgperson)";
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
controls.setReturningObjFlag(false);
controls.setReturningAttributes(attrIds);
try
{
NamingEnumeration enumDev =
initCtx.search("ou=people", filter, sc);
67
Classes à connaître
Context.list()
NameClassPair
Context.listBindings()
Binding
Directory.search()
SearchResult
Renvoient une NamingEnumeration de ...
68
Utilisation d'un SearchResult
while (enumDev.hasMore())
{
SearchResult sr = (SearchResult)enumDev.next();
Attributes attributes = sr.getAttributes();
NamingEnumeration ne = attributes.getAll();
while (ne.hasMore())
{
Attribute attr = (Attribute) ne.next();
String attrID = attr.getID();
NamingEnumeration values = attr.getAll();
...
while (values.hasMore())
child.add(
new DefaultMutableTreeNode(values.nextElement()));
}
}
69
Résumé : Directory
•
•
•
•
Mêmes méthodes que Context
Créé à partir de InitialDirContext
Rajoute la gestion des attributs
Rajoute les fonctions de recherche
70
Autres fonctionnalités
Noms composés
Object obj1 = ctx.lookup("cn=Ted Geisel, ou=People, o=JNDITutorial");
CompositeName cname = new CompositeName(
"cn=Ted Geisel, ou=People, o=JNDITutorial");
Object obj2 = ctx.lookup(cname);
• L'interface lookup a 2 signatures : String ou
Name
72
Stockage d'objets
• On peut stocker
–
–
–
–
–
Des objets serialisables
Des références et des objets référençables
Des objets avec des attributs
Des Remote Objects
Des objets Corba
73
Exemple : stockage d'un objet
RMI
// On initialise le Contexte
// ctx = new javax.naming.InitialDirContext...
Hello h = new HelloImpl();
// Bind the object to the directory
ctx.bind("cn=RemoteHello", h);
• Une fois que l'objet est stocké dans le Directory,
une autre application peut l'utiliser
Hello h2 = (Hello)ctx.lookup("cn=RemoteHello");
74
Exemple : stockage d'une
référence
•
public class Fruit implements Referenceable {
String fruit;
public Fruit(String f) {
fruit = f;
}
public Reference getReference() throws NamingException {
return new Reference(
Fruit.class.getName(),
new StringRefAddr("fruit", fruit),
FruitFactory.class.getName(),
null);
// Factory location
}
75
Factory pour une référence
public class FruitFactory implements ObjectFactory {
public Object getObjectInstance(Object obj, Name name, Context ctx,
Hashtable env) throws Exception {
if (obj instanceof Reference) {
Reference ref = (Reference)obj;
if (ref.getClassName().equals(Fruit.class.getName())) {
RefAddr addr = ref.get("fruit");
if (addr != null) {
return new Fruit((String)addr.getContent());
}}}
return null;
}}
76
URL LDAP
• Ldap supporte les URLS de la forme :
ldap://host:port/dn?attributes?scope?filter?exten
sions
• Le nom d'hôte par défaut est localhost
• Le port par défaut est 389
• Exemple :
Object obj = new InitialContext().lookup(
"ldap://localhost:389/cn=homedir,cn=Jon%20Ruiz,
ou=People,o=jnditutorial");
77
alias
• Il est possible de définir des alias
ctx.search("ou=Staff", "(cn=J*)", null);
• Propriété d'environnement
java.naming.ldap.derefAliases
–
–
–
–
always
never
finding
searching
78
Autres idées
• Espaces de nommages
• Fédérations de serveur , referrals (~alias de
serveurs)
• Sécurité, authentification, SSL
• Liens avec JINI, EJB ...
79