Alfstore workflow framework Spécification technique Version 0.91 (2012-08-03) www.alfstore.com Email: info@alfstore.com Alfstore workflow framework 2012-10-28 1/28
Historique des versions Version Date Auteur Commentaires v 0.9 2012-07-30 I. Abrosimov Création du document V 0.91 2012-08-06 I. Abrosimov Mise à jour Alfstore workflow framework 2012-10-28 2/28
Table des matières I Architecture technique... 4 I.1 L architecture de la solution... 4 I.2 L architecture d adaptateur... 6 II Détails techniques... 8 II.1 Conventions de nommage... 8 II.1.1 Code du projet... 8 II.1.2 Nom des packages et des namespaces... 8 II.2 Conventions d échange des données... 8 II.2.1 Les listes et la pagination... 8 II.2.2 Conversion à JSON... 8 II.3 Configuration des formulaires... 10 II.4 Réponse de communication... 13 II.5 «My tasks» gadget... 14 II.5.1 Liste des taches... 14 II.5.2 Liste des workflows initialisée par l utilisateur... 17 II.5.3 Détails du workflow (instance du workflow)... 18 II.5.4 Editer une tâche de workflow... 23 II.5.5 Sauvegarder une tâche... 25 II.5.6 Récupérer une tâche... 27 II.5.7 Replacer la tâche dans le pot commun... 27 II.5.8 Réassigner une tâche... 27 II.6 DMS Gadget... 27 II.7 Description de service... 27 III Frameworks à utiliser... 28 Alfstore workflow framework 2012-10-28 3/28
I Architecture technique I.1 L architecture de la solution Ce chapitre décrit le chemin global de l architecture. Les composants en blanc sont les composants système; en bleu les composants du module dépendants du système (ou de la plateforme) ; en orange les composants du framework. Les dernières sont utilisables sur les différentes plateformes. La liste des composants utilisés dans le diagramme: Platform Presentation Layer: couche de présentation de la plateforme: les gadgets ou widgets sont gérés par les différents standards et par les différents moteurs. Cette couche représente le module du containeur. Presentation Component: composant qui gère la présentation du module. Ce composant varie selon la plateforme, mais fait partie du produit final, du gadget, du widget ou du portlet. Javascript presentation framework : ce composant est un composant entièrement écrit en JavaScript et contient la logique de présentation. Ce composant fait partie du framework «FWOS RSE». Javascript communication adapter : ce composant contient la logique de la communication avec la logique métier écrit en Java. Platform communication layer : couche de communication entre le module et le container (plateforme). Java communication layer : couche-réceptacle des requêtes provenant du composant JavaScript. Les requêtes ensuite sont transformées en appels aux services. Ce composant est plateforme-dépendant. Service Framework : couche d abstraction pour des appels liés à la gestion des workflows. Workflow/DMS Adapter : l adaptateur de GED/Workflow. Ce composant est différent pour chaque DMS ou système de gestion de Workflow. Alfstore workflow framework 2012-10-28 4/28
Platform Presentation Layer Presentation Component Open Social Gadget Javascript Presentation Framework Javascript Communication Adapter Jive Widget / Portlet Platform Communication layer Communication layer Platform dependent Java communication layer Service Framework Java Workflow Framewok Workflow/DMS Adapter DMS/Worlflow Alfstore workflow framework 2012-10-28 5/28
I.2 L architecture d adaptateur Le chemin d intégration avec Alfresco/Activiti : Framework Service Alfresco/Activiti Service implementation (Adapter) Alfresco + Activiti Alfresco WebScript API Alfresco Core API Activiti Alfresco Data En étant intégré dans Alfresco, Activiti est automatiquement accessible à l aide d API d Alfresco. On peut même accéder directement en utilisant API WebScript sans écrire de WebScripts personnalisés. Le chemin représentant l intégration avec la couche service Alfresco : Alfstore workflow framework 2012-10-28 6/28
Framework Service Service implementation (adapter) Forms Configuration Alfresco Alfresco Form API WebScripts Alfresco Workflow WebScripts CMIS Alfresco core API Alfresco Data Alfstore workflow framework 2012-10-28 7/28
II Détails techniques II.1 Conventions de nommage II.1.1 Code du projet Le nom «framewflow» est utilisé temporairement pour le code du projet. Il contiendra le code assurant l interface entre le gadget et le back end qui sera dans un premier Alfresco. Un sous projet nommé dms-service contiendra le code permettant d assurer l interopérabilité avec le système de GED/JBPM. II.1.2 Nom des packages et des namespaces Comme le projet est «open source» les packages et les namespaces doivent avoir «org.alfstore.*» au début. Pour le projet frameflow, le package principal sera «org.alfstore.frameflow», pour le projet dms-service il sera «org.alfstore.dms». II.2 Conventions d échange des données Ce chapitre a pour le but de décrire les appels au webservice et format d échange des données. II.2.1 Les listes et la pagination La pagination ne sera pas gérée dans la première version. II.2.2 Conversion à JSON Toutes les données d échange présentées dans ce chapitre sont en format JavaBean et seront converties en JSON à l aide du framework «Jackson». Les dates vont être gardées dans le format numérique (par défaut dans Jackson) dans la première version. Prévoir l utilisation du format ISO-8601 pour les prochaines versions (?). Exemple : Bean public class Exemple { protected String string; protected Date date; Alfstore workflow framework 2012-10-28 8/28
protected int integer; } protected boolean bool;... Diagramme : JSON : { "string" : "test", "date" : 1343998397947, "integer" : 1234, "bool" : true } Alfstore workflow framework 2012-10-28 9/28
II.3 Configuration des formulaires La configuration des formulaires des worklfows est gérée par la partie Java du framework. La configuration est stockée en format JSON (dans la v1.0) et en format XML (dans v2.0). La lecture du format JSON peut être effectuée à l aide du framework «Jackson». Note : il n y aura pas d héritage entre les formulaires : tous les champs doivent être explicitement décrits. Le format de fichier de configuration est présenté par le diagramme suivant : Et en format JSON : { "forms" : [ { "type" : "wf:activitireviewtask", "formname" : "task-edit", "areas" : [ { "id" : "info", "type" : "default", "caption" : "workflow.area.task.info", "subareas" : null, "apperanceoptions" : null }, { "id" : "progress", "type" : "default", "caption" : "workflow.area.task.progress", "subareas" : null, "apperanceoptions" : null }, { "id" : "items", "type" : "default", "caption" : "workflow.area.items", "subareas" : null, "apperanceoptions" : null }, { Alfstore workflow framework 2012-10-28 10/28
}, { "id" : "others", "type" : "default", "caption" : "workflow.area.other", "subareas" : null, "apperanceoptions" : null "id" : "response", "type" : "default", "caption" : "workflow.area.response", "subareas" : null, "apperanceoptions" : null } ], "fields" : [ { "fieldname" : "task.wfinstance.message", "show" : true, "hide" : false, "readonly" : true, "areaid" : "info", "appearance" : "textarea", "apperanceoptions" : null, "title" : null, "description" : null, "help" : null }, { "fieldname" : "task.owner", "show" : true, "hide" : false, "readonly" : true, "areaid" : "info", "appearance" : "user", "apperanceoptions" : null, "title" : null, "description" : null, "help" : null }, { "fieldname" : "task.priority", "show" : true, "hide" : false, "readonly" : true, "areaid" : "info", "appearance" : "list", "apperanceoptions" : null, "title" : null, "description" : null, "help" : null }, { "fieldname" : "task.duedate", "show" : true, "hide" : false, "readonly" : true, "areaid" : "info", "appearance" : "date", "apperanceoptions" : null, "title" : null, "description" : null, "help" : null Alfstore workflow framework 2012-10-28 11/28
} } ] }, { }, { }, { }, { } ] "fieldname" : "task.status", "show" : true, "hide" : false, "readonly" : false, "areaid" : "progress", "appearance" : "list", "apperanceoptions" : null, "title" : null, "description" : null, "help" : null "fieldname" : "task.wfinstance.attachements", "show" : true, "hide" : false, "readonly" : true, "areaid" : "items", "appearance" : "attachments", "apperanceoptions" : null, "title" : null, "description" : null, "help" : null "fieldname" : "task.comment", "show" : true, "hide" : false, "readonly" : false, "areaid" : "response", "appearance" : "textarea", "apperanceoptions" : null, "title" : null, "description" : null, "help" : null "fieldname" : "transitions", "show" : true, "hide" : false, "readonly" : true, "areaid" : "response", "appearance" : "transitions", "apperanceoptions" : null, "title" : null, "description" : null, "help" : null Note : le terme «area» correspond à «Set» dans Alfresco. Attention : les valeurs du «fieldname» font la référence aux objets internes : «task» de type «WorkflowUserTask». Pour accéder aux propriétés additionnels il faut utiliser l expression «task.properties['wfge:instructions']» (à simplifier pour v1.0?) Alfstore workflow framework 2012-10-28 12/28
II.4 Réponse de communication La couche de communication doit émettre à la sortie la classe «JsonResponse». Si lors du traitement de la requête, l objet «Error» doit être retourné comme réponse et contenir le code erreur (à définir), le message d erreur et l exception Java à l origine de l erreur (s il y en a). Note : l exception doit être traduite en JSON comme une table des chaînes des caractères contenant le «stack trace». Alfstore workflow framework 2012-10-28 13/28
II.5 «My tasks» gadget II.5.1 Liste des taches Dans la spécification de Saint-Gobain ce chapitre est décrit comme «My tasks tab». II.5.1.1 Appel du frameflow La requête effectué sur le framework sera de la forme /api/tasks/{username} où username est l identifiant de l utilisateur dans le sous-système (identifiant de login). Méthode http public final JsonResponse getalltasks(@pathvariable("username") String username) { } Cette méthode du controller permet d encapsuler l appel au service d appel au moteur JBPM. II.5.1.2 Couche Service L appel du frameflow sera relayé vers la couche service via l appel à la méthode : public abstract DMSBean getusertasks(sessiondata sessiondata, String sortorder) throws WFServiceException; Paramètres d entrée : sessiondata données de la session d authentification, à utiliser pour récupérer le nom d utilisateur et le ticket d Alfresco sortorder ordre de tri de la liste - ne pas utiliser pour la première version. La méthode retourne un objet DMSBean représentant les informations suivantes: Alfstore workflow framework 2012-10-28 14/28
Ci-dessous un exemple de la représentation JSON du flux sortant : { "paging" : { "total" : 1, "perpage" : -1, "startfrom" : 0 }, "tasks" : [ { "id" : "activiti$1050", "type" : "wf:activitireviewtask", "title" : null, "description" : "R\u00E9viser des documents pour les approuver ou les rejeter", "wfinstancemessage" : "Merci de r\u00e9viser ce document et revenir vers moi en cas de probl\u00e8me", "state" : "IN_PROGRESS", "owner" : { "username" : "admin", "firstname" : "Administrator", "lastname" : "" }, Alfstore workflow framework 2012-10-28 15/28
} } ] "duedate" : 1343900530747, "status" : "NOT_STARTED", "priority" : "2", "actionpermissions" : { "claimable" : false, "editable" : true, "pooled" : false, "reasignable" : false, "releasable" : false } II.5.1.3 Appel back end Afin de retourner les différentes tâches de l utilisateur, la couche service réalisera un appel vers le serveur Alfresco via la requête REST : GET /alfresco/service/api/taskinstances?authority=@{user}&properties=bpm_priority,bpm_status,bpm_duedate,bpm_de scription&exclude=wcmwf:*&skipcount=0&maxitems=-1 Ou @{user} est le nom d utilisateur. A noter que «maxitems» est mis à «-1» pour éviter la pagination. La réponse JSON est mappée par le framework Jakson via l utilisation d annotations et représente les objets suivants : Alfstore workflow framework 2012-10-28 16/28
II.5.2 Liste des workflows initialisée par l utilisateur Dans la spécification de Saint-Gobain voir le chapitre «III.2.2 tab». Workflow I ve started II.5.2.1 Appel du frameflow La requête effectué sur le framework sera de la forme /api/instances/{username} où username est l identifiant de l utilisateur dans le sous-système (identifiant de login). II.5.2.2 Couche Service L appel est ensuite relayé à la couche service via la méthode : Méthode de service : public abstract WorkflowInstancesList getuserinitiatedinstances(sessiondata sessiondata, String sortorder) throws WFServiceException; Paramètres d entrée : sessiondata données de la session d authentification, à utiliser pour récupérer le nom d utilisateur et le ticket d Alfresco sortorder ordre de tri de la liste - ne pas utiliser pour la v1.0 Le résultat est défini par WorkflowInstancesList : Alfstore workflow framework 2012-10-28 17/28
II.5.2.1 Appel back end La liste des workflow initié par l utilisateur est obtenue du back end par l appel : GET /workflowinstances?exclude=jbpm$wcmwf:*,jbpm$wf:articleapproval,activiti$publishwebcontent,jbpm$publishwebcontent,jbpm$inwf:invitation-nominated,jbpm$imwf:invitationmoderated,activiti$activitiinvitationmoderated,activiti$activitiinvitationnominat ed&skipcount=0&maxitems=-1&initiator=@{initiator} Ou @{initiator} est le nom d utilisateur. A noter que «maxitems» est mis à «-1» pour éviter la pagination. La réponse du back end est représenté par le graph d objet suivant : II.5.3 Détails du workflow (instance du workflow) II.5.3.1 Appel du frameflow La requête effectué sur le framework sera de la forme /api/workflowdetails/{workflowinstanceid} où workflowinstanceid est l identifiant de l instance de Workflow. II.5.3.2 Couche Service L appel est ensuite relayé à la couche service via la méthode : public abstract WorkflowInstanceDetails getworkflowinstancedetails (SessionData sessiondata, String workflowinstanceid) Alfstore workflow framework 2012-10-28 18/28
throws WFServiceException; Paramètres d entrée : sessiondata données de la session d authentification, à utiliser pour récupérer le nom d utilisateur et le ticket d Alfresco workflowinstanceid l id de l instance du workflow Le résultat d appel est défini dans WorkflowInstanceDetails : II.5.3.3 Appel back end Pour obtenir les informations caractérisant les informations d un workflow, la couche service doit réaliser les appels suivant : (1)GET /alfresco/s/api/workflow-instances/@{wfinstanceid}?includetasks=true Alfstore workflow framework 2012-10-28 19/28
La réponse est de la forme ; Pour chaque tâche appartenant au worflow et constituant soit l historique des tâches soit les tâches en cours, il est nécessaire d obtenir le détail de chaque tâche par l appel : (2)GET /alfresco/s/api/task-instances/@{taskid} Ou @{wfinstanceid} est l id de l instance du workflow et @{taskid} est l id d une tâche La réponse est de la forme : Alfstore workflow framework 2012-10-28 20/28
Il est également nécessaire de réaliser l appel suivant afin d obtenir les identifiants des documents faisant l objet du workflow : (3)POST /alfresco/s/api/formdefinitions Envoyer les données : {"itemkind": "task", "itemid": "@{starttaskinstanceid}", "fields": ["bpm:sendemailnotifications", "packageitems"]} Exemple: {"itemkind": "task", "itemid": "activiti$20316", "fields": ["message", "taskowner", "bpm:priority", "bpm:duedate", "bpm:taskid", "bpm:status", "packageitems", "bpm:comment", "transitions"]} La réponse est de la forme : Puis les caractéristiques des documents sont obtenues par l appel suivant puis (4)POST /alfresco/s/api/forms/picker/items Envoyer les données : {"items":["@{assoc_packageitems}"],"itemvaluetype":"noderef"} Exemple {"items":["workspace://spacesstore/d60c2d24-1f38-4819-9b49-7e236d3ddcec"],"itemvaluetype":"noderef"} Ou @{starttaskinstanceid} est l id de la tâche de démarrage reçu dans la requête (1) @{assoc_packageitems} sont les id des documents attachés. La réponse est de la forme : Alfstore workflow framework 2012-10-28 21/28
Alfstore workflow framework 2012-10-28 22/28
II.5.4 Editer une tâche de workflow II.5.4.1 Appel du frameflow La requête effectué sur le framework sera de la forme /api/edit-task/{taskid} où taskid est l identifiant de la tâche à éditer. II.5.4.2 Couche Service Méthode de service : public abstract EditTaskFormData getedittaskform(sessiondata sessiondata, String taskid) throws WFServiceException; Paramètres d entrée : sessiondata données de la session d authentification, à utiliser pour récupérer le nom d utilisateur et le ticket d Alfresco ; taskid id de la tâche ; Le résultat d appel est défini par EditTaskData: Alfstore workflow framework 2012-10-28 23/28
II.5.4.3 Appel back end Lors de l édition d une tâche il est nécessaire de réaliser deux appels. Le premier appel permet d obtenir les caractéristiques de la tâche : (1) GET /alfresco/s/api/task-instances/@{taskid}?detailed=true La réponse est de la forme : Le deuxième permet de connaître la liste des champs éditables, leurs caractéristiques et les contraintes associées à chaque champ. C est lors de cet appel qu il est nécessaire d obtenir la liste des champs à requêter par la configuration réalisé dans le frameflow (cf Configuration des formulaires) (2) POST /alfresco/s/api/formdefinitions Envoyer les données : {"itemkind": "task", "itemid": "@{taskid}", "fields": ["message", "taskowner", "bpm:priority", "bpm:duedate", "bpm:taskid", "bpm:status", "packageitems", "bpm:comment", "@{field1}",...,"@{fieldn}"]} @{field1} @{fieldn} sont les autres propriétés reçues dans (1). Alfstore workflow framework 2012-10-28 24/28
La réponse est de la forme : II.5.5 Sauvegarder une tâche La sauvegarde d une tâche peut être déclenchée par l action de sauvegarde mais aussi par les boutons de choix des transitions. Les transitions d une tâche sont obtenues dans la requête du chapitre 5.4 avec le champ «transitions». II.5.5.1 Appel du frameflow Lors de la sauvegarde d un formulaire liée à une tache ou à une transition, le framework est appelé avec l url : POST /api/save-task/{taskid} II.5.5.2 Couche Service Méthode de service : public abstract void savetaskformdata(sessiondata sessiondata,string taskid, Map<String, String> properties) throws WFServiceException; Paramètres d entrée : sessiondata données de la session d authentification, à utiliser pour récupérer le nom d utilisateur et le ticket d Alfresco ; taskid id de la tâche ; properties les propriétés saisi par utilisateur. Alfstore workflow framework 2012-10-28 25/28
II.5.5.1 Appel back end La sauvegarde d une tâché est relayé au back end via l appel : POST /alfresco/s/api/task/@{taskid}/formprocessor Envoyer les données : Exemple : {"prop_bpm_status":"in Progress","assoc_packageItems_added":"","assoc_packageItems_removed":"", "prop_bpm_comment":"this is a comment"} La réponse est de la forme : Alfstore workflow framework 2012-10-28 26/28
II.5.6 Récupérer une tâche Cette fonction n est pas supportée dans v1.0 II.5.7 Replacer la tâche dans le pot commun Cette fonction n est pas supportée dans v1.0 II.5.8 Réassigner une tâche Cette fonction n est pas supportée dans v1.0 II.6 DMS Gadget TODO pour Lot 2. II.7 Description de service /** * Workflow service * @author Illya Abrosimov (i.abrosimov@alfstore.com) */ public interface WorkflowService { public abstract UserTasksList getusertasks(sessiondata sessiondata, String sortorder) throws WFServiceException; public abstract WorkflowInstancesList getuserinitiatedinstances(sessiondata sessiondata, String sortorder) throws WFServiceException; public abstract EditTaskFormData getedittaskform(sessiondata sessiondata, String taskid) throws WFServiceException; public abstract WorkflowInstanceDetails getworkflowinstancedetails(sessiondata sessiondata, String workflowinstanceid) throws WFServiceException; public abstract void savetaskformdata(sessiondata sessiondata,string taskid, Map<String, String> properties) throws WFServiceException; } Alfstore workflow framework 2012-10-28 27/28
III Frameworks à utiliser Ce chapitre décrit les frameworks à utiliser lors le développement du projet. Spring le framework à utiliser pour IOC et MVC. Jackson pour lire et écrire les flux JSON Dozer (http://dozer.sourceforge.net/) pour convertir les beans java aux autres beans Java (bean mapper). Pour la partie de la couche Web assurant l interface entre le gadget et le sous-système de GED/JBPM, le framework Spring MVC 3.1 sera utilisé. Alfstore workflow framework 2012-10-28 28/28