Skip to content

Config

Le fichier de configuration config.xml permet de définir les paramètres de configuration de l'application. Il s'agit d'un fichier XML qui doit se trouver dans le dossier de base de l'application et structuré selon le principe suivant:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<config>
    <section1>
        <property1>value section1.property1</property1>
        <property2>value section1.property2</property2>
        <!-- ... -->
    </section1>
    <section2>
        <property1>value section2.property1</property1>
        <property2>value section2.property2</property2>
        <!-- ... -->
    </section2>
    <!-- ... -->
</config>

Encoding

Le prolog du ficihier XMl ci-dessus déclare un charset utf-8. Ce n'est pas une obligation, mais Ewt recommande d'utiliser ce charset dans tout le projet, en particulier au niveau des scripts.

Le fichier est subdivisé en sections, dans lesquelles sont définies des propriétés. L'ordre des sections et des propriétés n'a pas d'importance.

Les valeurs des propriétés peuvent être notées en clair, sous forme de valeur chiffrée (dans ce cas on indiquera que la valeur est chiffrée au moyen d'un attribut encrypted="true") ou sous forme de référence. Par exemple il est possible de reprendre la valeur d'une variable d'environnement au moyen de la syntaxe ${env:MA_VARIABLE}.

Valeurs de propriétés

Ewt autorise l'usage de variables dans les valeurs de propriétés. Un exemple est donné à la fin de ce document pour l'entrée admin.instanceName: la valeur

<instanceName>${env:INSTANCENAME}</instanceName>

fait ici référence à une variable d'environnement. Il est également possible de référencer des propriétés systèmes ou d'autres types de valeurs. Il est aussi possible de combiner différentes valeurs, comme x${env:aaa}y${sys:bbb}z.

Le chapitre variables donne plusieurs exemples de variables.

Valeurs chiffrées

Les propriétés peuvent être chiffrées. Dans ce cas, on indiquera que la valeur est chiffrée au moyen de l'attribut encrypted="true". Pour traiter les valeurs chiffrées, Ewt a besoin d'une clé de chiffrement. Celle-ci est à définir via la variable d'environnement EWT_ENCRYPT_PASSWORD.

Générer une valeur chiffrée

La manière la plus simple de générer une valeur chiffrée est de le faire au moyen d'un script. La ligne de commande suivante effectuera le chiffrement d'une valeur donnée:

$cipher.encrypt("mavaleur", { password: "${env:EWT_ENCRYPT_PASSWORD}" });

Valeurs publiques

Non implémenté

Cette option n'est pas supportée dans la version actuelle du moteur

Les éléments marqués comme publiques sont repris dans l'arbre de sortie généré par le moteur, de sorte qu'ils sont exploitables par la feuille de style de transformation.

Pour spécifier qu'un élément est public, on lui définit un attribut public="true". L'élément et ses fils sont alors repris intégralement dans l'arbre, à l'exception de ceux pour lesquels un attribut public="false" serait spécifié.

Section admin

La section admin contient une série de propriétés globales à l'application.

applicationName

Nom de l'application. En réalité cet élément ne joue aucun rôle. Il n'est pas obligatoire et est juste repris tel quel dans l'arbre de sortie pour permettre à la feuille de style de l'afficher.

documentMode

Indique le mode de gestion de dossiers. Les valeurs possibles sont single (par défaut) ou multi.

single

En mode single le moteur ne conserve qu'un seul dossier ouvert à la fois par session. Cela signifie que le moteur ferme automatiquement tout dossier ouvert lors de l'ouverture ou de la création de dossier.

Exceptions au mode single

Attention, le fait d'activer le mode single ne signifie pas que le moteur fonctionne exclusivement en mode mono-dossier. Certaines parties du moteur continuent de supporter un mode multi-dossier, indépendamment de la valeur de documentMode. C'est notamment le cas des scripts: l'ouverture d'un dossier depuis un script (avec $doc.open ou $doc.create) n'entraîne pas la fermeture des autres dossiers déjà ouverts. Ces derniers restent ouverts. Il y a plusieurs raisons à cela:

  • Optimisation : Il arrive fréquemment qu'un script doivent créer ou modifier un dossier lié au dossier courant, sans pour autant vouloir faire basculer l'utilisateur sur ce nouveau dossier. Pour éviter de fermer/ouvrir plusieurs fois un même dossier, le script ne ferme les dossiers que lorsque ceux-ci sont explicitement fermés par le script.

  • Conservation du contexte lors des appels REST : Il s'agit d'une condition indispensable au bon fonctionnement des applications. Pour comprendre, il faut se rappeler que dans Ewt, les éléments contextualisables (c'est-à-dire le dossier, ses groupes, ses champs, etc. qui possèdent un contexte) sont référencés dans l'interface utilisateur au moyen d'un contexte codé. Il s'agit d'un hash généré à partir de l'élément lui-même, de la session ainsi que d'un sel généré aléatoirement (peut varier selon le niveau de sécurité souhaité dans l'application). L'utilisation de contexte hashé sécurise les paramètres et évite que l'on puisse falsifier des noms d'éléments. Le hash en question est généré à l'ouverture du dossier et perdu à sa fermeture. Du fait de la partie aléaoire qui le compose, le hash ne peut pas être reconstruit a posteriori.

    Prenons alors le cas d'une page Web affichant un dossier D0 et qui lance l'exécution d'un script au moyen d'un appel REST. Le script invoqué crée un dossier lié D1, le modifie, le ferme puis rouvre à nouveau le dossier D0. Si la création du dossier D1 entraînait la fermeture du dossier D0, cela aurait pour effet de retirer de la session tous les hash du dossier D0. Ces hash seraient alors recréés à la réouverture de D0. L'interface utilisateur ne serait alors plus synchrone avec la session Ewt car les hash contenus dans les noms de champs HTML de la page Web ne correspondraient plus aux hash référencés au niveau de la session. Le dossier ne serait alors plus modifiable. Pour éviter cette situation, le moteur ne ferme pas automatiquement le dossier D0 à la création de D1. Les hash de D0 ne sont ainsi pas perdus. Cela signifie que malgré le mode single, le moteur est capable de conserver en mémoire plusieurs dossiers ouverts simultanément. On notera également au passage que la réouverture de D0 en fin de traitement n'est pas nécessaire étant donné que D0 n'a jamais été explicitement fermé par le script. D'ailleurs en mode dev, le moteur signalera un avertissement pour indique que le dossier D0 est déjà ouvert.

Lorsque le mode single est activé et que plusieurs dossiers se retrouvent ouverts à la fin de l'exécution du script, le moteur se charge alors de fermer les dossiers qui sont de trop : il ne conserve que le dossier qui a été ouvert en dernier.

multi
En mode multi, le moteur peut conserver plusieurs dossiers en session et fournit les données de tous ces dossiers dans l'arbre de sortie

Le mode de gestion de dossiers a un impact important sur l'application, tant en au niveau de l'output qu'au niveau du fonctionnement interne. La note ci-dessous donne plus de détails sur l'impact de ce paramètre au niveau du fonctionnement du moteur.

Incidence de documentMode sur le fonctionnement du moteur

La principale différence que l'on peut noter entre les modes single et multi se situe au niveau de l'arbre de sortie généré par le moteur. En mode single, cet output ne fournira les données que d'un seul dossier, alors qu'en mode multi il reprend les données de tous les dossiers ouverts. L'application devra en tenir compte lorsque la construction des écrans.

Le format de l'output n'est en réalité que l'effet final du paramètre paramètre sur le fonctionnement du moteur, mais son incidence ne se limite pas seulement à cela. Certains composants du moteur fonctionnent différemment selon le mode de document. Par exemple, la notification gen-output s'applique dans le contexte du dossier courant en mode single lorsqu'un dossier est ouvert, qu'elle n'a aucun contexte dans le mode multi.

transientObjectNamePrefix

Préfixe des champs définis par la feuille de style et que le moteur doit reprendre en sortie en tant qu'objets transients. Le préfixe par défaut est SESSION:. Concrètement cela signifie que tous les champs obtenus d'un formulaire HTML et donc le nom est préfixé au moyen de SESSION: seront considérés comme objets transients.

Objet transient

Un objet transient (ou objet transitoire) est un objet qui est enregistré provisoirement au niveau du thread que le moteur est en train de gérer, mais pas au niveau de la session utilisateur. Cela signifie que les objets transients "transitent" par le moteur Ewt, mais ne sont pas stockés dans la session.

Les objets transients se distinguent des objets persistents qui, eux, sont conservés dans la session utilisateur.

Les objets transients sont plutôt destinés à véhiculer des informations utiles à l'interface utilisateur alors que les objets persistents sont plutôt utiles à traiter des informations utiles à l'application. Notons enfin que les objets persistents peuvent être secrets, c'est-à-dire que leur valeur n'est jamais affichée dans l'arbre de sortie. Les objets transients n'ont pas cette propriété.

tupleIdForm

Forme par défaut à utiliser pour les identifiants de dossier/tuple. Les valeurs possibles sont int, bigint, uuid ou snowflake. La valeur par défaut est uuid.

Il est possible de surcharger cette valeur au niveau des définitions de champs dans la descript via l'attribut idform. Voir la documentation relative aux champs de la descript.

À noter que le type doit être adapté au SGBD utilisé. Par exemple SQLite ne supporte pas bigint.

enableScheduler

Flag true/false indiquant si l'application utilise un scheduler.

La valeur par défaut est false.

Démarrage automatique

Il est recommandé d'activer le démarrage automatique d'une application qui utilise un scheduler afin que celui-ci puisse démarrer dès l'activation d'une instance.

Pour ce faire, il faut déclarer l'application dans la liste des auto-load-applications au niveau du fichier bootstrap.

instanceName

Nom de l'instance utilisée pour répartir les tâches du scheduler.

runMode

Mode d'exécution de l'application. La propriété peut prendre les valeurs suivantes:

  • prod: mode prévu pour le fonctionnement en production
  • test: mode prévu pour les tests
  • dev: mode prévu pour le développement (dans ce mode, l'application surveille automatiquement les mises à jour de fichiers de script et les recharge lorsque cela est nécessaire; l'arbre de sortie contient également des éléments de debug pour aider à identifier les sources de problèmes)

La valeur par défaut est prod.

debuggerPort

Port d'écoute du debugger. Le debugger utilise un socket réseau pour la communication entre un outil de debugging externe et Ewt via le protocole DAP. Le socket n'est ouvert que si l'application est en mode dev (voir runMode) et que le port est strictement supérieur à 0.

debuggerAddress

Adresse IP de bind pour le debugger.

Cette propriété n'est pas obligatoire lorsque l'on souhaite activer le debugger. Elle permet de filtrer les accès par IP.

dumpOutput

Cette propriété sert essentiellement au debug. Elle permet de forcer le moteur à enregistrer l'arbre xml de sortie dans un fichier d'output (fichier _output-web.xml dans le cas du servlet web, _output-pdf.xml en cas d'impression PDF, etc.). La propriété peut être soit une valeur true/false, soit un path (défini du dur ou au moyen de variables).

Lorsque la propriété est false, aucun fichier n'est généré.

Lorsque la propriété est true, le moteur enregistre l'output dans le dossier de travail de l'application. À noter que le résultat est le même si on utilise la valeur {$var:workDirectory}.

Lorsque la propriété est un path, le fichier est enregistré à l'endroit indiqué. Le path doit désigner un répertoire. Il doit exister et la jvm doit disposer des droits d'écriture dans le dossier. L'exemple donné plus bas montre comment utiliser une variable pour désigner le path.

La valeur par défaut est false.

Multi threading et multi applications

Lorsqu'on indique un path, il faut garder à l'esprit que le moteur d'application est généralement utilisé dans un contexte multithread. Cela signifie qu'un thread peut écrire des données dans le fichier d'output et un autre thread peut remplacer ce contenu juste ensuite. Il est donc possible que le contenu du fichier ne corresponde pas à ce que l'on s'attend à avoir.

Il faut également penser que plusieurs applications peuvent tourner en parallèle. Si chaque application référence le même path, le fichier d'output sera écrasé par chaque application. Il est donc recommandé d'utiliser un path spécifique à l'application (ou d'utiliser la valeur true qui désigne le dossier de travail de l'application).

cipherPassword

Mot de passe par défaut pour le chiffrement/déchiffrement (voir méthodes $cipher.encrypt et $cipher.decrypt). En clair, cette propriété remplace le second paramètre des méthodes ci-dessus lorsque celui-ci n'est pas explicitement indiqué dans l'appel.

Dans l'exemple donné à la fin de ce document, la valeur passé à la propriété admin.cipherPassword est chiffrée. C'est en fait le cas de la plupart des données qui représentent des credentials ou des clés. Pour générer la valeur chiffrée, on peut utiliser l'instruction de script suivante:

1
$cipher.encrypt("mavaleur", { password: $sys.getEnv("EWT_ENCRYPT_PASSWORD") });

sessionTTL

Durée de vie des sessions, en minutes. Ce TTL désigne le temps durant lequel les sessions non rafraîchies restent dans le cache si l'utilisateur n'effectue aucune action (aucun post). Lorsqu'une session expire, les locks de tous les dossiers de la session sont automatiquement libérés. Les durées de vie des sessions sont réinitialisées si l'utilisateur effectue une action.

Un TTL par défaut de 60 (soit 1 heure) est appliqué si sessionTTL et sessionEOL ne sont pas définis.

Remarque 1

Les sessions dont il est question ici sont les sessions Ewt, c'est-à-dire les sessions créées par Ewt lorsqu'il reçoit une requête de type GET.

Il ne faut pas confondre avec les sessions HTTP qui, elles, sont gérées par le serveur d'application et qui sont créées lorsque l'utilisateur se connecte pour la première fois depuis un client. Le TTL de ces dernières peut être configuré à l'aide de l'entrée

<session-config>
    <session-timeout>30</session-timeout>
</session-config>

du web.xml. Cette valeur exprime la durée d'inactivité maximale, en minutes. Cela signifie que la session HTTP est automatiquement perdue lorsque l'utilisateur est inactif pendant plus longtemps que la durée indiquée. La session HTTP est prolongée automatiquement lorsque l'utilisateur envoie une requête au serveur.

Ewt est configuré pour lier les sessions Ewt aux sessions HTTP depuis lesquelles elles sont créées. Cela signifie que les sessions Ewt créées depuis une sessions HTTP sont automatiquement supprimées lorsque la session HTTP expire ou est terminé (par exemple lors du logout de l'utilisateur).

Remarque 2

La durée de vie des sessions Ewt peut avoir un impact sur la quantité de mémoire que le moteur devra allouer, il n'est donc pas conseillé de spécifier des TTL trop grands.

sessionEOL

Délai d'expiration absolu des sessions. Si définie, cette propriété permet d'indiquer à quel(s) moment(s) les sessions doivent expirer, ainsi toutes les sessions existantes à l'heure indiquée (ou l'une des heures indiquées) sont automatiquement supprimées. L'heure doit être définie selon le format hh:mm:ss ou hh:mm.

Pour indiquer plusieurs heures, utiliser une virgule ou un point-virgule (p.ex "03:00:00;12:30").

Veuillez tenir compte de la remarque 1 de la propriété sessionTTL.

sessionRenewable

Flag indiquant si une session peut être renouvelée (ou étendue). Par défaut, les sessions expirées sont perdues. Il est toutefois possible d'autoriser une session à être étendue. Cela signifie que le délai de fin de vie de la session est reporté d'un cycle (en fonction des paramètres sessionTTL et/ou sessionEOL).

Pour qu'une session soit étendue, il faut qu'elle puisse être retrouvée, ce qui n'est pas le cas par défaut. Il est donc nécessaire d'activer le mode failover pour que les sessions soient stockées en base de données.

failoverMode

Mode de failover souhaité sur l'application. Le but du failover est d'assurer une continuité de service lorsqu'une instance est stoppée (de manière volontaire ou non). Le failover permet de récupérer les sessions sur une autre instance à la volée.

Le failover permet également de prolonger une session au-delà de sa durée de vie normale. Voir propriété sessionRenewable.

Concrètement, le paramètre active un mode dans lequel le moteur sérialise les sessions et les sauvegarde en vue de pouvoir les restaurer en cas de besoin. Le fait d'activer un mode de failover peut avoir un impact sur les performances de l'application, c'est pourquoi il est conseillé de ne l'activer que lorsqu'un haut niveau de service est souhaité.

La propriété peut prendre l'une des valeurs suivantes:

default

L'application gère le failover au moyen d'un mode basique. Dans ce mode, génère une valeur json décrivant les objets gérés par la session. En cas de failover, le moteur rechargera alors les données de dossier depuis le support de failover (voir failoverSupport) afin de reconstruire le dossier.

Ce mode de failover est activé par défaut. Il offre un bon compromis en termes de fonctionnement et de ressources nécessaires à sa mise en oeuvre. Il ne permet cependant pas de conserver le lock sur les dossiers lorsqu'un rattrapage de session doit être effectué.

none
Indique explicitement à l'application de ne pas activer le failover.
full
Dans ce mode, la session est intégralement sérialisée. Cela signifie que les dossiers, les champs de dossiers, les objets persistents, etc. sont sérialisés et peuvent ainsi être restaurés en cas de failover. Ce mode nécessite davantage de traitement et de stockage au niveau du support utilisé.

Toute valeur qui diffère de celles ci-dessus sera ignorée et n'activera pas le failover.

failoverSupport

Support pour l'implémentation du failover. Cette propriété permet d'indiquer où le moteur doit stocker les données nécessaires au failover, lorsque celui-ci est activé (voir failoverMode).

La propriété peut prendre l'une des valeurs suivantes:

database
Active le failover en utilisant la base de données comme support pour enregistrer les sessions. Le moteur utilise alors la table ewt_sessions pour stocker les informations de sessions.
request - Ce mode n'est pas supporté dans la version actuelle.
Active le failover en utilisant la requête HTTP pour véhiculer les infos de sessions de façon chiffrée.

Le mode par défaut est database.

lockingColName

Nom de colonne par défaut utilisé pour permettre à Ewt de gérer le locking. Si la propriété n'est pas définie, le moteur utilise le nom _locking.

Important: si vous utilisez une base de données Oracle, vous devez impérativement définir cette propriété car Oracle n'autorise pas les noms de colonnes qui commencent par un "_".

lockingTTL

Durée de vie des lock pessimistes, en minutes. Fonctionne selon le même principe sessionTTL, mais appliqué ici aux locks de tuples. Si défini, les locks qui dépassent la durée de vie limite sont automatiquement supprimés de la table ewt_locking.

Un TTL par défaut de 1440 (soit 24 heures) est appliqué si lockingTTL et lockingEOL ne sont pas définis. Si les deux propriétés sont spécifiées, la durée de vie des locks sera le max des deux. Autrement dit, lockingTTL désigne une durée de lock incompressible et lockingEOL est l'heure à laquelle les locks sont libérés une fois cette durée de vie expirée.

Remarque

Il est possible d'indiquer une valeur négative ou nulle pour signifier que l'on ne souhaite pas forcer d'expiration. Si également aucune valeur n'est définie pour la propriété lockingEOL, l'application ne se chargera pas de libérer les locks.

lockingEOL

Délai d'expiration absolu des locks pessimistes. Si définie, cette propriété permet d'indiquer à quel(s) moment(s) les locks doivent être levés. Ainsi tous les dossiers verrouillés sont automatiquement déverrouillés. L'heure doit être définie selon le format hh:mm:ss ou hh:mm.

Pour indiquer plusieurs heures, utiliser une virgule ou un point-virgule (p.ex "03:00:00;12:30").

Voir lockingTTL.

enableTrash

Flag true/false indiquant si l'application utilise la corbeille.

La valeur par défaut est false.

trashTTL

Durée de conservation des éléments dans la corbeille, en millisecondes. La valeur par défaut est 2592000, ce qui correspond à 30 jours. Les éléments sont automatiquement supprimés après cette durée.

Voir également la notification trash-clean

enableHistory

Flag true/false indiquant si l'application doit journaliser les actions des utilisateurs. Lorsque le flag est activé, le moteur inscrit toutes les actions dans la table ewt_history. Cette dernière enregistre notamment les éléments suivants:

  • identifiant de l'utilisateur (principal)
  • date et heure
  • servlet invoqué
  • méthode utilisée pour la requête ("get" ou "post")
  • action
  • paramètres de l'action
  • nom de modèle
  • identifiant de dossier
  • nom de groupe
  • identifiant de tuple
  • nom de champ
  • ancienne valeur brute du champ
  • nouvelle valeur brute du champ
  • ancien libellé du champ (= libellé affiché en remplacement de la valeur dans le cas des listes d'options par exemple)
  • nouveau libellé du champ
  • commentaires additionnels

Section database

verbose

Active le mode de debug des requêtes SQL. Les valeurs possibles sont:

  • false : désactive les traces; c'est le mode par défaut
  • trace : affiche les requêtes en tant que traces
  • debug ou true : affiche les requêtes en tant que debug
  • info : affiche les requêtes en tant que info
  • warn : affiche les requêtes en tant que warn
  • error : affiche les requêtes en tant que error

maxConnectionAttempts

Nombre de tentatives de reconnexions au serveur de base de données en cas de perte de connexion. La valeur par défaut est 4. Chaque tentative de reconnexion est espacée d'un délai équivalent au timeout défini pour le pool (par défaut défini à 30 secondes, mais modifiable via la propriété connectionTimeout du pool).

defaultConnectionConfig

Nom de la connexion par défaut. La valeur doit référencer l'attribut name d'un nœud <connection>. À noter qu'on peut se passer de cette propriété en définissant une entrée <connection> sans attribut name.

connection

Sous-section de paramètres de connexion à la base de données. L'élément <connection> peut est défini plusieurs fois, mais dans ce cas il faut nommer les connexions au moyen d'un attribut name et indiquer quelle est la connexion par défaut utilisée par l'application via la propriété defaultConnectionConfig.

engine ou connection/engine

Type de moteur utilisé. Les valeurs possibles sont:

  • postgres
  • mssql
  • mysql
  • mariadb
  • oracle
  • hsqldb
  • sqlite

driver ou connection/driver

Classe implémentant le driver JDBC.

url ou connection/url

URL de connexion à la base de données.

property ou connection/property

Propriété(s) supplémentaire à passer au driver. L'élément peut être spécifié plusieurs fois pour passer plusieurs propriétés. Les propriétés doivent être notées selon la syntaxe key=value.

username ou connection/username

Nom d'utilisateur à utiliser pour se connecter à la base de données.

password ou connection/password

Mot de passe associé au nom d'utilisateur.

poolProperty ou connection/poolProperty

Propriété du pool de connexion.

Ewt s'appuie sur le pool HikariCP. Les propriétés de pool indiquées sont donc destinées à ce dernier. Elles doivent être notées selon la syntaxe key=value.

L'élément peut être répété si on souhaite spécifier plusieurs propriétés.

encoding ou connection/encoding

Encoding à utiliser par le driver.

Section email

emailSupport

Adresse e-mail de support. Il s'agit de l'adresse par défaut vers laquelle sont redirigés les demandes de support (voir $mail.genLinkMailtoSupport).

defaultSmtpConfig

Nom de la config smtp par défaut. À noter qu'on pourrait aussi se passer de cet élément et redéfinir une entrée <smtp> unique, sans attribut name.

smtp

Sous-section de paramètres de connexion à un serveur smtp. L'élément <smtp> peut est défini plusieurs fois, mais dans ce cas il faut nommer les connexions au moyen d'un attribut name et indiquer quelle est la connexion par défaut utilisée par l'application via la propriété defaultSmtpConfig.

host ou smtp/host

URL du serveur smtp.

port ou smtp/port

Port à utiliser pour se connecter au serveur smtp.

username ou smtp/username

Nom d'utilisateur du serveur smtp.

password ou smtp/password

Mot de passe associé au nom d'utilisateur.

starttls ou smtp/starttls

Paramètre true/false indiquant si on souhaite activer STARTTLS.

headers ou smtp/headers

Sous-arbre dans lequel on peut spécifier les headers d'e-mails.

headers/header ou smtp/headers/header

Header d'e-mail. Le nom du header est à passer via l'attribut name.

mailbox

Sous-section de paramètre de connexion à un serveur pop ou imap. La méthode $mail.read s'appuie sur ces derniers pour se connecter à une boîte mail.

type

Type de boîte mail. Les types reconnus sont "pop3", "pop3s", "imap" et "imaps".

host

URL du serveur

port

Port de connexion au serveur

username

Nom d'utilisateur pour l'authentification sur le serveur

password

Mot de passe à utiliser pour l'authentification sur le serveur

security

Type de sécurité. Peut prendre une des valeurs "none", "starttls" ou "ssl" (ce dernier est mis pour le mode "ssl/tls")

Section styles

Liste des styles disponibles avec indication de la feuille de style associée. Dans le reste de l'application, à l'exception éventuellement des scripts, on ne fera jamais référence directement au fichier xsl (la feuille de style), mais uniquement au nom du style qui l'exploite, c.-à-d. à la valeur mise dans l'attribut name.

style

Déclaration de style. L'élément doit être défini pour chaque feuille de style que l'on souhaite rendre utilisable par le moteur. Chaque entrée devra contenir un nom (attribut name) et référencer le fichier xsl.

defaultStyle

Style par défaut. Peut être vide ou indéfini si l'on souhaite une application entièrement pilotée par les scripts ou une application qui n'est que pur service web.

transformerFactory

Classe du transformerFactory à utiliser. La liste des valeurs possibles dépend des jar présents dans les libs. Voici quelques valeurs possibles:

  • org.apache.xalan.processor.TransformerFactoryImpl
  • net.sf.saxon.TransformerFactoryImpl
  • com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl

Un patch spécial a été mis en place pour corriger le problème de traitement des emoji par xalan 2.7.1 et suiv. Il est donc recommandé d'utiliser les libs xalan-2.7.3.2 et serializer-2.7.3.2 (disponibles sur [https://github.com/epilogic-ch/xalan-java/releases/tag/2.7.3.2]https://github.com/epilogic-ch/xalan-java/releases/tag/2.7.3.2)).

Section locale

Cette section permet de forcer certains éléments relatifs à la locale.

defaultLocale

Locale à forcer au niveau des threads. Lorsque cette option est définie, le moteur ne tient plus compte de la locale des clients mais impose la locale indiquée.

decimalSeparator

Séparateur de décimales à utiliser pour les nombres. Lorsque cette option est définie, le moteur force l'utilisation du séparateur à la place du séparateur standard associé à la locale.

groupingSeparator

Séparateur de milliers à utiliser pour les nombres. Lorsque cette option est définie, le moteur force l'utilisation du séparateur à la place du séparateur standard associé à la locale.

Section bundles

Dans cette section, on indique la liste des bundles de langues à reprendre dans l'arbre de sortie pour les différents styles. Ainsi, la feuille de style disposera des libellés définis dans ces bundles lors de la transformation. Il est possible de spécifier plusieurs bundles par style en les séparant par une virgule (par exemple pour gérer le cas où un style utilise une stylesheet qui a elle-même des imports d'autres stylesheets)

Il n'est pas nécessaire de définir de bundles dans le cas où la feuille de style utilise des libellés hardcodés.

defaultBundles

Liste des bundles repris systématiquement dans l'arbre de sortie. Il est possible de spécifier plusieurs bundles dans la valeur, en utilisant la notation comma-separated.

defaultLocale

Nom de la locale par défaut à utiliser lorsqu'un client demande des ressources dans une locale que l'application ne supporte pas et qu'aucun bundle par défaut n'est fourni.

Rôle de la propriété bundles.defaultLocale

La gestion des bundles de ressources dans Ewt s'appuie sur les fonctionnalités de java. Ce dernier recherche la ressource la plus adéquate pour la locale attendue. La mécanique utilisée pour déterminer la ressource à utiliser est largement documentée en ligne. En bref, les fichiers de ressources sont censés être organisés de façon hiérarchique. Par exemple le fichier de base est censé contenir les libellés communs à toutes les locales, le fichier ayant le suffixe "fr" contient les libellés propres au français et le fichier "fr_CH" contient les particularités au français de Suisse Romande.

Sur une application multilingue, il ne faut pas chercher à intégrer à la version de base les libellés d'une langue en particulier. Le fichier doit contenir des libellés communs à toutes les langues. Pour illustrer la conséquence d'un mauvais usage de la variante de base, prenons le cas suivant.

Prenons par exemple une JVM configurée avec une locale par défaut "en". Le sous-dossier i18n de l'application contient des fichiers descript.properties (dans lequel on aurait eu la mauvaise idée de saisir des libellés pour le français) et descript_en.properties (libellés en anglais).

Si une requête demande des libellés pour la locale "fr_CH", l'interface affichera des libellés en anglais !!! Cela vient du fait que java fait passer le fichier de ressources correspondant à la locale par défaut avant le fichier de ressources de base.

Pour solutionner le problème, il suffit de ne pas utiliser de variante de base descript.properties. À la place, on aura uniquement des variantes localisées (descript_fr.properties, descript_en.properties, etc.). L'absence de version de base présente toutefois un risque : si l'application contient des fichiers de langues pour le français et l'anglais uniquement, une requête qui demande des libellés en allemand générerait une exception (ressource manquante).

C'est là qu'intervient la propriété bundles.defaultLocale : elle permet d'indiquer vers quelle locale l'application doit se rabattre dans ce cas. Il faut bien évidemment que la langue indiquée existe au niveau des langues disponibles dans le sous-dossier i18n.

descriptBundle

Nom du bundle contenant les libellés des éléments décrits dans la descript. Par défaut, Ewt s'appuie sur un bundle language.

style

Élément permettant d'indiquer les bundles à reprendre dans l'arbre de sortie en fonction du style utilisé.

Pour chaque élément <style>, on indiquera le nom du style en question via l'attribut name et le nom du ou des bundles à reprendre au niveau de la valeur.

Section notifications

Définition des scripts à appeler en fonction des notifications générées par le moteur. La section peut contenir 0 ou n entrées <notification>.

Veuillez vous reporter au chapitre Notification pour avoir plus d'élément sur le fonctionnement de ces dernières.

notification

Déclare une règle de notification. Une notification doit posséder un nom (attribut name) décrivant le type de notification, et une valeur qui correspond à un nom de script à appeler.

Les valeurs possibles pour l'attribut name sont décrites dans le chapitre relatif aux notifications.

Les noms de notifications peuvent porter un suffixe qui indique quand elles doivent s'exécuter. Typiquement, on indiquera un suffixe :before pour indiquer que la notification doit être appelée avant que l'événement ne se produise, ou un suffixe :after pour indiquer que la notification est à faire après l'événement. Par défaut, les notifications sont envoyées après un événement de type création, ajout ou ouverture, et avant un événement de type suppression ou fermeture. Le script appelé via une notification a la possibilité d'interrompre ou d'annuler l'action.

Les scripts appelés peuvent obtenir des infos sur la notification via la variable $notification. Il est possible de spécifier plusieurs scripts pour un événement (notation comma-separated), par exemple:

<notification name="doc-change">onDocChange,calcResume</notification>

Section security

Règles de sécurité. Par défaut les règles de sécurité sont activées, les propriétés définies dans cette section permettent de les court-circuiter.

publishAllScriptsAsService

Indique que n'importe quel script de l'application peut être invoqué en tant que service, c'est-à-dire appelé par REST ou par SOAP.

Par défaut l'option n'est pas active. Cela signifie que les scripts ne peuvent pas être démarrés par service, sauf s'ils possèdent une annotation @accept qui définit les conditions d'exécution du script. L'option publishAllScriptsAsService permet de lever cette sécurité.

allowBareContextInAction

Certaines actions s'appuient sur un contexte. C'est par exemple le cas de l'action delete qui attend en paramètre le nom du modèle et le numéro du dossier à supprimer. Chaque action permet d'indiquer ces éléments de deux façons:

  1. soit explicitement avec des paramètres modelName, docId, groupName, tupleId et fieldName
  2. soit implicitement avec une référence de contexte; dans ce cas, il s'agit d'une valeur hash générée par le moteur et qui représente le contexte.

Par défaut, seule la seconde variante ci-dessus est permise pour les actions suivantes:

  • addTuple
  • arrange
  • clone
  • close
  • delete
  • delTuple
  • setState
  • setView

En effet, cette notation évite que des identifiants de dossiers ne transitent en clair par le formulaire HTML. À noter que les actions create et open ne sont pas concernées, car ces actions portent sur des dossiers qui ne sont pas encore ouverts dans la session, et qui n'ont par conséquence pas de contexte anonymisé.

Il est toutefois possible de demander au moteur d'autoriser les paramètres explicites en définissant la propriété allowBareContextInAction à true. Cela signifie que les méthodes mentionnées plus haut ne signaleront pas d'erreur si elles sont invoquées avec des paramètres en clair.

La propriété autorise un attribut name qui permet de spécifier le nom de l'action sur laquelle porte la propriété. Ainsi par exemple la propriété <allowBareContextInAction name="addTuple">true</allowBareContextInAction> autorise l'utilisation de modelName pour l'action addTuple uniquement.

Pour désactiver l'identification par contexte sur d'autres actions, il suffit de répéter plusieurs fois la balise allowBareContextInAction, en spécifiant à chaque fois le nom de l'action via l'attribut name.

ignoreCSRF

Ce flag permet de désactiver la sécurité contre les attaques CSRF. Le moteur implémente un mécanisme de protection contre CSRF et par défaut il est activé. Il peut toutefois arriver pour de petites applications en local que l'on souhaite désactiver ce mécanisme, bien que cela ne soit pas recommandé.

Le chapitre Bonnes pratiques décrit le principe d'attaque CSRF et la solution implémentée dans Ewt pour s'en protéger.

ignoreReferer

Ce flag permet de désactiver le contrôle du header Referer des requêtes reçues par le serveur.

La valeur prendre plusieurs formes:

  • true : désactive tous les checks sur le referer
  • host : désactive uniquement le check du hostname
  • port : désactive uniquement le check du port

Il est possible de combiner host et port en les séparant par une virgule. Ainsi les valeurs host,port ou port,host reviennent au même que la valeur true.

Toute autre valeur est ignorée.

Section auth

L'authentification et l'autorisation peut être gérées de deux façons sur une application Ewt:

  1. Par défaut le moteur Ewt délègue la gestion de l'authentification et des autorisations au serveur d'applications (Tomcat, JBoss, etc.) sur lequel il est déployé. Dans ce cas, la section auth n'a pas besoin d'être spécifiée.
  2. Ewt peut prendre la main pour gérer la partie authentification et autorisation. Dans ce cas, la section auth doit être définie et le fichier web.xml de la web application doit être adaptée en conséquence. Une version du WAR pré-configuré peut être générée à partir des sources du moteur.

    Dans cette version, les éléments relatifs aux contraintes de sécurité (<security-constraint>), à la méthode d'authentification (<login-config>) et aux rôles (<security-role>) sont retirés et deux filtres sont ajoutés pour prendre en charge les aspects de sécurité:

    <filter>
        <filter-name>EwtAuthFilter</filter-name>
        <filter-class>org.pac4j.jee.filter.SecurityFilter</filter-class>
        <init-param>
            <param-name>configFactory</param-name>
            <param-value>ch.epilogic.ewt.auth.EwtAuthConfig</param-value>
        </init-param>
        <init-param>
            <param-name>authorizers</param-name>
            <param-value>ewt-application-roles</param-value>
        </init-param>
    </filter>
    
    <filter>
        <filter-name>EwtAuthCallback</filter-name>
        <filter-class>org.pac4j.jee.filter.CallbackFilter</filter-class>
        <init-param>
            <param-name>defaultUrl</param-name>
            <param-value>/</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>EwtAuthFilter</filter-name>
        <url-pattern>/web/*</url-pattern>
        <url-pattern>/rest/*</url-pattern>
        <url-pattern>/soap/*</url-pattern>
        <url-pattern>/data/*</url-pattern>
    </filter-mapping>
    
    <filter-mapping>
        <filter-name>EwtAuthCallback</filter-name>
        <url-pattern>/auth</url-pattern>
    </filter-mapping>
    

Section websocket

Paramètres de configuration des websockets fournis par l'application.

maxTextMessageBufferSize

Longueur maximale des messages envoyés par WebSocket, en bytes. Par défaut, la longueur max est de 8192 bytes.

La valeur maximale possible pour cette propriété est 2147483647 (2GB). Une valeur supérieure sera plafonnée à 2GB.

maxBinaryMessageBufferSize

Taille maximale des données binaires envoyées par WebSocket, en bytes. Par défaut la taille max est de 1048576 bytes, soit 1MB.

La valeur maximale possible pour cette propriété est 2147483647 (2GB). Une valeur supérieure sera plafonnée à 2GB.

Section policies

Policies à appliquer pour l'accès à l'application.

On place cette définition au niveau du config plutôt qu'au niveau de la descript car il se peut qu'une application Ewt n'ait pas de descript.

policy

Référence de policy à vérifier pour autoriser l'accès à l'application.

Section ged

Cette section permet de spécifier les paramètres de connexion à une API de GED. La section fonctionne sur le même principe que la section database.

defaultConnectionConfig

Nom de la connexion par défaut. La valeur doit référencer l'attribut name d'un nœud <connection>. À noter qu'on peut se passer de cette propriété en définissant une entrée <connection> sans attribut name.

connection

Sous-section de paramètres de connexion à l'API de GED. L'élément <connection> peut être défini plusieurs fois, mais dans ce cas il faut nommer les connexions au moyen d'un attribut name et indiquer quelle est la connexion par défaut utilisée par l'application via la propriété defaultConnectionConfig.

Les paramètres dépendent du type de GED utilisé.

La GED "FileIndex" est une GED intégrée à Ewt. Elle s'appuie sur le file system du serveur et une table SQL faisant office d'index. Cette GED supporte le versioning.

type ou connection/type
Type de GED. Pour la GED "FileIndex", la valeur du paramètre doit être fileindex
indexTable ou connection/indexTable
Nom de la table qui sert d'index pour la GED. En réalité, la GED FileIndex repose sur deux tables: l'une enregistre la structure de la GED (les répertoires et fichiers) et la seconde enregistre les références de données (les fichiers et leurs versions). La valeur du paramètre indexTable est donc utilisé comme préfixe pour ces deux tables. Ainsi, pour une valeur maged, le moteur générera des tables maged_nodes et maged_files.
rootDirectory ou connection/rootDirectory
Path local faisant office de racine pour le stockage des éléments de GED.
rootNodeId ou connection/rootNodeId
Identifiant de l'élément racine dans lequel l'application est autorisée à écrire.

La GED "Alfresco" utilise l'API REST du système de GED Alfresco.

type ou connection/type
Type de GED. Pour la GED "Alfresco", la valeur du paramètre doit être alfresco
baseUrl ou connection/baseUrl
URL de l'API principale gérant les objets de la GED.
searchUrl ou connection/searchUrl
URL de l'API dévouée à la recherche avancée. L'URL peut être la même que baseUrl si les fonctions de recherche avancée sont prises en charge par le même endpoint.
rootNodeId ou connection/rootNodeId
Identifiant de l'élément racine dans lequel l'application est autorisée à écrire.
username ou connection/username
Utilisateur technique à utiliser pour se connecter à l'API.
password ou connection/password
Mot de passe associé au compte username.

Cette section permet de déclarer le ou les index de recherche que l'application doit gérer. On y définit des éléments <index> dans lesquels on spécifie les paramètres de l'index. Chaque élément <index> doit posséder un nom qui servira à identifier l'index dans les autres fichiers de configuration et dans les scripts.

Veuillez vous reporter au chapitre Indexation et recherche pour plus d'informations.

Section commands

Cette section permet de déclarer les commandes autorisées dans le cadre de méthode $exec.start

Exemple de fichier de config

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?xml version="1.0" encoding="UTF-8"?>
<config>
  <admin>
    <applicationName>Mon application 🚀</applicationName>
    <documentsMode>multi</documentsMode>
    <transientObjectNamePrefix>SESSION:</transientObjectNamePrefix>
    <tupleIdForm>snowflake</tupleIdForm>
    <enableScheduler>true</enableScheduler>
    <instanceName>${env:INSTANCENAME}</instanceName>
    <runMode>dev</runMode>
    <debuggerPort>8000</debuggerPort>
    <debuggerAddress></debuggerAddress>
    <dumpOutput>${var:homeDirectory}</dumpOutput>
    <logLevel>trace</logLevel>
    <cipherPassword encrypted="true">QlAX...</cipherPassword>
    <sessionTTL>60</sessionTTL>
    <sessionEOL>03:00:00</sessionEOL>
    <sessionRenewable>true</sessionRenewable>
    <failoverMode>default</failoverMode>
    <failoverSupport>database</failoverSupport>
  </admin>

  <database>
    <verbose>false</verbose>
    <defaultConnectionConfig>postgres</defaultConnectionConfig>

    <connection name="postgres">
      <engine>postgres</engine>
      <driver>org.postgresql.Driver</driver>
      <url>jdbc:postgresql://...</url>
      <property>tcpKeepAlive=true</property>
      <username>username</username>
      <password>password</password>
      <poolProperty>poolName=cnxPool-Ewt</poolProperty>
      <encoding>utf-8</encoding>
    </connection>
  </database>

  <email>
    <emailSupport>hello@world.com</emailSupport>
    <defaultSmtpConfig>serveur1</defaultSmtpConfig>

    <smtp name="serveur1">
      <host>mail.google.com</host>
      <port>587</port>
      <username encrypted="true">8cyB...</username>
      <password encrypted="true">Rkj1...</password>
      <starttls>true</starttls>
      <headers>
        <header name="Content-Type">text/html; charset=utf-8</header>
        <header name="Content-Transfer-Encoding">8bit</header>
      </headers>
    </smtp>

    <smtp name="serveur2">
      <host>mail.somesmtp.net</host>
      <port>587</port>
      <username encrypted="true">pEOt...</username>
      <password encrypted="true">NF+W...</password>
      <starttls>true</starttls>
    </smtp>
  </email>

  <styles>
    <style name="default">default.xsl</style>
    <style name="documents">documents.xsl</style>
    <style name="info">documents.xsl</style>
    <style name="benevoles">documents.xsl</style>
    <style name="impressionEtiquettes">dlgImpressionEtiquettes.xsl</style>
    <style name="mailing">dlgMailing.xsl</style>
    <style name="refuserArticles">dlgRefuserArticles.xsl</style>
    <style name="listeArticlesVendeur">vendeur.xsl</style>
    <style name="moduleCaisse">moduleCaisse.xsl</style>
    <style name="statistique">dlgStatistique.xsl</style>
    <style name="impressions">dlgImpressions.xsl</style>

    <defaultStyle>default</defaultStyle>
    <transformerFactory>org.apache.xalan.processor.TransformerFactoryImpl</transformerFactory>
  </styles>

  <bundles>
    <style name="documents">documents</style>
    <style name="info">documents</style>
    <style name="benevoles">documents</style>
    <style name="mailing">mailing</style>

    <defaultBundles>base,default</defaultBundles>
  </bundles>

  <notifications>
    <notification name="incoming-get-request:web">onGetRequest.script</notification>
    <notification name="incoming-post-request:web">onGetRequest.script</notification>
    <notification name="doc-save">onDocSave.script</notification>
    <notification name="doc-create">onDocCreate.script</notification>
    <notification name="doc-close">onDocClose.script</notification>
  </notifications>

  <security>
  </security>

  <policies>
    <policy name="main"/>
  </policies>

  <commands>
  </commands>

  <search>
    <index name="default">
      <engine>lucene</engine>
      <root>c:/Temp/lucene/ve-documents/</root>
    </index>
    <index name="other">
      <engine>lucene</engine>
      <root>c:/Temp/lucene/ve-other/</root>
    </index>
  </search>
</config>