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