Java Naming and Directory Interface

publicité
Introduction
Java Naming and Directory Interface (JNDI)
Java Standard Edition
Java Naming and Directory Interface
API de connexion à des services d’annuaires et de résolution de noms
RMI Registry (RMI), CosNaming (Corba), LDAP, NIS, File System, DNS…
!!Uniformise l’accès à ces annuaires dans une seule API
!!Utilisation simultanée et transparente de ces annuaires
Gaël Thomas
[email protected]
Service de résolution de noms
Associe des noms à des entités + recherche à partir du nom
Université Pierre et Marie Curie
Master Informatique
M2 – Spécialité SAR
Service d’annuaire
Associe des attributs et des noms aux entités + recherche à partir des deux
2008-2009
Introduction
Exemple de service de résolution de noms : RMIRegistry
!!API définie en Java
!!Associe des noms plats à des objets RMI
Rappel : objet RMI = objet Serveur, implémente l’interface Remote
Serveur WEB
Service de transport : IIOP, RMI ou autre
Cache
2008-2009
Conteneur EJB
Master SAR - M2 MDOC - Introduction
Lancer le service de résolution de noms :
Service BD : JDBC
Conteneur WEB
Service Transaction: JTA/JTX
Service Nommage :
JNDI
JEE
Conteneur EJB
2
Exemples d’annuaire
Client léger : navigateur Web
HTTP
Client
lourd
Master SAR - M2 MDOC - Introduction
!!shell$ rmiregistry &
Se connecter au service de résolution de noms en Java
!!Registry LocateRegistry.getRegistry(String host, int port);
Base
De
Donnée
3
2008-2009
Master SAR - M2 MDOC - Introduction
4
Exemples d’annuaire
Exemples d’annuaire
Exemple de service de résolution de noms : le système de fichiers
Exemple de service de résolution de noms : RMIRegistry
!! API définie par le système d’exploitation
!! Associe des noms hiérarchiques à des objets fichiers
Notion de répertoire :
Utiliser le RMI Registry
!!void bind(String name, Remote obj);
!!void rebind(String name, Remote obj);
!!String[] list();
!!Remote lookup(String name);
•! Entité contenant des noms
•! Un répertoire possède un nom dans un autre répertoire
Utiliser le système de fichier sous linux
!! ls (list), rm (remove), touch/redirection (bind), mv (move)
/
etc
passwd
2008-2009
Master SAR - M2 MDOC - Introduction
5
2008-2009
Exemples d’annuaire
uid=anne
2008-2009
!!Recherche à l’aide de filtre
Exemples :
•! (user=Bob) : cherche Bob
•! (&(user=B*)(objectclass=Person)) : cherche une personne dont le nom
commence par B
•! (&(age>22)(age<33)(objectclass=Person)) : cherche les personne dont l’âge est
compris entre 22 et 33
dn: dc=inria, dc=fr
uid=igor
6
•! scope=sub : dans tout le sous-arbre
•! scope=one : uniquement parmi les fils
•! scope=base : uniquement sur notre propre nœud (utile pour consulter les autres
attributs d’un nœud)
dn: dc=fr
ou=people
Master SAR - M2 MDOC - Introduction
!!Recherche : dans un sous-arbre (à partir d’un DN)
!!Scope : définit la profondeur de la recherche
Un nœud est identifié par son DN (Distinguished Name) constitué de la liste
(inverse) des RDN jusqu’à la racine
ou=computer
ls
Exemple de service d’annuaire : LDAP
!! Associe des propriétés (clé=valeur) à des entités
!! Chaque entité possède une classe (Person etc..) définie dans un schéma
!! Structure hiérarchique, appelée DIT (Directory Information Tree)
!! Chaque nœud de l’arbre est une entité qui possède une propriété appelée RDN
(Relative Distinguished Name) unique pour la classe
dc=inria
conf.d
Exemples d’annuaire
Exemple de service d’annuaire : LDAP
dc=fr
bin
dn: ou=people, dc=inria, dc=fr
Un annuaire LDAP est une BD hiérarchique
dn: uid=igor, ou=people, dc=inria, dc=fr
Master SAR - M2 MDOC - Introduction
7
2008-2009
Master SAR - M2 MDOC - Introduction
8
Architecture de JNDI
Architecture de JNDI
Architecture de JNDI
JNDI API : api d’utilisation de services de nommage
javax.naming.*, javax.naming.directory.*, javax.naming.ldap.*,
javax.naming.event.*
Naming Manager : correspondance entre l’API JNDI et les
fournisseurs de services
JNDI SPI : api interne des fournisseurs de services
javax.naming.spi.*
2008-2009
Master SAR - M2 MDOC - Introduction
9
2008-2009
Master SAR - M2 MDOC - Introduction
Architecture de JNDI
Architecture de JNDI
JNDI : système hiérarchique de résolution de noms et annuaire
Hiérarchie de contexte
!!API d’accès à des annuaires avec des fournisseurs d’annuaires
!!API d’accès à des services de résolution de noms sinon
(API d’accès à un annuaire hérite de l’API de résolution de noms)
!!Un contexte est un répertoire de noms
(répertoire dans les fs, NamingContext Corba, nom de domaine DNS…)
!!Contient des associations <nom, objet>
!!Peut contenir des sous-contextes (association <nom, Context>)
!!N’existe que si le fournisseur de service l’offre (pas le cas de RMIRegistry)
Différences principales entre les deux API
!!Annuaire : recherche par nom ou par filtre
!!Service résolution nom : recherche par nom uniquement
InitialContext
!!Contexte racine dans JNDI
!!Obligatoire pour toute recherche
!!Construit avec new InitialContext() ou new InitialContext(Hashtable env)
Possibilité de passer des paramètres au contexte initial via
Étude dans le suite : le service de résolution de nom uniquement
!!API pour les annuaires : voir la JavaDoc javax.naming.directory
!!Notions correspondent à celles de LDAP
2008-2009
Master SAR - M2 MDOC - Introduction
10
•! Propriété (jndi.properties)
•! Table de hash env
11
2008-2009
Master SAR - M2 MDOC - Introduction
12
Utilisation de JNDI
Utilisation de JNDI
Les deux paramètres de base du contexte initial
Extrait de l’API de Context
!!INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial"
Classe du fournisseur de service du contexte initial
!!void bind(String name, Object obj):
associe l’objet obj au nom name
(Attention : cette classe doit être dans le CLASSPATH)
(chemin complet, tous les contexte intermédiaires doivent exister)
!!PROVIDER_URL = "java.naming.provider.url »
Paramètres passé au fournisseur, en général URL du service
!!NamingEnumeration<Binding> listBinding(String name):
renvoie la liste des associations possédant le nom name (1 niveau)
!!Object lookup(String name):
Renvoie l’objet ayant pour nom name (dans le sous-arbre)
!!void rebind(String name, Object obj):
Ré-associe l’objet obj au nom name
!!void unbind(String name):
Détruit l’association ayant pour nom name
!!Context createSubcontext(String name):
Crée un sous-contexte ayant pour nom name (préférable à bind)
Exemple
Properties props = Properties();
props.put(INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.registry.RegistryContextFactory");
props.put(PROVIDER_URL, "rmi://localhost:1099");
Context ic = new InitialContext(props);
2008-2009
Master SAR - M2 MDOC - Introduction
13
2008-2009
Utilisation de JNDI
Master SAR - M2 MDOC - Introduction
14
L’usine à objet
Exemple avec le service de résolution de noms RMI
Problème avec les Stateful Bean:
A chaque client son Bean!
public interface Hello { void sayHello(); }
public HelloImpl implements Hello { … implem … }
! ! ic.lookup("Test@Remote")
renvoie un nouveau Bean à chaque appel
Côté serveur
Context ic = new InitialContext(props);
Remote obj = new HelloImpl();
UnicastRemoteObject.exportObject(obj, 0);
ic.rebind("mon-serveur", obj);
Solution : enregistrer des javax.naming.Reference
! ! Interception de la recherche
Côté client
Context ic = new InitialContext(props);
Hello server = (Hello)ic.lookup("mon-serveur");
server.sayHello();
2008-2009
Master SAR - M2 MDOC - Introduction
15
2008-2009
Master SAR - M2 MDOC - Introduction
16
L’usine à objet
L’usine à objet
Exemple : l’usine MaFactory
Exemple : l’enregistrement
public MaFactory extends ObjectFactory {
public Object getObjectInstance(Object obj, Name name,
Context nameCtx, Hashtable environment) {
String cname = name.get(0); // nom de l’objet
Class cl = Class.forName(name); // charge la classe
return cl.newInstance();
}
}
interface Cinema {}
public CinemaImpl implements Cinema {}
2008-2009
Master SAR - M2 MDOC - Introduction
// (class de l’objet, class de l’usine, classpath de l’usine)
Reference ref = new Reference(
Cinema.class.getName(),
MaFactory.class.getName(),
null);
ic.bind("CinemaImpl", ref);
17
2008-2009
L’usine à objet
18
URL JNDI
Exemple : la recherche
ContextInitial : associé à un unique fournisseur
ic.lookup("CinemaBean");
lookup
Master SAR - M2 MDOC - Introduction
Valeur
retournée
Problème :
Utiliser simultanément plusieurs fournisseurs de nommages
new CinemaBean
getObjectInstance
"CinemaBean"
rmiregistry
ref
car
instance de MyFactory
Solution :
Les URL JNDI
Reference
!!Définissent des protocoles
!!Associe des protocoles avec des fournisseurs
"rmi://localhost:1099/mon-serveur",
"iiop://susanoo.lip6.fr/un-autre-serveur"
2008-2009
Master SAR - M2 MDOC - Introduction
19
2008-2009
Master SAR - M2 MDOC - Introduction
20
URL JNDI
URL JNDI
URL RMI : accès direct à un service de résolution de noms
Exemple :
InitialContext ic = new InitialContext();
URL = schema:partie-specific-au-protocole
Hello sever =
(Hello)ic.lookup("rmi://localhost:1099/mon-server");
!!Le fournisseur correspondant au schéma est automatiquement chargé
!!Évite de donner explicitement une classe au contexte initiale
// ! équivalent à
//
(new com.sun.jndi.url.rmi.rmiURLContextFactory())
//
.getInitialContext(props)
//
.lookup("mon-server");
// avec props "contient" localhost et 1099
Construction de la classe correspondant au schema
package_prefix.schema.schemaURLContextFactory
package_prefix = com.sun.jndi.url par défaut
Remarque : ici, le contexte initial ic n’a pas de drivers (SPI) associé
2008-2009
Master SAR - M2 MDOC - Introduction
21
2008-2009
URL JNDI
Master SAR - M2 MDOC - Introduction
22
URL JNDI
Définition de nouvelles URL JNDI
Exemple :
!!Paramètre du contexte initial (propriété)
!!Context.URL_PKG_PREFIX = "java.naming.factory.url.pkgs »
Exemple :
InitialContext ic = new InitialContext(props);
ic.lookup("java:comp/env/ejb/Cinema");
//
charge com.bubble.java.javaURLContextFactory
//
délègue la recherche de comp/env/ejb/Cinema à
//
cette usine à fournisseur d’annuaire
props.put(URL_PKG_PREFIX, "org.wiz:com.bubble");
Cherche les usines à fournisseur d’annuaire en essayant de charger les classes
org.wiz.schema.schemaURLContextFactory
puis com.bubble.schema.schemaURLContextFactory
puis com.sun.jndi.url.schema.schemaURLContextFactory
2008-2009
Master SAR - M2 MDOC - Introduction
23
2008-2009
Master SAR - M2 MDOC - Introduction
24
JNDI dans Java Enterprise Edition
JNDI et Java Enterprise Edition
Nommage local
Deux espaces de nommage pour chaque composant (Web ou EJB)
Nommage local
!!Espace de nommage global (new InitialContext())
Service de nommage classique, service peut être distant
!!Espace de nommage local sous le schéma d’URL java:
Convention : les noms importés sont dans java:comp/env
Réécriture des noms, service forcément local
Principe :
!!Un composant utilise les noms locaux
!!Le descripteur de déploiement importe les noms globaux
! Le code est indépendant des noms globaux
2008-2009
Master SAR - M2 MDOC - Introduction
Nommage global
EJB Test
Client Lourd
Référence
comp/
env/
Cinema
Utilisation directe
Test@Remote
Lien
Lien
Cinema@Remote
comp/
env/
Cinema
Référence
MaServlet
25
2008-2009
JNDI dans Java Enterprise Edition
comp/
env/
Test
Lien
Nommage local
JNDI dans Java Enterprise Edition
EJB Cinema
Master SAR - M2 MDOC - Introduction
26
JNDI dans Java Enterprise Edition
Principe du nommage avec les annotations :
Exemple 1 en utilisant les paramètres par défaut :
!!name : le nom local
!!mappedName : le nom global (donc, à éviter! Sauf pour clients lourds…)
!!Fichier TestBean.java
Exemple 1 :
@Stateful(name= "Test", mappedName="Test@Remote")
@Remote(Test.class)
Par défaut,
public class TestBean implements Test {
name=nom de l’interface
@EJB(name="Cinema")
de l’entité en question
(sans le package)
Cinema cinema;
les deux name peuvent
}
êtres omis
@Stateful(mappedName="Test@Remote")
public class TestBean implements Test {
@EJB
Cinema cinema;
}
!!Fichier CinemaBean.java
@Stateless
public class CinemaBean implements Cinema {…}
Tous les noms locaux des beans sont exportés dans l’unité de déploiement
(ici, Cinema est packagé dans le même Bean que Test)
2008-2009
Master SAR - M2 MDOC - Introduction
27
2008-2009
Master SAR - M2 MDOC - Introduction
28
JNDI dans Java Enterprise Edition
JNDI dans Java Enterprise Edition
Exemple 2 :
EJB : importation de noms externes et modification des liaisons
@Resource(name="rigolo", mappedName="topic_rigolo")
Topic
topic;
@Resource(name="factory", mappedName="JTCF")
TopicConnectionFactory factory;
Ajouter un fichier ejb-jar.xml
Les noms dans le services globales sont donc
!! "topic_rigolo" pour le topic
!!"JTCF" pour l’usine
Intérêt du nom local :
Pour modifier le lien entre nom global et nom local dans le fichier
de déploiement
2008-2009
Master SAR - M2 MDOC - Introduction
29
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>AutreBean</ejb-name>
<!-- insérer ici les importations
</session>
</enterprise-beans>
</ejb-jar>
2008-2009
JNDI dans Java Enterprise Edition
-->
Master SAR - M2 MDOC - Introduction
JNDI dans Java Enterprise Edition
Importation d’un EJB Test dans un EJB AutreBean
Importation d’une ressource dans un EJB AutreBean
<ejb-name>AutreBean</ejb-name>
paramètre name de @EJB
<ejb-ref>
<ejb-ref-name>Test</ejb-ref-name>
<remote>mdoc.ejbsample.Test</remote>
<mapped-name>Test@Remote</mapped-name>
nom global du Bean Test
<injection-target>
<injection-target-class>
mdoc.AutreBean</injection-target-class>
<injection-target-name>
champs @EJB de AutreBean
champsEJB</injection-target-name>
</injection-target>
</ejb-ref>
<ejb-name>AutreBean</ejb-name>
paramètre name de @Resource
<resource-ref>
<res-ref-name>monitor</res-ref-name>
<mapped-name>monitoring_topic</mapped-name>
<injection-target>
nom global du topic
<injection-target-class>
mdoc.AutreBean</injection-target-class>
<injection-target-name>
champs @Resource de AutreBean
topic</injection-target-name>
</injection-target>
</resource-ref>
class AutreBean { @EJB(name="Test") champsEJB; }
class AutreBean { @Resource(name="monitor") topic; }
2008-2009
Master SAR - M2 MDOC - Introduction
30
31
2008-2009
Master SAR - M2 MDOC - Introduction
32
JNDI dans Java Enterprise Edition
JNDI dans Java Enterprise Edition
Web : importation de noms externes et modification des liaisons
Web : importation de noms externes et modification des liaisons
1 - Enrichir le fichier web.xml
2 - Définir le fichier jonas-web.xml
correspond à java:comp/env/Test
dans le composant Web
<ejb-ref>
<ejb-ref-name>Test</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home></home>
<remote>mdoc.ejbsample.Test</remote>
</ejb-ref>
correspond à java:comp/env/monitor
<jonas-web-app>
<jonas-ejb-ref>
Nom local
<ejb-ref-name>Test</ejb-ref-name>
<jndi-name>Test@Remote</jndi-name>
Nom global
</jonas-ejb-ref>
Nom local
<jonas-resource>
<res-ref-name>monitor</res-ref-name>
<jndi-name>monitoring_topic</jndi-name>
</jonas-resource>
Nom global
</jonas-web-app>
dans le composant Web
<resource-ref>
<res-ref-name>monitor</res-ref-name>
<res-type>javax.jmx.Topic</res-type>
<res-auth>Container</res-auth>
</resource-ref>
2008-2009
Master SAR - M2 MDOC - Introduction
33
2008-2009
JNDI dans Java Enterprise Edition
Master SAR - M2 MDOC - Introduction
34
JNDI dans Java Enterprise Edition
Web : importation de noms externes et modification des liaisons
Nommage et répartition
!!Version centralisée : deux conteneurs centralisés sur deux machines
Utilisation :
void doGet(HttpServletRequest i, HttpServletResponse o) {
Test test = (Test)(new InitialContext()).
lookup("java:comp/env/Test");
Topic topic = (Topic)(new InitialContext()).
lookup("java:comp/env/monitor");
}
Service de nommage 1
sur Machine 1
Service de nommage 2
sur Machine 2
Conteneur 1
sur Machine1
class MaServlet extends HttpServlet {
@EJB(name="Test") Test test;
@Resource(name="monitor") Topic topic;
}
Master SAR - M2 MDOC - Introduction
Conteneur 2
sur Machine2
!!Version distribuée : un service de nommage commun sur une autre machine
Ou
2008-2009
Conteneur 1
sur Machine1
Conteneur 2
sur Machine2
Service de nommage
sur Machine 3
35
2008-2009
Master SAR - M2 MDOC - Introduction
36
JNDI dans Java Enterprise Edition
Conclusion
Nommage et répartition
JNDI : masque l’hétérogénéité des services d’annuaires
!!Version tolérante aux fautes et/ou répartition de charge
Conteneur 1
sur M1
Conteneur 2
sur M2
Proxy de répartition
sur M1
Proxy de répartition
sur M2
!!Une API pour de multiples services
!!Mais : possibilité limitées par le service
•! Pas d’arbre avec JNDI si service RMIRegistry
•! Pas de lookup("*t*") avec RMIRegistry
Notion d’URL JNDI : accès simultané à plusieurs services d’annuaire
!!Mais ne masque pas la localisation du service d’annuaire
!!Mais ne masque pas le type du service d’annuaire
Tolérance
aux pannes
Service de nommage
répliqué 1 sur M3
JNDI dans JEE
Service de nommage
répliqué 2 sur M4
!!Le conteneur à composant prend en charge l’accès aux service de nommage
!!Masquage des noms réels via le schéma d’URL java: + fichier déploiement
!!Construction avancée distribuée pour tolérance aux pannes/répartition
charge
synchronisation
2008-2009
Master SAR - M2 MDOC - Introduction
37
2008-2009
Master SAR - M2 MDOC - Introduction
38
Téléchargement