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