Home > Services

Services IU

Un Service IU (Service d'Interface Utilisateur) est une ressource HTTP, en général une JSP ou une servlet Java, qui est intégrée à l'outil EBX.Manager. Elle permet de fournir aux utilisateurs des fonctionnalités spécifiques et avancées.

L'application JSP ou la Servlet Java doit être encodée en UTF-8.

Il y a deux types de services IU :

Services IU de niveau adaptation

Ces services sont exécutés dans le contexte :

Cas d'usage typiques

Implémentation

Un service IU est ajouté en deux étapes :

  1. Déclarer votre service IU dans le modèle d'adaptation. Voir Définition du schéma .

  2. Implémenter votre service comme une application JSP ou Java Servlet. Le code de l'application utilisera la classe ServiceContext

Notons que le schéma considéré doit être packagé, au préalable, dans un module. Vous pouvez aussi consulter l'exemple d'implémentation d'import/export du Tutoriel .

Utilisation des services dans le Manager

Une fois que vous avez développé, déployé et déclaré un service IU, les utilisateurs y accèderont dans EBX.Manager en utilisant le bouton

Services IU de niveau branche ou version

Un service IU peut aussi être exécuté au niveau d'une branche. Cette application Java/JSP/Servlet doit être déclarée dans un module (voir ci-dessous).

L'objectif de ce type de service est de permettre l'écriture de processus à caractère métier de haut niveau en donnant de la flexibilité sur l'accès aux fonctions comme le merge, l'import/export, la validation, etc.

Cas d'usage types

Accès aux services

Les services sont accessibles via le menu principal des branches :

Menu

Dans le sous-menu "Services", on trouve tous les services declarés sur tous les modules enregistrés sur la plate-forme.

Menu

Déclaration

Les services doivent être déclarés au sein de la configuration d'un module.

La recommandation est de créer une application web dédiée à ce type de services, puisqu'ils sont disponibles pour toutes les branches mais peuvent avoir un cycle de vie différent de celui des données et de celui du produit.

Les services sont declarés dans le fichier module.xml comme suit : 

<?xml version="1.0encoding="UTF-8"?>
<module xmlns="urn:ebx-schemas:module_2.1xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
     xsi:schemaLocation="urn:ebx-schemas:module_2.1 http://schema.orchestranetworks.com/module_2.1.xsd">
    <name>mdm-test</name>
    <publicPath>mdm-test</publicPath>
    <locales>
        <locale>fr-FR</locale>
    </locales>
    <services>
        <service name="Service1">
            <resourcePath>/pages/mdm-test.jsp</resourcePath>
            <type>branch</type>
            <documentation xml:lang="fr-FR">
                <label>Merge filles sur parent</label>
                <description>Ce service merge toutes les filles sur la branche parente si elles sont valides
                </description>
            </documentation>
            <documentation xml:lang="en-US">
                <label>Merge children on parent</label>
                <description>This service merge all children on parent branch after validation</description>
            </documentation>
        </service>
        <service name="Service2">
            <resourcePath>/pages/mdm-merge-validate.jsp</resourcePath>
            <type>branch</type>
            <documentation xml:lang="fr-FR">
                <label>Merge/Valide/Export</label>
                <description>Merge la branche courante avec son parent puis valide ce parent et l'exporte.
                </description>
            </documentation>
            <documentation xml:lang="en-US">
                <label>MergeValidate/export</label>
                <description>Merge current branch to parent if valid. Then validates parent and export it.
                </description>
            </documentation>
        </service>
        <service name="Fake1">
            <resourcePath>/pages/fake.jsp</resourcePath>
            <type>version</type>
            <documentation xml:lang="fr-FR">
                <label>Service fake</label>
                <description>Ne fait rien mais le fait sur une version.</description>
            </documentation>
            <documentation xml:lang="en-US">
                <label>Service fake</label>
                <description>Do nothing but do it on a version.</description>
            </documentation>
        </service>
        <service name="Fake2">
            <resourcePath>/pages/fake.jsp</resourcePath>
            <type>any</type>
            <documentation xml:lang="fr-FR">
                <label>Service fake</label>
                <description>Ne fait rien mais le fait sur une version ou une branch.</description>
            </documentation>
            <documentation xml:lang="en-US">
                <label>Service fake</label>
                <description>Do nothing but do it on a version or a branch.</description>
            </documentation>
        </service>
    </services>
</module>

Avec les définitions suivantes pour les éléments :

Elément Obligatoire Définition

services

Oui, s'il y a des services

Racine pour la déclaration des services.

service

Oui, s'il y a au moins un service

Un par service

attribute: name

Oui

Nom du service. Doit être unique au périmètre d'un module.

resourcePath

Oui

Chemin menant au service. Relatif par rapport au chemin de la webapp correspondant au module.

type

Oui

Permet de restreindre l'exécution d'un service. Les valeurs possibles sont : branch, version, any.

documentation

Non

Libellé et description du service. Permet d'obtenir un texte compréhensible par l'utilisateur final.

attribute: xml:lang

Oui

Variante de language pour la documentation.

label

Non

Texte court décrivant le service.

description

Non

Texte long décrivant le service.

Exemples

Le code suivant illustre une implémentation exemple de ce type de service. Le service valide la home courante puis redirige l'utilisateur vers le merge interactif. A la fin du merge, une jsp valide les résultats et exporte la branche.

merge-validate.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%> 
<%@ page import="com.orchestranetworks.service.ServiceContext" %> 
<%@ page import="java.io.*"%>  
<%@ page import="java.util.*"%> 
<%@ page import="com.onwbp.adaptation.*"%>   
<%@ page import="com.onwbp.base.text.*"%>   
<%@ page import="com.orchestranetworks.service.*"%>   
<%@ page import="com.orchestranetworks.ui.*"%> 
<% 
    final ServiceContext sContext = ServiceContext.getServiceContext(request);  
%>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Test Jsp</title>
</head>
<body>
<%= sContext.getServiceLabel() %> : Merge children on current branche : 
<%= sContext.getCurrentHome().getLabelOrName(sContext.getLocale()) %>
<hr width="50%" align="left" />
<%
final AdaptationHome currentHome = sContext.getCurrentHome();
final AdaptationHome parentHome  = currentHome.getParentBranch();
request.getSession().setAttribute("parentHome", parentHome);
if (!currentHome.getValidationReportsMap(Severity.ERROR).isEmpty()) {
   out.write("The current home is not valid, you cannot proceed to the merge decisions");
   return;

String myURL = sContext.getURLForIncludingResource("/pages/merge-validate-end.jsp");
UIHttpManagerComponent httpComponent = UIHttpManagerComponent.createOnServiceContext(sContext);
httpComponent.selectHome(currentHome);
httpComponent.setService(ServiceKey.MERGE);
httpComponent.setRedirectionURI(myURL);
out.write("The current home is valid, you can proceed to the merge decisions<br />");
out.write("<a href=\""+httpComponent.getURIWithParameters()+"\">Next step</a>");
%>
</body>
</html>

merge-validate-end.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%> 
<%@ page import="com.orchestranetworks.service.ServiceContext" %> 
<%@ page import="java.io.*"%>  
<%@ page import="java.util.*"%> 
<%@ page import="com.onwbp.adaptation.*"%>   
<%@ page import="com.onwbp.base.text.*"%>   
<%@ page import="com.orchestranetworks.service.*"%>   
<%@ page import="com.orchestranetworks.ui.*"%> 
<%@ page import=" com.orchestranetworks.instance.*" %>
<% 
    final ServiceContext sContext = ServiceContext.getServiceContext(request);  
%>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>EBX Test Jsp</title>
</head>
<body>
<%= sContext.getServiceLabel() %>
<hr width="50%" align="left" />

<%
    UIHttpManagerComponentReturnCode rc = UIHttpManagerComponentHelper.getReturnCodeFromHttpRequest(request);
    if (rc.isMergeCancelled()) {
        out.println("The procedure has been canceled:");
        return;
    }
    AdaptationHome parent = (AdaptationHome) request.getSession().getAttribute("parentHome"); 
    if (!parent.getValidationReportsMap(Severity.ERROR).isEmpty())
    {
        out.println(parent.getLabelOrName(sContext.getLocale()) + " is not valid, cannot export.<br />");
        return;
    }
        out.println(parent.getLabelOrName(sContext.getLocale()) + " is valid, continue.<br />");
        String versionName = ""+ System.currentTimeMillis();
        parent.getRepository().createHome(
        parent,
        HomeKey.forVersionName(versionName),
        sContext.getSession().getUserReference(),
        sContext.getSession(),
        UserMessage.createInfo("My label"),
        UserMessage.createInfo("My Description"));
        out.println("A version has been created : "+versionName+"<br />");
        final Archive archive = Archive.forFile(new File(parent.getLabelOrName(sContext.getLocale())+".ebx"));
        Procedure proc = new Procedure()  
        {  
             public void execute(ProcedureContext aContext) throws Exception  
             {  
                  aContext.doExportArchive(archive);         
             }
        };
        ProcedureResult result = sContext.execute(proc);  
        out.println("Archive done. "+archive.getLocationInfo());
%>

</body>
</html>

Optimisation et refactorisation

EBX.Platform fournit des services en standard comme l'optimisation et la refactorisation .

Contrôle d'accès

Les permissions sur les branches et les versions s'appliquent toujours au sein des services. Cependant, il est possible d'ajouter du code métier pour se prémunir d'accès non autorisés aux services. Ce code est de la responsabilité du développeur.

Validation

Le service de validation est sujet à permissions. La permission peut être positionnée explictement au niveau de l'instance. Au niveau home, la validation est désactivée si la validation est interdite pour l'utilisateur courant dans au moins une des instances.

NB : Cette règle de permission ne s'applique pas quand la validation est appelé programmatiquement.

Mise à jour de masse

Quand un service effectue des mises à jour de masse sur le référentiel, il ne sera pas toujours possible d'inclure l'ensemble des opérations dans une seule transaction atomique. Le nombre de mises à jour dépend de la taille mémoire allouée à la JVM, une telle limite existe par nature.

Il est par conséquent possible de définir l'empan de la transaction en présisant le nombre de modifications par transaction via la méthode ProcedureContext.setCommitThreshold(int commitThreshold) , illustrée dans l'exemple suivant où un commit sera effectué toutes les 1000 opérations : 

Procedure procedure = new Procedure()
{
   public void execute(ProcedureContext aContext) throws Exception
   {
      aContext.setCommitThreshold(1000);
      aContext.setAllPrivileges(true);
      aContext.doImportArchive(specs);
   }
};

Il est à noter qu'en cas d'anomalie toutes les occurrences précédemment commitées resteront en base.

Home > Services