Operation

Réagir aux opérations


    Consulter la Javadoc pour plus de précisions sur cette API

    Un peu de vocabulaire :

    • Operation : Action sur un objet du domaine
    • OperationHandler : Fragment de code exécuté avant ou après l’opération
    • OperationHook : OperationHandler exposé comme service REST

    L’abonnement à une opération passe par la création d’un document de classe OperationHandlerRegistration. Les tags référencés par cette classe permettent de configurer l’abonnement :

    Tag Type Description
    OperationHandler string Classe Java de l’OperationHandler ou l’URL d’un OperationHook
    ExecutionPhase choicelist Phase d’exécution de l’opération
    Action choicelist Action de l’opération
    ObjectType choicelist Type d’objet auquel réagir
    Enabled boolean Détermine si l’abonnement est actif ou inactif
    Asynchronous boolean Détermine si l’OperationHandler doit être exécuté de manière asynchrone ou non
    RegistrationOrder integer Ordonnancer les différents abonnements à une même opération
    StopOnException boolean Détermine si l’exécution de l’opération doit être stoppée en cas d’exception (seulement si synchrone)
    Authorization string chaîne d’autorisations basic à fournir au hook (générée en ligne grâce à blitter)

    FlowerDocs fournit nativement quelques OperationHandler comme le :

    • com.flower.docs.core.tsp.operation.LogOperationHandler : permet de logger le contexte pour lequel il est exécuté
    • com.flower.docs.core.tsp.operation.DroolsOperationHandler : permet d’appliquer des règles métiers (à travers une table de décision Drools)

    Développement

    En plus de ceux fournis nativement, il est possible de développer son propre OperationHandler.

    package com.xxx.sample;
    
    import org.springframework.stereotype.Component;
    import com.flower.docs.operation.api.OperationContext;
    import com.flower.docs.operation.api.OperationHandler;
    
    @Component
    public class OperationHandlerSample implements OperationHandler
    {
        public void process(OperationContext context)
        {
        }
    }

    Pour que cet OperationHandler puisse être utilisé par FlowerDocs, il est nécessaire que :

    • la classe soit présente dans le classpath de la JVM
    • que le package du handler (ici com.xxx.sample) soit scanné par Spring


    Une fois ces deux étapes réalisées, l’OperationHandler sera appelé conformément aux abonnements définis.

    DroolsOperationHandler

    Cet OperationHandler s’appuie sur le moteur de règle Drools et une table de décision (fichier MS Excel) afin de déterminer les règles à appliquer.

    Une table de décision est composée de deux types de colonnes :

    • les conditions : détermine les cas dans lesquels appliquer une règle
    • les actions : les actions à exécuter pour une règle donnée

    Au sein d’une table de décision, il est possible d’utiliser les méthodes suivantes à partir de l’objet util :

    Tag Description
    getDocumentService() Récupère le service de gestion de document
    getFolderService() Récupère le service de gestion de dossier
    getTaskService() Récupère le service de gestion de tâche
    getVirtualFolderService() Récupère le service de gestion de dossier virtuel
    getService(Component component) Récupère le service de gestion de composant
    getClassService(Component component) Récupère le service de gestion des classes de composants
    getTagClassService() Récupère le service de gestion des classe de tags
    getAclService() Récupère le service de gestion d’ACL
    getFactDAO() Récupère la DAO de gestion de l’historique
    create(Component component) Crée le composant fourni en entrée et retourne celui réellement créé
    update(Component component) Modifie le composant fourni en entrée
    changeClass(Component component, String classId) Modifie la classe du component fourni en entrée et propage uniquement les tags en commun entre la classe initiale et la nouvelle
    getClassId(Component component) Récupère la valeur de la classe du composant sinon vide
    setClassId(Component component, String classId) Définie la valeur de la classe du composant
    getStatus(Component component) Récupère la valeur du statut du composant
    setStatus(Component component, Status status) Définie la valeur du statut du composant
    getTagValues(Component component, String tagName) Récupère la liste de valeurs d’un tag sinon null
    setTagValues(Component component, String tagName, List<String> values) Définie la liste de valeurs d’un tag en modifiant sa valeur s’il existe, sinon en ajoutant un tag
    setTagReadOnly(Component component, String tagName, boolean readonly) Modifie un tag en le mettant en lecture seule ou lecture écriture
    addTagValues(Component component, String tagName, List<String> values) Ajoute une liste de valeurs à un tag existant ou ajoute le tag
    getAnswerId(Task task) Récupère la dernière réponse appliquée sur une tâche
    log(String message) Affiche dans les logs un message préfixé par [Drools] en INFO

    Un OperationHook est un OperationHandler exposé en tant que service REST. Grâce à un OperationHook, il pourra ainsi être possible de réagir aux opérations effectuées sur les composants depuis un service WEB distant.

    Endpoints

    En fonction de la catégorie de composant concerné par l’opération effectuée, une requête POST est envoyée sur les endpoints suivants :

    • /{{scope}}/documents/
    • /{{scope}}/folder/
    • /{{scope}}/virtual_folders/
    • /{{scope}}/tasks/

    Il peut être développé avec n’importe quel language permettant d’exposer des services WEB.

    Le corps des requêtes envoyées sur ces endpoints contient un objet décrivant le contexte d’exécution de l’opération et diffère donc en fonction des opérations.

    Configurer un OperationHook

    Un OperationHook peut être configuré de la même façon qu’un OperationHandler classique. Son nom correspond à l’URL permettant d’accéder aux endpoints listés ci-dessus. A partir de l’URL configurée, il doit être possible d’envoyer un POST sur {{hook URL}}/{{scope}}/documents/.

    Sécurité

    Il est recommandé de sécuriser les OperationHook déployés. Pour cela, FlowerDocs permet de configurer une chaîne de caractère fournie lors des appels REST dans une en-tête HTTP Authorization.

    Typiquement, une authentification BASIC peut être utilisée pour sécuriser un OperationHook. Pour que FlowerDocs fournisse l’authentification définie, il est nécessaire de mettre à jour l’abonnement avec la chaîne d’autorisation à fournir.

    Cette chaîne de caractère peut être générée en ligne grâce à blitter.

    Gestion des erreurs

    Par défaut, lors de l’exécution d’un OperationHook, FlowerDocs Core log les erreurs renvoyées, par le service REST, en parsant le corps de la réponse HTTP.

    Pour renvoyer des exceptions adaptées en fonction du contexte, il est nécessaire de fournir les en-têtes code et message sur la réponse HTTP.

    Avec Spring, un ExceptionHandler peut être défini facilement pour gérer toutes les exceptions FlowerDocs et les renvoyer correctement à FlowerDocs Core :

    @ExceptionHandler(CodeBasedException.class)
    public ResponseEntity<Object> handleCustomException(CodeBasedException ex, WebRequest request)
    {
        HttpHeaders headers = new HttpHeaders();
        headers.add("code", ex.getCode());
        headers.add("message", ex.getMessage());
        return new ResponseEntity<Object>(headers, HttpStatus.INTERNAL_SERVER_ERROR);
    }


    Dans le cas d’OperationHook synchrones, il est possible de renvoyer des messages d’erreurs personnalisés à l’utilisateur final. Pour cela, il est nécessaire d’utiliser le code d’erreur F00039 :

    throw ExceptionBuilder.createFunctionalException(F00039, "Custom error message");