Operation


    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

    Classe de document

    La classe document OperationHandlerRegistration doit référencer les tags suivants :

    • OperationHandler (chaîne de caractères)
    • ExecutionPhase : BEFORE ou AFTER
    • Action : liste de choix autorisant les valeurs suivantes :
      • CREATE pour réagir à la création de composant
      • READ pour réagir à l’ouverture de composant
      • UPDATE pour réagir à la mise à jour de composant
      • SEARCH pour réagir à la recherche de composant
      • ADD_CONTENT pour réagir à l’ajout de contenu à un document
      • DELETE_CONTENT pour réagir à la suppression de contenu d’un document
      • ANSWER pour réagir à l’application d’une réponse sur une tâche
      • ASSIGN pour réagir à l’assignation d’une tâche
    • ObjectType : DOCUMENT, TASK, FOLDER ou VIRTUAL_FOLDER
    • Enabled (booléen)
    • Asynchronous (booléen)
    • RegistrationOrder (entier)
    • StopOnException (booléen) : détermine si l’opération doit être stoppée lorsqu’une exception est déclenchée (et que la phase est BEFORE)

    Configuration d’un abonnement

    Comme indiqué précédemment, 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 Description
    OperationHandler Classe Java de l’OperationHandler ou l’URL d’un OperationHook
    ExecutionPhase Phase d’exécution de l’opération
    Action Action de l’opération
    ObjectType Type d’objet auquel réagir
    Enabled Détermine si l’abonnement est actif ou inactif
    Asynchronous Détermine si l’OperationHandler doit être exécuté de manière asynchrone ou non
    RegistrationOrder Ordonnancer les différents abonnements à une même opération
    StopOnException Détermine si l’exécution de l’opération doit être stoppée en cas d’exception (seulement si synchrone)

    Flower 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 Flower, 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étermine les règles à appliquer.

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

    • les conditions : détermine les cas dans lesquel 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 composant
    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
    getTagValue(Component component, String tagName) Récupère la valeur d’un tag sinon vide
    setTagValue(Component component, String tagName, String tagValue) Définie la valeur 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
    addTagValue(Component component, String tagName, String tagValue) Ajoute une valeur à 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

    Exemple

    Dépendances Maven

    <dependency>
    	<groupId>com.flower.docs.core</groupId>
    	<artifactId>flower-docs-ws-client</artifactId>
    	<version><span class="version">2.4.2.5</span></version>
    </dependency>
    <dependency>
    	<groupId>com.flower.docs.apis</groupId>
    	<artifactId>flower-docs-operation-api</artifactId>
    	<version><span class="version">2.4.2.5</span></version>
    </dependency>
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-web</artifactId>
    	<version>2.1.5.RELEASE</version>
    </dependency>
    

    Hook

    @RestController
    @RequestMapping("/log")
    public class SampleOperationHook extends OperationHook
    {
        private static final Logger LOGGER = LoggerFactory.getLogger(SampleOperationHook.class);
    
        @Override
        public void process(OperationContext context) throws TechnicalException, FunctionalException
        {
            LOGGER.info("Processing context={}", context);
        }
    }
    

    Modification du contexte

    Sécurité

    Configuration

    • accès au Core ws.url

    Gestion des erreurs

    Par défaut, lors de l’exécution d’un OperationHook, le Core Flower log les erreurs renvoyées en parsant le corps de la réponse HTTP. Pour renvoyer des exceptions Flower adaptées en fonction du contexte, il faut ajouter dans un objet instancié par Spring le code suivant :

    @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");