Documentation utilisateur
Nous essayons de simplifier les modifications requises dans votre projet
pour activer CorbaTrace. Nous utilisons uniquement les méthodes de l'OMG
pour l'installer. Ce fichier peut ne pas être parfaitement synchronisé
avec les derniers fichiers sources. Voir dans le CVS le fichier INSTALL et
dans l'API JavaDoc pour les nouvelles instructions.
Installation dans votre projet
Vous avez un exemple du serveur et un du client dans ./src/java/corbatrace/hello.
Inclure uniquement CorbaTrace.jar dans votre CLASSPATH.
set CLASSPATH=$CLASSPATH:mypath/CorbaTrace.jar
Ajouter au début de vos fichiers sources :
import corbaTrace.Interceptor;
Client
Dans vos sources, avant la création de l'orb, initialisez l'intercepteur en créant une instance d'InterceptorClient .
Après l'initialisation de l'orb, et avant les appels distants, ajoutez :
obj = interceptorClient.active_interception(obj, orb);
où obj est créé de la façon suivante :
org.omg.CORBA.Object obj = orb.string_to_object(myIOR);
Vous pouvez obtenir votre propre objet en utilisant la fonction standard suivante :
Hello hello = HelloHelper.narrow(obj);
Une fois tous les objets créés, ajoutez :
interceptorClient.activate_log(orb, "My Name");
"My Name" est utilisé pour identifier votre composant. Tous les objets client sur le même orb font partis du même composant.
Si vous voulez changer la stratégie d'interception, appelez la methode suivante :
interceptorClient.change_level_interception(obj, orb, int); (Se référer au site OMG specification pour plus de détails).
Voici un exemple :
import corbatrace.InterceptorClient;
...
class MyClass {
...
interceptorClient = new InterceptorClient();
...
ORB orb = ORB.init(args, props);
...
obj = orb.string_to_object(ref);
obj = interceptorClient.active_interception(obj, orb);
interceptorClient.activate_log(orb, "My Component");
...
Hello hello = HelloHelper.narrow(obj);
...
}
Vous pouvez télécharger le code de cet exemple Client sur votre CVS : Cliquez ici.
Server
Dans vos sources, avant la creation de l'orb, initialisez l'intercepteur en créant une instance d'InterceptorServer .
Après l'initialisation de l'orb, appelez la méthode ci-dessous pour obtenir les références sur le RootPOA :
obj = orb.resolve_initial_references("RootPOA");
où obj est un org.omg.CORBA.Object.
Obtenez votre propre rootPOA en utilisant la méthode standard suivante :
POA rootPOA = org.omg.PortableServer.POAHelper.narrow(obj);
Puis créez le POA en utilisant la méthode "create_poa" de la classe InterceptorServer :
poa_interceptor = interceptorServer.create_poa(orb, rootPOA, "myHelloPOA");
où "myHelloPOA" est le nom du nouveau POA créé dynamiquement, et rootPOA votre propre POA.
Activez l'objet sur ce POA :
obj = interceptorServer.activate_object(poa, helloImpl, "My Component");
Cette méthode enregistre et active l'objet sur le POA qui vient d'être créé.
Ce POA permettra aux applications clientes d'y accéder. Cette
méthode active aussi le POAManager qui contrôle la manière avec laquelle
le POA gère les requêtes des différents clients.
Obtenez votre propre objet en utilisant la méthode standard suivante :
Hello hello = HelloHelper.narrow(obj);
Enregistrez votre objet "hello" dans un fichier (ou dans le CosNaming) :
writeObjectToFile(orb, hello, filename);
Mise en attente du serveur :
Celui-ci écoute les demandes des différents clients et y répond
en appelant les méthodes correspondantes sur l'objet serveur :
orb.run();
Destruction du serveur avant de quitter le programme :
orb.destroy();
Voici un exemple :
import corbaTrace.InterceptorServer;
...
class MyClass {
...
interceptorServer= new InterceptorServer();
...
ORB orb = org.omg.CORBA.ORB.init(args,props);
obj = orb.resolve_initial_references("RootPOA");
POA rootPOA = org.omg.PortableServer.POAHelper.narrow(obj);
poa_interceptor = interceptorServer.create_poa(orb, rootPOA, "myHelloPOA");
...
obj = interceptorServer.activate_object(poa, helloImpl,"My Component");
Hello hello = HelloHelper.narrow(obj);
writeObjectToFile(orb, hello, "My File");
...
orb.run();
orb.destroy();
}
Vous pouvez téléchargez tout le code de cet exemple Serveur sur votre CVS :
- Server.java
- Hello.idl
- Hello_impl.java
Résultat
Compilez votre projet et exécutez-le.
Des fichiers log sont générés ( *_Ctrace.xml pour les objets client et *_Strace.xml pour les objets serveur).
Leur compréhension est facile.
Vous pouvez les convertir en XMI et utilisez d'autres filtres (pas encore implémenté).
Vous pouvez voir XMI dans tous les outils UML qui lisent les fichiers XMI
standards. Vous pouvez aussi utiliser notre outil appelé : xmi2latex.
Captures d'écran
Lors de l'exécution de notre exemple vous obtenez les deux captures d'écran ci-dessous :
Server
Client
Après l'interception, deux logs sont générés (fichiers joints) :
Generer un Diagramme de Sequence UML
Après la création des logs des messages interceptés, vous pouvez les utiliser avec notre outil (Log2xmi) pour générer un diagramme de séquence UML au format XMI.
Cet outil a quatre objectifs :
- parser vos fichiers de log, et fusionner les messages partiels pour obtenir des messages complets.
- synchroniser toutes les horloges locales des objects à une horloge commune (puisque souvent distribués sur différentes machines à travers le monde).
- appliquer quelques filtres personnels pour obtenir des informations plus pertinentes.
- generer un fichier XMI que vous pouvez directement visualiser sur des outils courants comme MagicDraw et Rational Rose.
La ligne de commande pour Log2xmi est la suivante:
java corbaTrace.log2xmi.Main [options] <XML logs>
Les logs XML sont les logs que vous avez généré à l'étape précédente. Ils peuvent être donnés sous la forme d'un chemin vers un fichier ou d'une URL.
N'oubliez pas de placer le fichier log.dtd dans le même répertoire que vos logs (de même pour les filtres).
Voici un résumé des options :
-o est le fichier xmi dans lequel log2xmi sauve tous les messages lus.
Par défaut, log2xmi utilise le nom de fichier "out.xml".
-f donne un fichier de filtre pour restreindre les messages générés (voir plus bas).
-x definit pour quelle application vous souhaitez générer le fichier XMI.
-xr signifie pour Rational Rose, -xm pour Magic Draw, et -xrm (ou -xmr) pour les deux.
-v indique de ne pas valider les logs XML avec leur DTD (lors du parsage).
Cela ne devrait rien changer comme les logs générés sont validés, mais vous pouvez l'utiliser si vous voulez toujours générer le fichier xmi même si les logs sont un peu corrompus.
note : cette option s'applique aussi au fichier de filtres (car celui-ci est aussi basé sur log.dtd).
Nous vous recommandons d'utiliser cette option aussi rarement que possible.
-s indique de passer l'étape de synchronisation.
Cela peut être utilisé seulement si vous savez que tous vos objets fonctionnent déjà avec la même horloge (dans le même fuseau horaire), et ainsi l'étape de synchronisation n'est pas nécessaire.
Cela peur accélérer un peu l'ensemble du traitement des logs.
-d affiche plus d'informations à chaque étape.
Elle est inutile dans la plupart des cas et ne devrait être considérée qu'à des fins de débuggage.
Les filtres sont écrits dans un fichier XML, comme défini dans la DTD (log.dtd)
Il fonctionne à deux niveaux :
- de manière globale
- au niveau d'un objet
Au niveau global, vous pouvez restreindre les messages à :
- vos types de messages donnés :
les types sont : REQUEST, REPLY, EXCEPTION, BROKEN_REQUEST, BROKEN_REPLY, et BROKEN_EXCEPTION.
- vos dates données (ou intervalles) :
Il y a trois types de filtres de date : après une date, avant une date, entre eux dates.
Les dates utilisent le même format que les logs : annee-mois-jourTheures-minutes-secondes-millisecondes (par ex: 2002-03-09T17:00:00.000)
- vos opérations données, independamment des objets.
pour chaque operation vous donnez son nom, et pouvez la restreindre plus précisemment avec les valeurs des arguments de l'opération.
Les arguments définis sont de deux types
- un type de données et une valeur
- une position d'argument dans l'opération (de 1 à n) et une valeur
- vos objets donnés avec leur ID (nom de l'objet)
Pour des objets donnés, vous pouvez aussi restreindre vos messages plus précisemment à des types de messages donnés, des dates, et des opérations, avec les même principes qu'au niveau global.
Chaque filtre différent (date - type - objet - methode) fonctionne comme un "ET" avec les autres.
Chaque composant de filtre (les dates pour un filtre de date, les arguments pour un filtre de méthode, etc.) fonctionne comme un "OU" avec les autres.
Par exemple : (filters.xml)
<filter>
<message_types>
<type value="BROKEN_REQUEST"/>
<type value="BROKEN_REPLY"/>
<type value="BROKEN_EXCEPTION"/>
</message_types>
<dates>
<after date="2002-03-09T17:00:00.000"/>
<before date="2002-03-09T15:00:00.000"/>
<between from="2002-03-09T15:30:00.000" to="2002-03-09T16:30:00.000"/>
</dates>
<methods>
<method name="anOperation1">
<argumentAt position="3" value="ddd"/>
<typedArgument type="string" value="ccc"/>
</method>
<method name="anOperation2">
</method>
</methods>
<objects>
<object id="anObjectID1">
<message_types>
<type value="BROKEN_REQUEST"/>
<type value="BROKEN_REPLY"/>
<type value="BROKEN_EXCEPTION"/>
</message_types>
<methods>
<method name="anOperation">
<argumentAt position="1" value="aaa"/>
<argumentAt position="2" value="bbb"/>
</method>
</methods>
</object>
<object id="anObjectID2">
</object>
</objects>
</filter>
Ces filtres de messages conservent les messages qui :
sont de type incomplets (n'importe lequel)
ET sont après 17H (le 9/3/2002)
OU avant 15H
OU entre 15H30 et 16H30
ET sont des operations nommées "anOperation1"
avec (un argument à la position 3 égal à "ddd"
OU un argument de type string égal à "ccc")
OU une operation nommée "anOperation2"
ET concerne un objet "anObject1"
avec un message de type incomplet
ET concernant l'operation "anOperation"
avec un argument à la position 1 égal à "aaa"
OU un argument à la position 2 égal à "bbb"
OU concerne un object "anObjectID2"
Bien sûr, ce n'est qu'un exemple. Ici, donner les types de messages comme "incomplets" pour l'objet "anObject1" n'est pas utile comme il est déjà défini de manière globale pour le même type de messages.
Documentation complète
Si vous voulez une explication complète sur le projet CorbaTrace, vous pouvez lire notre rapport et notre présentation. Le rapport parle de l'architecture de CorbaTrace et de sa création, des intercepteurs portables de Corba, de XMI et de beaucou d'autres choses.
La documentation sur les nouveautés de la version 2.0 et la nouvelle IHM n'a pas été traduite (honte à nous). Regardez donc la version anglaise
Contactez-nous en cas d'erreurs ou pour nous soumettre vos corrections.
http://corbatrace.tuxfamily.org
|