Académique Documents
Professionnel Documents
Culture Documents
Guide de programmation
Copyright 2011 PRELYTIS
iii
Guide de programmation
2.7. Authentification spcifique ......................................................................................... 6. Intgration par URL .................................................................................................................... 1. Authentification .................................................................................................................. 2. Trackback .......................................................................................................................... 7. Session externe de type "plugin" .................................................................................................... 1. Exemple de paramtrage de session externe "classique" .............................................................. 2. Exemple de paramtrage de session externe "plugin" ................................................................. 3. API Plugin ......................................................................................................................... 4. Exemple de fichier Javascript ................................................................................................
22 31 31 31 32 32 32 33 34
iv
PRELYTIS LiveDashBoard (version WAR) ne met disposition que les API Rest. * Les services prsents en versions 4.2.x sont toujours prsents en versions 4.4.x. ** JSR-109 et JSR-181 sont des normes JAVA spcifiant les rles des fabriquants d'application (tels que PRELYTIS), et des fabriquants de serveurs d'application (tels qu'IBM). De plus, ces normes s'appuient sur la norme web service WS-I Basic Profile. Nous pouvons donc dire que les Web services de LiveDashBoard respectent la norme WS-I Basic Profile. Par ailleurs, la partie mtier de LiveDashBoard est accessible par un mcanisme de requte/rponse. Ces requtes/rponses sont gres par un empilement paramtrable de faades. Le dveloppement d'une ou plusieurs faades spcifiques permet ainsi d'adapter le fonctionnement de LiveDashBoard aux besoins du client.
1. EJB
Un EJB est un objet binaire qui est expos par le serveur d'application dans lequel est dploy LiveDashBoard. Chaque EJB expose une interface qui peut tre appele par une application cliente JAVA. Le fabriquant de l'EJB peut choisir d'exposer sont EJB en accs local (accessible uniquement depuis le serveur d'application) et/ou en accs distant (accessible depuis le rseau). Un client d'un tel EJB n'a pas besoin d'environnement particulier pour fonctionner. Donc n'importe quelle application JAVA peut appeler un EJB avec accs distant. Cependant, l'accs ces procdures distantes se fait par le rseau sur des ports spcifiques, autres que le port 80. Attention aux configurations rseaux et pares-feux. Pour plus de prcisions sur les EJBs, le tutorial de SUN [http://java.sun.com/javaee/reference/tutorials/] est un bon dpart.
2. Service web
Un service web est une interface expose en XML, accessible depuis un navigateur par une simple URL. Il n'y a pas de problme de configuration rseau et pare-feu attendre. Un web service n'est pas li une technologie particulire, donc un consommateur de service web peut tre crit dans n'importe quel langage (par exemple en .NET, en PHP, etc.) Cependant, la fabrication et la lecture du flux XML rend l'usage des services web moins performants. De plus, comme ce flux doit tre comprhensible par n'importe quel langage de programmation, les types de donnes transfrables sont limits.
3. Contenu
Ces canaux de diffusion sont privilgier, pour intgrer LiveDashBoard avec d'autres applications. Les chapitres suivants expliquent les fonctionnalits exposes pour chaque canal, avec des exemples de paramtrage et d'implmentation pour diffrents types de clients (PHP, JAVA, .NET). API Rest EJB publis en version 4.2.x
EJB publis en version 4.4.x Web services publis en version 4.2.x Faades en version 4.4.x Sessions externes de type "plugin" en version 4.4.1+
2. API disponibles
Nous supposons que PRELYTIS LiveDashBoard est install et accessible depuis l'adresse http://localhost/tdb/ ; Les API de type REST sont alors accessibles depuis l'adresse http://localhost/tdb/rest/
<?xml version="1.0" encoding="UTF-8"?> <status> <installation baseUrl="/opt/prelytis/livedashboard" version="4.4.3" pro <license found="true" valid="true" owner="PRELYTIS SA"/> <driver found="true"/> <database found="true" version="4.4.3"/> </status>
API Rest
API Rest
2.7. Licence
Entre URL Mthode Code retour Flux HTTP /rest/license GET Sortie 403 si l'URL est protge, 200 sinon <?xml version="1.0" encoding="UTF-8"?> <license> <element name="enddate" limit="null"/> <element name="user-standard" limit="10" current="3"/> <element name="user-message" limit="10" current="0"/> <element name="user-scorecard" limit="10" current="0"/> <element name="user-mobile" limit="10" current="0"/> <element name="world" limit="10"/> <element name="query" limit="-1"/> <element name="report" limit="-1"/> <element name="task-control" limit="100"/> <element name="task-metric" limit="100"/> </license>
API Rest
<user>param</user> <properties> <property> <name>paramName</name> <value>value</value> </property> </properties> <pool> <maxactive>-1</maxactive> <maxidle>10</maxidle> <minidle>0</minidle> <validationquery></validationquery> <maxwait>1000</maxwait> <minevictableidletime>60000</minevictableidletime> <timebetweenevictionruns>360000</timebetweenevictionruns> <numactive>2</numactive> <numidle>8</numidle> </pool> </datasource> ... </datasources> Commentaires driver : Nom de la classe Java du pilote JDBC utilis url : URL de connexion la base de donnes user : Compte de base de donnes utilis property/name : Nom du paramtre property/value : Valeur utilise pour le paramtre pool : n'apparait que si la connexion est gre par un pool pool/maxactive : nombre de connexion autoris en simultane (-1 : pas de limite) pool/maxidle : nombre maximum de connexions en attente d'utilisation pool/maxidle : nombre minimum de connexions en attente d'utilisation (recommand : 0) pool/validationquery : requte excuter pour s'assurer que la connexion est valide pool/maxwait : nombre de millisecondes attendre pour qu'une connexion se libre (lorsque maxactive est diffrent de -1) pool/minevictableidletime : nombre de millisecondes attendre pour qu'une connexion soit candidate l'viction pool/timebetweenevictionruns : priode (en millisecondes) laquelle le processus d'viction doit tre lanc pool/numactive : nombre de connexions actives pool/numidle : nombre de connexions en attente d'utilisation
2.9. Listes
Entre URL Mthode Code retour Flux HTTP /rest/[type d'objet]/ GET Sortie 403 si l'URL est protge, 404 si [type d'objet] n'est pas reconnu, 200 sinon <?xml version="1.0" encoding="UTF-8"?> <data> <element objectid="[identifiant]" name="..." descriptionkey="..." ...> <description key="..." lang=".." value="..."/> </element> ... </data>
API Rest
o [type d'objet] peut prendre l'une des valeurs user, world, ...
2.10. Exemple
Pour consulter la liste des mondes configurs, lancer la commande HTTP GET http://localhost/tdb/admin/world/. Le serveur rpond :
<?xml version="1.0" encoding="UTF-8"?> <data> <element objectid="100" name="world1" descriptionkey="514f93db7f00010100c4178a5fed6 <description key="514f93db7f00010100c4178a5fed605c" lang="fr" value="monde 1"/> <description key="514f93db7f00010100c4178a5fed605c" lang="en" value="world 1"/> </element> </data>
<?xml version="1.0" encoding="UTF-8"?> <data> <[type d'objet] objectid="[identifiant]" name="..." descriptionkey="... <description key="..." lang=".." value="..."/> ... </[type d'objet]> </data>
o [Type d'objet] est une des valeurs prcedemment listes et [identifiant] est l'identifiant numrique unique de l'objet visualiser
2.11.1. Exemple
Pour consulter le dtail du monde ayant l'identifiant 100, lancer la commande HTTP GET http://localhost/tdb/rest/world/100. Le serveur rpond :
<?xml version="1.0" encoding="UTF-8"?> <data> <world objectid="100" name="data" descriptionkey="514f93db7f00010100c4178a5fed605c" owner="superadmin" creationdate="20090329101900" lastmodificationdate="20090 url="jdbc:mysql://localhost/demo42data" driveroid="2" limittocatalogschema=" readonly="0" usedcnt="1" user="root" password="be5facfd32eefa4f" contpasswor resultsettype="1003" resultsetconcurrency="1007" fetchsize="-2147483648" tra drivername="MySQL"> <description key="514f93db7f00010100c4178a5fed605c" lang="fr" value="donnes"/> <description key="514f93db7f00010100c4178a5fed605c" lang="en" value="data"/> </world> </data>
API Rest
GET Sortie 403 si l'URL est protge, 404 si [type d'objet] n'est pas reconnu, 200 sinon
<?xml version="1.0" encoding="UTF-8"?> <data> <[type d'objet] objectid="[identifiant]" name="..." descriptionkey="... <description key="..." lang=".." value="..."/> ... </[type d'objet]> </data>
o [Type d'objet] est une des valeurs prcedemment listes et [Name] est le nom unique de l'objet visualiser
2.12.1. Exemple
Pour consulter le dtail du monde ayant pour nom data, lancer la commande HTTP GET http://localhost/tdb/rest/worldByName/data. Le serveur rpond :
<?xml version="1.0" encoding="UTF-8"?> <data> <world objectid="100" name="data" descriptionkey="514f93db7f00010100c4178a5fed605c" owner="superadmin" creationdate="20090329101900" lastmodificationdate="20090 url="jdbc:mysql://localhost/demo42data" driveroid="2" limittocatalogschema=" readonly="0" usedcnt="1" user="root" password="be5facfd32eefa4f" contpasswor resultsettype="1003" resultsetconcurrency="1007" fetchsize="-2147483648" tra drivername="MySQL"> <description key="514f93db7f00010100c4178a5fed605c" lang="fr" value="donnes"/> <description key="514f93db7f00010100c4178a5fed605c" lang="en" value="data"/> </world> </data>
API Rest
Chapitre 3. EJBs
1. EJBs de LiveDashBoard 4.2.x
LiveDashBoard expose (entre autres) deux EJBs : DashboardFacade I18nFacade Les EJBs sont dclars dans un descripteur de dploiement (fichier XML), qui se trouve dans l'EAR de LiveDashBoard : prelytis.ear/prelytis-base-ejb.jar/META-INF/ejb-jar.xml. Ci dessous se trouve un extrait de la dclaration de l'EJB DashboardFacade.
<session> <description>(Stateless)SessionBean DashboardFacade.</description> <ejb-name>DashboardFacade</ejb-name> <home>com.prelytis.dashboard.interfaces.DashboardFacadeRemoteHome</home> <remote>com.prelytis.dashboard.interfaces.DashboardFacadeRemote</remote> <local-home>com.prelytis.dashboard.interfaces.DashboardFacadeLocalHome</local-home <local>com.prelytis.dashboard.interfaces.DashboardFacadeLocal</local> <ejb-class>com.prelytis.dashboard.ejb.DashboardFacadeEJB</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> [...]
Context iniCtx = new InitialContext(); DashboardFacadeLocalHome home = (DashboardFacadeLocalHome) iniCtx.lookup("java:comp/e DashboardFacade res = home.create(); [...]
10
EJBs
[...]
Context iniCtx = new InitialContext(); I18nFacadeLocalHome home = (I18nFacadeLocalHome) iniCtx.lookup("java:comp/env/I18nFac I18nFacade res = home.create(); [...]
11
EJBs
2.1.2. Le client
Pour utiliser un EJB (2.x), il faut le demander au serveur de nom, via un contexte initial (Context.lookup()). Pour obtenir un EJB (2.x) distant, il suffit de le demander au serveur de nom distant (en gnral, celui du serveur d'application). import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; [...] Hashtable<String, String> table = new Hashtable<String, String>(); // PARTIE DEPENDANTE DU SERVEUR D'APPLICATION UTILISE table.put(Context.INITIAL_CONTEXT_FACTORY, ...); [...] Context iniCtx = new InitialContext(table);
Object objref = iniCtx.lookup("ejb/DashboardFacade"); DashboardFacadeRemoteHome remoteHome = (DashboardFacadeRemoteHome)PortableRemoteObjec DashboardFacadeRemote facade = remoteHome.create(); [...]
Context iniCtx = new InitialContext(); Object objref = iniCtx.lookup("ejb/I18nFacade"); I18nFacadeRemoteHome remoteHome = (I18nFacadeRemoteHome)PortableRemoteObject.narrow(o
12
EJBs
Pour obtenir un accs distant la faade LiveDashBoard : Hashtable<String, String> table = new Hashtable<String, String>();
13
EJBs
Context context = new InitialContext(table); Object objRef = context.lookup("ejb/DashboardFacade"); DashboardFacadeRemoteHome home = (DashboardFacadeRemoteHome)PortableRemoteObject.narr Le serveur JBoss doit tre prpar pour accepter les accs distants. Il faut prciser certains paramtres au dmarrage dans le fichier bin/run.conf ou la ligne de commande (o xxx est le nom du serveur appeler) : -Djboss.bind.address=x.x.x.x -Djava.rmi.server.hostname=xxx -Djava.rmi.server.useLocalHostname=false
Hashtable<String, String> table = new Hashtable<String, String>(); table.put("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContext table.put("java.naming.factory.url.pkgs", "com.sun.enterprise.naming"); table.put("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDISt //table.put("org.omg.CORBA.ORBInitialHost", "127.0.0.1"); //table.put("org.omg.CORBA.ORBInitialPort", "3700");
Context context = new InitialContext(table); Object objRef = context.lookup("ejb/DashboardFacade"); DashboardFacadeRemoteHome home = (DashboardFacadeRemoteHome)PortableRemoteObject.narr
Hashtable<String, String> table = new Hashtable<String, String>(); table.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContext table.put("org.omg.CORBA.ORBClass", "com.ibm.CORBA.iiop.ORB"); table.put(Context.PROVIDER_URL, "iiop://was61:2809");
14
EJBs
Context context = new InitialContext(table); Object objRef = context.lookup("ejb/DashboardFacade"); DashboardFacadeRemoteHome home = (DashboardFacadeRemoteHome) PortableRemoteObject.nar
15
Le javadoc de chaque service web est fourni avec LiveDashBoard. Vous pouvez le consulter dans le rpertoire webservice/doc de votre distribution de LiveDashBoard. Sous JBoss, la liste des services web publis sur le serveur est accessible l'URL suivante : http://xxx:8080/jbossws/ services/
1. String hello(String)
Mthode servant tester le bon dploiement du service web. La mthode retourne la chane passe en paramtre, prfixe par "from data WS :".
2. WSParameterListResponse parameterListRequest(WSParameterListRequest)
Mthode servant obtenir la liste des tuples d'une session de paramtrage. Elle ne fonctionne actuellement que pour les rapports. Cette liste permet de choisir un rapport (avec son identifiant) dans un appel ultrieur.
3. WSReportMetaDataResponse reportMetaDataRequest(WSReportMetaDataRequest)
Mthode permettant d'obtenir la description du rapport sans devoir le requter. Elle permet de prparer des filtres pour un appel reportRequest par exemple.
4. WSReportResponse reportRequest(WSReportRequest)
Mthode servant obtenir les donnes d'un rapport. WSReportRequest peut tre rempli partir des informations fournies par WSParameterListResponse
5. WSReportFilterResponse reportFilterRequest(WSReportFilterRequest)
Mthode permettant de parcourir un filtre hirarchique sur un rapport
16
6. WSMenuResponse menuRequest(WSMenuRequest)
Mthode permettant d'obtenir le menu d'un utilisateur. Cela correspond au contenu de l'espace de travail d'un utilisateur.
17
Chapitre 5. Faade
Les communications avec la partie mtier de LiveDashBoard se font via une faade et un mcanisme de requte/rponse. Au dmarrage de LiveDashBoard, les faades sont cres et configures. Elles constituent un empilement, invoques les unes la suite des autres lors de chaque requte. Le schma ci-dessous reprsente le fonctionnement gnral des faades :
Les faades implmentent l'interface com.prelytis.dashboard.interfaces.DashboardFacade. Celle-ci comporte la mthode : public Response dashboardRequest(Request value) throws DashboardException La faade LifeCycle vrifie que l'application est bien dmarre. Si c'est le cas, elle transmet la requte la faade suivante. Une exception est sinon leve. La faade AccessControl s'assure que l'identifiant de session fourni sur chaque requte est toujours valide et que la requte envoye est autorise pour l'utilisateur. La faade Authentication se charge de l'authentification des utilisateurs. Elle se charge uniquement des LoginRequest. PRELYTIS fournit les faades d'authentification suivantes : Valeur com.prelytis.dashboard.ext.HttpAuthenticationFacade Signification Rcupration de l'authentification HTTP effectue par le conteneur
18
Faade
Valeur
Signification
com.prelytis.dashboard.ext.HttpHeaderAuthenticationFacade Utilisateur authentifi indiqu dans un champ de l'entte HTTP com.prelytis.dashboard.ext.LdapAuthenticationFacade com.prelytis.dashboard.ext.OemAuthenticationFacade Authentification sur un LDAP Authentification oem
com.prelytis.dashboard.ext.LegacyAuthenticationFacade Utilisation d'un module d'authentification dvelopp pour la version 4.2 de LiveDashBoard Vous pouvez dvelopper votre propre faade pour raliser une authentification spcifique. La faade Business est la dernire faade mais la plus importante : C'est elle qui gnre la rponse. La rponse est renvoye aux faades appelantes en cascade.
19
Faade
2. Faades d'authentification
2.1. Authentification applicative
Lors d'une installation standard, la faade com.prelytis.dashboard.business.StandardAuthenticationFacade est utilise. Cette faade se charge de vrifier le mot de passe fourni la connexion avec celui stock dans la base de paramtrage de LiveDashBoard (mot de passe stock en MD5-Base64 dans la table BA_User).
20
Faade
21
Faade
</module>
22
Faade
L'import cre un projet prelytis dans le workspace. Crer un projet Java authentication-back dans lequel le module d'authentification sera dvelopp :
23
Faade
La liste des JARs importer est dfinie dans l'image ci-dessus. Il faut chercher ces JARs dans le projet prelytis. Crer un projet Java authentication-front dans lequel l'"authentication tracker" sera dvelopp Dclarer les dpendances sur le projet authentication-front (Project/Properties) :
24
Faade
25
Faade
Crer un nouveau package com.prelytis.sample.back dans le projet authentication-back (File/New/Package) Crer une classe Java AuthenticationFacade (File/New/Class) avec le code suivant : package com.prelytis.sample.back; import java.util.Map; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import import import import import import import import import import import import com.prelytis.dashboard.api.LoginBackException; com.prelytis.dashboard.dao.DaoFactory; com.prelytis.dashboard.dao.UserDao; com.prelytis.dashboard.ext.AbstractFacade; com.prelytis.dashboard.interfaces.DashboardException; com.prelytis.dashboard.interfaces.DashboardFacade; com.prelytis.dashboard.interfaces.Types; com.prelytis.dashboard.util.PRP; com.prelytis.dashboard.value.LoginRequest; com.prelytis.dashboard.value.Request; com.prelytis.dashboard.value.Response; com.prelytis.dashboard.value.data.BeanUserDefinition;
26
Faade
@Override public void init(Map<String, String[]> properties) { // TODO Read needed parameters declared in prelytis.xml } @Override public Response dashboardRequest(Request request) throws DashboardException { if (request.getType() == Types.LOGIN) { LoginRequest value = (LoginRequest)request; DaoFactory daoFactory = DaoFactory.getInstance(); UserDao userDao = daoFactory.getUserDao(); String userName = null; BeanUserDefinition user = null; try { userName = value.getUserPrincipal().getName(); user = userDao.getUserDefinition(userName); } catch (Exception ex) { LogManager.getLogger(this.getClass()). info("Unknown user " + userName); throw new LoginBackException(LoginBackException.CONNECT_UNKNOWN_USER, LoginBackException.INVALID_USER_KEY); } if (!user.getPublicAccess()) { if (value.getPassword() == null) { value.setPassword(new char[] {}); } String pwd = new String(value.getPassword()); Logger log = LogManager.getLogger(this.getClass()); // Check password in LiveDashBoard database if (!PRP.checkPassword(user.getPassword(), pwd)) { log.info("Invalid password for user " + userName); throw new LoginBackException(LoginBackException.CONNECT_UNKNOWN_USER, LoginBackException.INVALID_USER_KEY); } // To remove left menu and top banner, // you can change the connection type as follows // value.setConnectionType(Integer.valueOf( // LoginRequest.OEM_CONNECTION_TYPE)); // To force connection (when a session already exists for this username) // value.setForceConnection(Boolean.TRUE); } } return getFacade().dashboardRequest(request); } } Crer un nouveau package com.prelytis.sample.front dans le projet authentication-front (File/New/Package) Crer une classe Java AuthenticationTracker (File/New/Class) avec le code suivant : package com.prelytis.sample.front;
27
Faade
import java.util.Iterator; import java.util.Map; import import import import import import import import import import import import javax.faces.application.Application; javax.faces.application.NavigationHandler; javax.faces.context.ExternalContext; javax.faces.context.FacesContext; javax.faces.event.PhaseEvent; com.prelytis.dashboard.value.LoginRequest; com.prelytis.dashboard.value.api.PrelytisPrincipal; com.prelytis.dashboard.web.control.LoginBean; com.prelytis.dashboard.web.control.NavigationBean; com.prelytis.dashboard.web.interfaces.SessionCtx; com.prelytis.dashboard.web.jsf.AbstractAuthenticationTracker; com.prelytis.dashboard.web.value.DefaultSessionCtx;
public final class AuthenticationTracker extends AbstractAuthenticationTracker { @Override public void afterPhase(PhaseEvent event, String viewId) { final FacesContext context = event.getFacesContext(); final ExternalContext external = context.getExternalContext(); final Map<?, ?> sessionMap = external.getSessionMap(); final SessionCtx sessionContext = (SessionCtx)sessionMap.get(DefaultSessionCtx.KEY); // No filter for following urls if (viewId.startsWith("/Login")) return; if (viewId.startsWith("/Logout")) return; // Already connected? Object userOid = (sessionContext != null) ? sessionContext.getUserOid() : null; if (userOid != null) { if (viewId.startsWith("/trackback")) { navigateTrackBack(context, viewId); } if ((viewId.startsWith("/public") || viewId.startsWith("/rss"))) { navigatePublic(context, viewId); } return; } String login = (String)external.getRequestParameterMap().get("user"); login = "".equals(login) ? null : login; if (login == null){ Map<String, String> parameters = external.getRequestParameterMap(); Iterator<Map.Entry<String, String>> it = parameters.entrySet().iterator(); while (it.hasNext() && login == null) { Map.Entry<String, String> entry = it.next(); String key = entry.getKey(); if (key.indexOf(":header:publicUser") > -1) { login = entry.getValue(); login = "".equals(login)?null:login; } }
28
Faade
} // Public user if (login != null) { if (!viewId.startsWith("/rss")) preparePublicAuthentication(context, viewId); LoginRequest loginRequest = createLoginRequest(external, null); loginRequest.setUserPrincipal(new PrelytisPrincipal(login)); loginRequest.setPublicAccess(Boolean.TRUE); LoginBean loginBean = getLoginBean(context); loginBean.setLoginRequest(loginRequest); String outcome = loginBean.doLogin(); if (outcome == null) navigateError(context, "An error occured"); if (viewId.startsWith("/rss")) redirectRss(context); else { Application application = context.getApplication(); NavigationHandler handler = application.getNavigationHandler(); handler.handleNavigation(context, null, outcome); } return; } if (viewId.startsWith("/trackback")) { prepareTrackBackAuthentication(context, viewId); Application application = context.getApplication(); NavigationHandler handler = application.getNavigationHandler(); handler.handleNavigation(context, null, NavigationBean.LOGIN_OUTCOME); context.renderResponse(); return; } // No user authenticated, redirection to login page redirectLogin(context); } } Modifier le fichier prelytis.xml avec les informations suivantes : <?xml version="1.0" encoding="UTF-8"?> <liveDashBoard> <server> <authenticationTrackerClassName> com.prelytis.sample.front.AuthenticationTracker </authenticationTrackerClassName> ... </server> ... <!-<module> <className> com.prelytis.dashboard.business.StandardAuthenticationFacade </className> <param> <name>connectionType</name> <value>web</value> <value>mobility</value>
29
Faade
</param> </module> --> <module> <className>com.prelytis.sample.back.AuthenticationFacade</className> <param> <name>myParameter</name> <value>value1</value> <value>value2</value> </param> </module> </liveDashBoard> Reportez-vous la documentation d'installation pour plus d'information sur le fichier prelytis.xml. Pour debugger votre module d'authentification, slectionner le projet prelytis et cliquer sur Run/Debug as/ Debug on Server Pour packager l'application sous forme d'un WAR avec le module d'authentification spcifique intgr, cliquer sur File/Export, choisir Web/WAR File :
30
1. Authentification
L'authentification est effectue par une faade. Dans le cadre d'une intgration par URL, il est judicieux de dleguer la partie authentification un mcanisme extrieur et commun entre toutes les applications (reverse proxy authentifiant) et de s'appuyer sur l'authentification HTTP (voir RFC2617 [http://tools.ietf.org/html/rfc2617]). Apache2 peut jouer le role de reverse proxy authentifiant : Authentification grce aux modules proposs LDAP, Base de donnes, fichiers, etc. Voir http:// httpd.apache.org/docs/2.2/howto/auth.html Reverse proxy avec les protocoles ajp, http. Voir http://httpd.apache.org/docs/2.2/mod/ mod_proxy.html Du ct de LiveDashBoard, la faade com.prelytis.dashboard.ext.HttpAuthenticationFacade permet de rcuprer l'utilisateur authentifi par HTTP.
2. Trackback
Les URL trackback sont des points d'entres vers certains crans de PRELYTIS LiveDashBoard. Si l'utilisateur n'est pas authentifi, la premire tape est l'authentification de l'utilisateur. L'authentification dpend de la configuration effectue dans prelytis.xml. Dans la configuration par dfaut, l'cran de login est affich. Une fois l'utilisateur authentifi, l'cran demand est affich. Type d'accs Accs au tableau de bord par dfaut Accs au tableau de bord dashboardName Accs au rapport reportName Accs au contrle controlName Accs l'indicateur metricName Accs une session de paramtrage sessionName Url utiliser /trackbackHome.html /trackbackDashboard.html? name=dashboardName /trackbackReport.html?name=reportName /trackbackControl.html? name=controlName /trackbackMetric.html?name=metricName /trackbackParametersList.html? name=sessionName
31
32
3. API Plugin
L'utilisation de Javascript la place d'une page statique, permet n'importe quel intgrateur/diteur tiers de fournir un contenu riche et dynamique (AJAX), compltement en phase avec les exigences du WEB 2.0. Lorsque que le dashboard est affich, le fichier Javascript est charg, et la classe est instancie par le dashboard. Cette classe se voit ajouter plusieurs proprits afin d'enrichir ses possibilits : cration d'un objet partir de la classe (this) affectation de this.ldbDiv affectation de this.ldbName affectation de this.ldbFilter affectation de this.ldbApplication affectation de this.ldbTemplateId affectation de this.ldbBlockId appel de la mthode this.ldbInit()
Finalement, la classe doit implmenter la mthode ldbInit(), afin de dmarrer. this.ldbDiv est le noeud DOM, de la DIV du plugin. this.ldbDiv.id est l'identifiant de la DIV. Tous les autres identifiants d'lments contenus dans la DIV doivent tre de la forme this.ldbDiv.id + ':monId'. this.ldbName est une chane de caractres. this.ldbFilter est un tableau d'objets filtres fournis au plugin. Le filtre est de la forme : this.ldbFilter[0].name this.ldbFilter[0].description this.ldbFilter[0].value this.ldbApplication est l'objet reprsentant l'environnement extrieur du plugin. Il est unique dans la page (et sera donc partag entre plusieurs plugins), et fournit les proprits suivantes : this.ldbApplication.version est une chane de caractre fournissant la version utilise. Cette information sera utile lors des volutions de l'API. this.ldbApplication.document est un objet qui permet de grer les documents LiveDashBoard. this.ldbApplication.document.REPORT_DOCUMENT_TYPE : entier indiquant le type de document rapport. this.ldbApplication.document.DASHBOARD_DOCUMENT_TYPE : entier indiquant le type de document dashboard. this.ldbApplication.document.CONTROL_DOCUMENT_TYPE : entier indiquant le type de document contrle. this.ldbApplication.document.openInDashboard(oid, docType, templateId, blockId) : permet d'ouvrir un document dans un bloc du dashboard. Le "doctype" est une constante dfinie ci-dessus. "l'oid" est l'identifiant du document ouvrir. Le "templateId" et le "blockId" sont l'identifiant du bloc qui recevra le nouveau document. this.ldbApplication.document.filterInDashboard(filters, templateId, blockId) : permet de filtrer un document dans un bloc du dashboard. Le "templateId" et le "blockId" sont l'identifiant du bloc qui recevra le nouveau filtre. this.ldbApplication.document.getInformations() : retourne la liste des pages et blocs du dashboard actuellement chargs dans le navigateur, avec leur description. var info = this.ldbApplication.document.getInformations() info.templates[0].id info.templates[0].blocks[0].id info.templates[0].blocks[0].title this.ldbApplication.infoMessage est un objet qui permet d'afficher un message d'information dans la page HTML, il disparat automatiquement au bout de 3,5 secondes. this.ldbApplication.infoMessage.open(message) o message est la chane afficher. this.ldbApplication.errorMessage est un objet qui permet d'afficher un message d'erreur dans la page HTML, il ne disparat pas automatiquement. this.ldbApplication.errorMessage.open(message) o message est la chane afficher. 33
this.ldbApplication.loadJsUrl(url, parentCallback) est une mthode qui permet de charger un fichier Javascript dans la page, et de garantir que le fichier n'est charg qu'une seule fois dans la page (par exemple si le mme plugin est prsent plusieurs fois dans le mme dashboard). parentCallback() est une fonction qui est appele lorsque le fichier est effectivement charg. this.ldbTemplateId est un entier indiquant l'id de la page du dashboard dans laquelle se trouve le plugin. this.ldbBlockId est un entier indiquant l'id du bloc dans la page du dashboard dans laquelle se trouve le plugin. La page et le bloc forment un identifiant unique du plugin dans un dashboard. Si le plugin n'est pas dans un dashboard, ces deux dernires proprits n'existent pas (typeof this.ldbTemplateId == 'undefined'). De plus, le plugin doit appeler une fonction javascript la fin du fichier, pour s'enregistrer auprs de l'application : ldb.api440.registerJsUrl(URL); o URL est une chane indiquant l'URL relative du fichier (la mme que celle indique dans le paramtrage du plugin).
initialize: function() { }, ldbInit: function() { this.ldbDiv.innerHTML = '<p>Hello world, API version ' + this.ldbApplication.vers var div0 = document.createElement('DIV'); div0.id = this.ldbDiv.id + ':div0'; div0.innerHTML = 'Afficher message'; div0.style.border = '1px solid black'; div0.style.margin = '5px'; div0.style.textAlign = 'center'; div0.style.cursor = 'pointer'; Event.observe(div0, 'click', this._message.bindAsEventListener(this)); this.ldbDiv.appendChild(div0); var div1 = document.createElement('DIV'); div1.id = this.ldbDiv.id + ':div1'; div1.innerHTML = 'Lire le filtre'; div1.style.border = '1px solid black'; div1.style.margin = '5px'; div1.style.textAlign = 'center'; div1.style.cursor = 'pointer'; Event.observe(div1, 'click', this._getFilter.bindAsEventListener(this)); this.ldbDiv.appendChild(div1); var div2 = document.createElement('DIV'); div2.id = this.ldbDiv.id + ':div2'; this.ldbDiv.appendChild(div2); var div3 = document.createElement('DIV'); div3.id = this.ldbDiv.id + ':div3'; div3.innerHTML = 'Lire les infos'; div3.style.border = '1px solid black'; div3.style.margin = '5px'; div3.style.textAlign = 'center';
34
div3.style.cursor = 'pointer'; Event.observe(div3, 'click', this._getInfo.bindAsEventListener(this)); this.ldbDiv.appendChild(div3); var div4 = document.createElement('DIV'); div4.id = this.ldbDiv.id + ':div4'; this.ldbDiv.appendChild(div4); var div5 = document.createElement('DIV'); div5.id = this.ldbDiv.id + ':div5'; div5.innerHTML = 'Filtrer un bloc'; div5.style.border = '1px solid black'; div5.style.margin = '5px'; div5.style.textAlign = 'center'; div5.style.cursor = 'pointer'; Event.observe(div5, 'click', this._filterBlock.bindAsEventListener(this)); this.ldbDiv.appendChild(div5); var div6 = document.createElement('DIV'); div6.id = this.ldbDiv.id + ':div6'; div6.innerHTML = 'Ouvrir un rapport'; div6.style.border = '1px solid black'; div6.style.margin = '5px'; div6.style.textAlign = 'center'; div6.style.cursor = 'pointer'; Event.observe(div6, 'click', this._openBlock.bindAsEventListener(this)); this.ldbDiv.appendChild(div6);
}, _message: function(e) { this.ldbApplication.infoMessage.open('Hello world from the plugin'); }, _openBlock: function(e) { var doctype = this.ldbApplication.document.REPORT_DOCUMENT_TYPE; this.ldbApplication.document.openInDashboard(156, doctype, 0, 2); }, _filterBlock: function(e) { var filters = new Array(); filters[0] = new Object(); filters[0].name = 'area'; filters[0].value = 'Americas'; this.ldbApplication.document.filterInDashboard(filters, 0, 1); }, _getFilter: function(e) { var ul, li; if (<emphasis role="b">this.ldbFilter</emphasis> != null) { var div = $(this.ldbDiv.id + ':div2'); div.innerHTML = ''; ul = document.createElement('UL'); for (var i = 0; i < this.ldbFilter.length; i++) if (this.ldbFilter[i] != null) { var filter = this.ldbFilter[i]; li = document.createElement('LI'); li.innerHTML = i + ': ' + filter.name + ' ' + filter.description + ' ' + fi ul.appendChild(li); } div.appendChild(ul); }
35
}, _getInfo: function(e) { var ul, li; var info = this.ldbApplication.document.getInformations(); if (info != null) { var div = $(this.ldbDiv.id + ':div4'); div.innerHTML = ''; ul = document.createElement('UL'); for (var i = 0; i < info.templates.length; i++) if (info.templates[i] != null) { var t = info.templates[i]; for (var j = 0; j < t.blocks.length; j++) if (t.blocks[j] != null) { var b = t.blocks[j]; if (b.title != null) { li = document.createElement('LI'); li.innerHTML = 't' + t.id + ':b' + b.id + ' - ' + b.type + ' - ' + b. ul.appendChild(li); } } } div.appendChild(ul); } } }); ldb.api440.registerJsUrl('static/test.js'); Le rsultat de ce plugin est visible ci-dessous
36