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 :
-
d'une adaptation instance (sous l'onglet "Services"),
-
d'une table (sous le menu "Actions"),
-
d'une occurrence sélectionnée (sous le menu "Actions").
Cas d'usage typiques
-
Mise à jour en masse des enregistrements (ou d'une sélection d'enregistrements) d'une table (par exemple, réévaluation des montants de la colonne "prix du produit" en appliquant un ratio saisi par l'utilisateur).
-
Import de données en provenance d'une source externe dans l'adaptation instance courante.
-
Export des occurrences sélectionnées d'une table vers un système tiers.
-
Implémentation d'événements spécifiques du cycle de vie d'une entité MDM. Par exemple, création d'un produit qui impacte plusieurs tables ou bien "fermeture" d'un produit à une date spécifiée par l'utilisateur.
-
Afficher des informations statistiques sur une table.
-
etc.
Implémentation
Un service IU est ajouté en deux étapes :
-
Déclarer votre service IU dans le modèle d'adaptation. Voir Définition du schéma .
-
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
-
Import de données en provenance d'une source externe
-
Export des données de la version vers un système tiers
-
Valider et versionner une branche avant un export
-
Envoyer des messages à un système de supervision avant une fusion
-
Exporter une version et monitorer en asynchrone les acquittements des systèmes cibles
-
etc.
Accès aux services
Les services sont accessibles via le menu principal des branches :
.
Dans le sous-menu "Services", on trouve tous les services declarés sur tous les modules enregistrés sur la plate-forme.
.
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 :
<module xmlns="urn:ebx-schemas:module_2.1" xmlns: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
<%@ 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 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 :
{
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