Home > Services
UI Services
A UI Service (User Interface Service) is a HTTP resource, generally a JSP or a Java Servlet, that is integrated into EBX.Manager. It gives the opportunity to offer specific and advanced functionalities to the user.
The JSP or the Java Servlet application must be UTF-8 encoded because it is included in the Manager page which is itself UTF-8 encoded.
There are two kinds of UI Services:
UI Services on adaptations
Such services are executed in the context:
-
of an adaptation instance (under the tab "Services"),
-
of a table (under the menu "Actions"),
-
of selected occurrence(s) (under the menu "Actions").
Typical use cases
-
Update a table, or a user selection of table occurrences (for example, adjust the product price column by applying the ratio specified by the user).
-
Import data from an external source into the current adaptation instance.
-
Export selected occurrences of a table.
-
Implement specific events of a "MDM entity" life-cycle (for example, a product creation impacts several tables or a product is "closed" at a date specified by the user).
-
Display some statistics on a table.
-
etc.
Implementation
A UI Service is added in two steps:
-
Declare your UI Service in the adaptation model. See Schema Definition .
Note that the schema must be packaged in a module.
-
Implement your service by using JSP or Servlet API. The code will use
ServiceContextAPI class.
You may check out a UI Service implementation example in Tutorial .
Use of services within EBX.Manager
Once you have developed, deployed and declared a UI Service, users will
access it with EBX.Manager by using the following button:
.
UI Services on branches or versions
A UI Service may also be executed on a branch. This Java/JSP/Servlet application has to be declared in a module (see configuration).
This means it is mandatory to have at least one module in addition to the product's modules.
The purpose of such services is to allow the end-user to write high-level core business procedures by giving flexibility on functions such as: merge, import/export, validations, and so on.
Typical use cases
-
Import data from an external source.
-
Export data to multiple systems.
-
Validate a branch and version it before its export
-
Send messages to a monitoring system before a merge
-
etc.
Access to services
The services are accessed through the main menu on branch or on version:
.
The submenu "services" shows all services declared on all modules.
.
Configuration
Those UI services have to be declared in the configuration of a module.
The general advice here is to create a web application dedicated to these services since they will be available on all branches but may have a life-cycle dissociated from the life-cycle of data and product.
The services are declared in the file module.xml as follows:
<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>
With the following elements definitions:
| Element | Mandatory | Definition |
|---|---|---|
|
services |
Yes, if there are services |
Root element for services |
|
service |
Yes, if there is one service |
One for each service |
|
attribute: name |
Yes |
Name of the service. Must be unique into the scope of a module |
|
resourcePath |
Yes |
Path leading to the service. Relative to the path of the webapp matching the module. |
|
type |
Yes |
Allows to restrict the execution of the service. Possible values are: branch, version, any. |
|
documentation |
No |
Label and description of the service. To have a user-fridenly way of listing the services in the Manager. |
|
attribute: xml:lang |
Yes |
Local for the current documentation block. |
|
label |
No |
Short text describing the service. |
|
description |
No |
Long text describing the service. |
Samples
The following code is a sample of such service implementation. The service validates the current home, then redirects the user to the merge interface. At the end of the interactive merge procedure, the user is redirected to a jsp which does some validation and then exports the branch.
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>
Optimize and refactor
EBX.Platform provides buit-in services such as the optimize and refactor .
Access control
Permissions on branches and versions are still applied to services. Therefore, it is possible to add some business (specific) code to prevent illegal access to services by checking the context. Such code is within the responsibility of the developper.
Validation
The validation service is subjected to specific permissions. These permissions can be explicitly set at instance level. At home level, the validation is deactivated for the current user if it is forbidden on at least one of the instances.
NB: This permission does not apply when the validation is called programmatically.
Massive updates
In case of a service whose purpose is to massively update the repository, it will not always be able to run operations in a single atomic transaction. Obviously, the number of changes depends on the amount of memory available in your JVM, but there will always be a limit to that amount.
So, it is possible to define the size of the commit by calling the method
ProcedureContext.setCommitThreshold(int commitThreshold) . This is illustrated in the following example where a commit will be executed every 1000 update operations:
{
public void execute(ProcedureContext aContext) throws Exception
{
aContext.setCommitThreshold(1000);
aContext.setAllPrivileges(true);
aContext.doImportArchive(specs);
}
};
One must take note that, when a problem occurs and a commit threshold is used, all data previously committed will remain in the database.
Home > Services